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 int policy_min_pw_len = 0;
557 pwp.in.user_handle = handle;
559 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
560 if (NT_STATUS_IS_OK(status)) {
561 policy_min_pw_len = pwp.out.info.min_password_length;
563 newpass = samr_rand_pass(tctx, policy_min_pw_len);
565 s.in.user_handle = handle;
569 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
570 /* w2k3 ignores this length */
571 u.info24.pw_len = strlen_m(newpass) * 2;
573 status = dcerpc_fetch_session_key(p, &session_key);
574 if (!NT_STATUS_IS_OK(status)) {
575 printf("SetUserInfo level %u - no session key - %s\n",
576 s.in.level, nt_errstr(status));
580 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
582 torture_comment(tctx, "Testing SetUserInfo level 24 (set password)\n");
584 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
585 if (!NT_STATUS_IS_OK(status)) {
586 printf("SetUserInfo level %u failed - %s\n",
587 s.in.level, nt_errstr(status));
597 static bool test_SetUserPass_23(struct dcerpc_pipe *p, struct torture_context *tctx,
598 struct policy_handle *handle, uint32_t fields_present,
602 struct samr_SetUserInfo s;
603 union samr_UserInfo u;
605 DATA_BLOB session_key;
607 struct samr_GetUserPwInfo pwp;
608 int policy_min_pw_len = 0;
609 pwp.in.user_handle = handle;
611 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
612 if (NT_STATUS_IS_OK(status)) {
613 policy_min_pw_len = pwp.out.info.min_password_length;
615 newpass = samr_rand_pass(tctx, policy_min_pw_len);
617 s.in.user_handle = handle;
623 u.info23.info.fields_present = fields_present;
625 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
627 status = dcerpc_fetch_session_key(p, &session_key);
628 if (!NT_STATUS_IS_OK(status)) {
629 printf("SetUserInfo level %u - no session key - %s\n",
630 s.in.level, nt_errstr(status));
634 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
636 torture_comment(tctx, "Testing SetUserInfo level 23 (set password)\n");
638 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
639 if (!NT_STATUS_IS_OK(status)) {
640 printf("SetUserInfo level %u failed - %s\n",
641 s.in.level, nt_errstr(status));
647 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
649 status = dcerpc_fetch_session_key(p, &session_key);
650 if (!NT_STATUS_IS_OK(status)) {
651 printf("SetUserInfo level %u - no session key - %s\n",
652 s.in.level, nt_errstr(status));
656 /* This should break the key nicely */
657 session_key.length--;
658 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
660 torture_comment(tctx, "Testing SetUserInfo level 23 (set password) with wrong password\n");
662 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
663 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
664 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
665 s.in.level, nt_errstr(status));
673 static bool test_SetUserPassEx(struct dcerpc_pipe *p, struct torture_context *tctx,
674 struct policy_handle *handle, bool makeshort,
678 struct samr_SetUserInfo s;
679 union samr_UserInfo u;
681 DATA_BLOB session_key;
682 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
683 uint8_t confounder[16];
685 struct MD5Context ctx;
686 struct samr_GetUserPwInfo pwp;
687 int policy_min_pw_len = 0;
688 pwp.in.user_handle = handle;
690 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
691 if (NT_STATUS_IS_OK(status)) {
692 policy_min_pw_len = pwp.out.info.min_password_length;
694 if (makeshort && policy_min_pw_len) {
695 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len - 1);
697 newpass = samr_rand_pass(tctx, policy_min_pw_len);
700 s.in.user_handle = handle;
704 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
705 u.info26.pw_len = strlen(newpass);
707 status = dcerpc_fetch_session_key(p, &session_key);
708 if (!NT_STATUS_IS_OK(status)) {
709 printf("SetUserInfo level %u - no session key - %s\n",
710 s.in.level, nt_errstr(status));
714 generate_random_buffer((uint8_t *)confounder, 16);
717 MD5Update(&ctx, confounder, 16);
718 MD5Update(&ctx, session_key.data, session_key.length);
719 MD5Final(confounded_session_key.data, &ctx);
721 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
722 memcpy(&u.info26.password.data[516], confounder, 16);
724 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex)\n");
726 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
727 if (!NT_STATUS_IS_OK(status)) {
728 printf("SetUserInfo level %u failed - %s\n",
729 s.in.level, nt_errstr(status));
735 /* This should break the key nicely */
736 confounded_session_key.data[0]++;
738 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
739 memcpy(&u.info26.password.data[516], confounder, 16);
741 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
743 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
744 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
745 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
746 s.in.level, nt_errstr(status));
755 static bool test_SetUserPass_25(struct dcerpc_pipe *p, struct torture_context *tctx,
756 struct policy_handle *handle, uint32_t fields_present,
760 struct samr_SetUserInfo s;
761 union samr_UserInfo u;
763 DATA_BLOB session_key;
764 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
765 struct MD5Context ctx;
766 uint8_t confounder[16];
768 struct samr_GetUserPwInfo pwp;
769 int policy_min_pw_len = 0;
770 pwp.in.user_handle = handle;
772 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
773 if (NT_STATUS_IS_OK(status)) {
774 policy_min_pw_len = pwp.out.info.min_password_length;
776 newpass = samr_rand_pass(tctx, policy_min_pw_len);
778 s.in.user_handle = handle;
784 u.info25.info.fields_present = fields_present;
786 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
788 status = dcerpc_fetch_session_key(p, &session_key);
789 if (!NT_STATUS_IS_OK(status)) {
790 printf("SetUserInfo level %u - no session key - %s\n",
791 s.in.level, nt_errstr(status));
795 generate_random_buffer((uint8_t *)confounder, 16);
798 MD5Update(&ctx, confounder, 16);
799 MD5Update(&ctx, session_key.data, session_key.length);
800 MD5Final(confounded_session_key.data, &ctx);
802 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
803 memcpy(&u.info25.password.data[516], confounder, 16);
805 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex)\n");
807 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
808 if (!NT_STATUS_IS_OK(status)) {
809 printf("SetUserInfo level %u failed - %s\n",
810 s.in.level, nt_errstr(status));
816 /* This should break the key nicely */
817 confounded_session_key.data[0]++;
819 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
820 memcpy(&u.info25.password.data[516], confounder, 16);
822 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
824 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
825 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
826 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
827 s.in.level, nt_errstr(status));
834 static bool test_SetAliasInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
835 struct policy_handle *handle)
838 struct samr_SetAliasInfo r;
839 struct samr_QueryAliasInfo q;
840 uint16_t levels[] = {2, 3};
844 /* Ignoring switch level 1, as that includes the number of members for the alias
845 * and setting this to a wrong value might have negative consequences
848 for (i=0;i<ARRAY_SIZE(levels);i++) {
849 torture_comment(tctx, "Testing SetAliasInfo level %u\n", levels[i]);
851 r.in.alias_handle = handle;
852 r.in.level = levels[i];
853 r.in.info = talloc(tctx, union samr_AliasInfo);
854 switch (r.in.level) {
855 case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
856 case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
857 "Test Description, should test I18N as well"); break;
858 case ALIASINFOALL: printf("ALIASINFOALL ignored\n"); break;
861 status = dcerpc_samr_SetAliasInfo(p, tctx, &r);
862 if (!NT_STATUS_IS_OK(status)) {
863 printf("SetAliasInfo level %u failed - %s\n",
864 levels[i], nt_errstr(status));
868 q.in.alias_handle = handle;
869 q.in.level = levels[i];
871 status = dcerpc_samr_QueryAliasInfo(p, tctx, &q);
872 if (!NT_STATUS_IS_OK(status)) {
873 printf("QueryAliasInfo level %u failed - %s\n",
874 levels[i], nt_errstr(status));
882 static bool test_GetGroupsForUser(struct dcerpc_pipe *p, struct torture_context *tctx,
883 struct policy_handle *user_handle)
885 struct samr_GetGroupsForUser r;
888 torture_comment(tctx, "testing GetGroupsForUser\n");
890 r.in.user_handle = user_handle;
892 status = dcerpc_samr_GetGroupsForUser(p, tctx, &r);
893 torture_assert_ntstatus_ok(tctx, status, "GetGroupsForUser");
899 static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
900 struct lsa_String *domain_name)
903 struct samr_GetDomPwInfo r;
905 r.in.domain_name = domain_name;
906 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
908 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
909 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
911 r.in.domain_name->string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
912 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
914 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
915 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
917 r.in.domain_name->string = "\\\\__NONAME__";
918 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
920 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
921 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
923 r.in.domain_name->string = "\\\\Builtin";
924 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
926 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
927 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
932 static bool test_GetUserPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
933 struct policy_handle *handle)
936 struct samr_GetUserPwInfo r;
938 torture_comment(tctx, "Testing GetUserPwInfo\n");
940 r.in.user_handle = handle;
942 status = dcerpc_samr_GetUserPwInfo(p, tctx, &r);
943 torture_assert_ntstatus_ok(tctx, status, "GetUserPwInfo");
948 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, struct torture_context *tctx,
949 struct policy_handle *domain_handle, const char *name,
953 struct samr_LookupNames n;
954 struct lsa_String sname[2];
956 init_lsa_String(&sname[0], name);
958 n.in.domain_handle = domain_handle;
961 status = dcerpc_samr_LookupNames(p, tctx, &n);
962 if (NT_STATUS_IS_OK(status)) {
963 *rid = n.out.rids.ids[0];
968 init_lsa_String(&sname[1], "xxNONAMExx");
970 status = dcerpc_samr_LookupNames(p, tctx, &n);
971 if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
972 printf("LookupNames[2] failed - %s\n", nt_errstr(status));
973 if (NT_STATUS_IS_OK(status)) {
974 return NT_STATUS_UNSUCCESSFUL;
980 status = dcerpc_samr_LookupNames(p, tctx, &n);
981 if (!NT_STATUS_IS_OK(status)) {
982 printf("LookupNames[0] failed - %s\n", nt_errstr(status));
986 init_lsa_String(&sname[0], "xxNONAMExx");
988 status = dcerpc_samr_LookupNames(p, tctx, &n);
989 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
990 printf("LookupNames[1 bad name] failed - %s\n", nt_errstr(status));
991 if (NT_STATUS_IS_OK(status)) {
992 return NT_STATUS_UNSUCCESSFUL;
997 init_lsa_String(&sname[0], "xxNONAMExx");
998 init_lsa_String(&sname[1], "xxNONAME2xx");
1000 status = dcerpc_samr_LookupNames(p, tctx, &n);
1001 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1002 printf("LookupNames[2 bad names] failed - %s\n", nt_errstr(status));
1003 if (NT_STATUS_IS_OK(status)) {
1004 return NT_STATUS_UNSUCCESSFUL;
1009 return NT_STATUS_OK;
1012 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1013 struct policy_handle *domain_handle,
1014 const char *name, struct policy_handle *user_handle)
1017 struct samr_OpenUser r;
1020 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
1021 if (!NT_STATUS_IS_OK(status)) {
1025 r.in.domain_handle = domain_handle;
1026 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1028 r.out.user_handle = user_handle;
1029 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
1030 if (!NT_STATUS_IS_OK(status)) {
1031 printf("OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(status));
1038 static bool test_ChangePasswordNT3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1039 struct policy_handle *handle)
1042 struct samr_ChangePasswordUser r;
1044 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1045 struct policy_handle user_handle;
1046 char *oldpass = "test";
1047 char *newpass = "test2";
1048 uint8_t old_nt_hash[16], new_nt_hash[16];
1049 uint8_t old_lm_hash[16], new_lm_hash[16];
1051 status = test_OpenUser_byname(p, mem_ctx, handle, "testuser", &user_handle);
1052 if (!NT_STATUS_IS_OK(status)) {
1056 printf("Testing ChangePasswordUser for user 'testuser'\n");
1058 printf("old password: %s\n", oldpass);
1059 printf("new password: %s\n", newpass);
1061 E_md4hash(oldpass, old_nt_hash);
1062 E_md4hash(newpass, new_nt_hash);
1063 E_deshash(oldpass, old_lm_hash);
1064 E_deshash(newpass, new_lm_hash);
1066 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1067 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1068 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1069 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1070 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1071 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1073 r.in.handle = &user_handle;
1074 r.in.lm_present = 1;
1075 r.in.old_lm_crypted = &hash1;
1076 r.in.new_lm_crypted = &hash2;
1077 r.in.nt_present = 1;
1078 r.in.old_nt_crypted = &hash3;
1079 r.in.new_nt_crypted = &hash4;
1080 r.in.cross1_present = 1;
1081 r.in.nt_cross = &hash5;
1082 r.in.cross2_present = 1;
1083 r.in.lm_cross = &hash6;
1085 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1086 if (!NT_STATUS_IS_OK(status)) {
1087 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1091 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1099 static bool test_ChangePasswordUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1100 const char *acct_name,
1101 struct policy_handle *handle, char **password)
1104 struct samr_ChangePasswordUser r;
1106 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1107 struct policy_handle user_handle;
1109 uint8_t old_nt_hash[16], new_nt_hash[16];
1110 uint8_t old_lm_hash[16], new_lm_hash[16];
1111 bool changed = true;
1114 struct samr_GetUserPwInfo pwp;
1115 int policy_min_pw_len = 0;
1117 status = test_OpenUser_byname(p, tctx, handle, acct_name, &user_handle);
1118 if (!NT_STATUS_IS_OK(status)) {
1121 pwp.in.user_handle = &user_handle;
1123 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1124 if (NT_STATUS_IS_OK(status)) {
1125 policy_min_pw_len = pwp.out.info.min_password_length;
1127 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1129 torture_comment(tctx, "Testing ChangePasswordUser\n");
1131 torture_assert(tctx, *password != NULL,
1132 "Failing ChangePasswordUser as old password was NULL. Previous test failed?");
1134 oldpass = *password;
1136 E_md4hash(oldpass, old_nt_hash);
1137 E_md4hash(newpass, new_nt_hash);
1138 E_deshash(oldpass, old_lm_hash);
1139 E_deshash(newpass, new_lm_hash);
1141 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1142 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1143 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1144 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1145 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1146 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1148 r.in.user_handle = &user_handle;
1149 r.in.lm_present = 1;
1150 /* Break the LM hash */
1152 r.in.old_lm_crypted = &hash1;
1153 r.in.new_lm_crypted = &hash2;
1154 r.in.nt_present = 1;
1155 r.in.old_nt_crypted = &hash3;
1156 r.in.new_nt_crypted = &hash4;
1157 r.in.cross1_present = 1;
1158 r.in.nt_cross = &hash5;
1159 r.in.cross2_present = 1;
1160 r.in.lm_cross = &hash6;
1162 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1163 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1164 "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash");
1166 /* Unbreak the LM hash */
1169 r.in.user_handle = &user_handle;
1170 r.in.lm_present = 1;
1171 r.in.old_lm_crypted = &hash1;
1172 r.in.new_lm_crypted = &hash2;
1173 /* Break the NT hash */
1175 r.in.nt_present = 1;
1176 r.in.old_nt_crypted = &hash3;
1177 r.in.new_nt_crypted = &hash4;
1178 r.in.cross1_present = 1;
1179 r.in.nt_cross = &hash5;
1180 r.in.cross2_present = 1;
1181 r.in.lm_cross = &hash6;
1183 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1184 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1185 "expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash");
1187 /* Unbreak the NT hash */
1190 r.in.user_handle = &user_handle;
1191 r.in.lm_present = 1;
1192 r.in.old_lm_crypted = &hash1;
1193 r.in.new_lm_crypted = &hash2;
1194 r.in.nt_present = 1;
1195 r.in.old_nt_crypted = &hash3;
1196 r.in.new_nt_crypted = &hash4;
1197 r.in.cross1_present = 1;
1198 r.in.nt_cross = &hash5;
1199 r.in.cross2_present = 1;
1200 /* Break the LM cross */
1202 r.in.lm_cross = &hash6;
1204 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1205 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1206 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status));
1210 /* Unbreak the LM cross */
1213 r.in.user_handle = &user_handle;
1214 r.in.lm_present = 1;
1215 r.in.old_lm_crypted = &hash1;
1216 r.in.new_lm_crypted = &hash2;
1217 r.in.nt_present = 1;
1218 r.in.old_nt_crypted = &hash3;
1219 r.in.new_nt_crypted = &hash4;
1220 r.in.cross1_present = 1;
1221 /* Break the NT cross */
1223 r.in.nt_cross = &hash5;
1224 r.in.cross2_present = 1;
1225 r.in.lm_cross = &hash6;
1227 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1228 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1229 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status));
1233 /* Unbreak the NT cross */
1237 /* Reset the hashes to not broken values */
1238 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1239 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1240 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1241 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1242 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1243 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1245 r.in.user_handle = &user_handle;
1246 r.in.lm_present = 1;
1247 r.in.old_lm_crypted = &hash1;
1248 r.in.new_lm_crypted = &hash2;
1249 r.in.nt_present = 1;
1250 r.in.old_nt_crypted = &hash3;
1251 r.in.new_nt_crypted = &hash4;
1252 r.in.cross1_present = 1;
1253 r.in.nt_cross = &hash5;
1254 r.in.cross2_present = 0;
1255 r.in.lm_cross = NULL;
1257 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1258 if (NT_STATUS_IS_OK(status)) {
1260 *password = newpass;
1261 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1262 printf("ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(status));
1267 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1269 E_md4hash(oldpass, old_nt_hash);
1270 E_md4hash(newpass, new_nt_hash);
1271 E_deshash(oldpass, old_lm_hash);
1272 E_deshash(newpass, new_lm_hash);
1275 /* Reset the hashes to not broken values */
1276 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1277 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1278 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1279 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1280 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1281 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1283 r.in.user_handle = &user_handle;
1284 r.in.lm_present = 1;
1285 r.in.old_lm_crypted = &hash1;
1286 r.in.new_lm_crypted = &hash2;
1287 r.in.nt_present = 1;
1288 r.in.old_nt_crypted = &hash3;
1289 r.in.new_nt_crypted = &hash4;
1290 r.in.cross1_present = 0;
1291 r.in.nt_cross = NULL;
1292 r.in.cross2_present = 1;
1293 r.in.lm_cross = &hash6;
1295 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1296 if (NT_STATUS_IS_OK(status)) {
1298 *password = newpass;
1299 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1300 printf("ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status));
1305 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1307 E_md4hash(oldpass, old_nt_hash);
1308 E_md4hash(newpass, new_nt_hash);
1309 E_deshash(oldpass, old_lm_hash);
1310 E_deshash(newpass, new_lm_hash);
1313 /* Reset the hashes to not broken values */
1314 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1315 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1316 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1317 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1318 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1319 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1321 r.in.user_handle = &user_handle;
1322 r.in.lm_present = 1;
1323 r.in.old_lm_crypted = &hash1;
1324 r.in.new_lm_crypted = &hash2;
1325 r.in.nt_present = 1;
1326 r.in.old_nt_crypted = &hash3;
1327 r.in.new_nt_crypted = &hash4;
1328 r.in.cross1_present = 1;
1329 r.in.nt_cross = &hash5;
1330 r.in.cross2_present = 1;
1331 r.in.lm_cross = &hash6;
1333 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1334 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1335 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1336 } else if (!NT_STATUS_IS_OK(status)) {
1337 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1341 *password = newpass;
1344 r.in.user_handle = &user_handle;
1345 r.in.lm_present = 1;
1346 r.in.old_lm_crypted = &hash1;
1347 r.in.new_lm_crypted = &hash2;
1348 r.in.nt_present = 1;
1349 r.in.old_nt_crypted = &hash3;
1350 r.in.new_nt_crypted = &hash4;
1351 r.in.cross1_present = 1;
1352 r.in.nt_cross = &hash5;
1353 r.in.cross2_present = 1;
1354 r.in.lm_cross = &hash6;
1357 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1358 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1359 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1360 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1361 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status));
1367 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
1375 static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
1376 const char *acct_name,
1377 struct policy_handle *handle, char **password)
1380 struct samr_OemChangePasswordUser2 r;
1382 struct samr_Password lm_verifier;
1383 struct samr_CryptPassword lm_pass;
1384 struct lsa_AsciiString server, account, account_bad;
1387 uint8_t old_lm_hash[16], new_lm_hash[16];
1389 struct samr_GetDomPwInfo dom_pw_info;
1390 int policy_min_pw_len = 0;
1392 struct lsa_String domain_name;
1394 domain_name.string = "";
1395 dom_pw_info.in.domain_name = &domain_name;
1397 torture_comment(tctx, "Testing OemChangePasswordUser2\n");
1399 torture_assert(tctx, *password != NULL,
1400 "Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?");
1402 oldpass = *password;
1404 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
1405 if (NT_STATUS_IS_OK(status)) {
1406 policy_min_pw_len = dom_pw_info.out.info.min_password_length;
1409 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1411 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1412 account.string = acct_name;
1414 E_deshash(oldpass, old_lm_hash);
1415 E_deshash(newpass, new_lm_hash);
1417 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1418 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1419 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1421 r.in.server = &server;
1422 r.in.account = &account;
1423 r.in.password = &lm_pass;
1424 r.in.hash = &lm_verifier;
1426 /* Break the verification */
1427 lm_verifier.hash[0]++;
1429 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1431 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1432 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1433 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1438 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1439 /* Break the old password */
1441 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1442 /* unbreak it for the next operation */
1444 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1446 r.in.server = &server;
1447 r.in.account = &account;
1448 r.in.password = &lm_pass;
1449 r.in.hash = &lm_verifier;
1451 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 invalidly encrpted password - %s\n",
1460 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1461 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1463 r.in.server = &server;
1464 r.in.account = &account;
1465 r.in.password = &lm_pass;
1468 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1470 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1471 && !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1472 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
1477 /* This shouldn't be a valid name */
1478 account_bad.string = TEST_ACCOUNT_NAME "XX";
1479 r.in.account = &account_bad;
1481 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1483 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1484 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
1489 /* This shouldn't be a valid name */
1490 account_bad.string = TEST_ACCOUNT_NAME "XX";
1491 r.in.account = &account_bad;
1492 r.in.password = &lm_pass;
1493 r.in.hash = &lm_verifier;
1495 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1497 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1498 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1503 /* This shouldn't be a valid name */
1504 account_bad.string = TEST_ACCOUNT_NAME "XX";
1505 r.in.account = &account_bad;
1506 r.in.password = NULL;
1507 r.in.hash = &lm_verifier;
1509 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1511 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1512 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
1517 E_deshash(oldpass, old_lm_hash);
1518 E_deshash(newpass, new_lm_hash);
1520 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1521 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1522 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1524 r.in.server = &server;
1525 r.in.account = &account;
1526 r.in.password = &lm_pass;
1527 r.in.hash = &lm_verifier;
1529 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1530 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1531 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1532 } else if (!NT_STATUS_IS_OK(status)) {
1533 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
1536 *password = newpass;
1543 static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
1544 const char *acct_name,
1546 char *newpass, bool allow_password_restriction)
1549 struct samr_ChangePasswordUser2 r;
1551 struct lsa_String server, account;
1552 struct samr_CryptPassword nt_pass, lm_pass;
1553 struct samr_Password nt_verifier, lm_verifier;
1555 uint8_t old_nt_hash[16], new_nt_hash[16];
1556 uint8_t old_lm_hash[16], new_lm_hash[16];
1558 struct samr_GetDomPwInfo dom_pw_info;
1560 struct lsa_String domain_name;
1562 domain_name.string = "";
1563 dom_pw_info.in.domain_name = &domain_name;
1565 torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name);
1567 torture_assert(tctx, *password != NULL,
1568 "Failing ChangePasswordUser2 as old password was NULL. Previous test failed?");
1569 oldpass = *password;
1572 int policy_min_pw_len = 0;
1573 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
1574 if (NT_STATUS_IS_OK(status)) {
1575 policy_min_pw_len = dom_pw_info.out.info.min_password_length;
1578 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1581 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1582 init_lsa_String(&account, acct_name);
1584 E_md4hash(oldpass, old_nt_hash);
1585 E_md4hash(newpass, new_nt_hash);
1587 E_deshash(oldpass, old_lm_hash);
1588 E_deshash(newpass, new_lm_hash);
1590 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
1591 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1592 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1594 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1595 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1596 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1598 r.in.server = &server;
1599 r.in.account = &account;
1600 r.in.nt_password = &nt_pass;
1601 r.in.nt_verifier = &nt_verifier;
1603 r.in.lm_password = &lm_pass;
1604 r.in.lm_verifier = &lm_verifier;
1606 status = dcerpc_samr_ChangePasswordUser2(p, tctx, &r);
1607 if (allow_password_restriction && NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1608 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1609 } else if (!NT_STATUS_IS_OK(status)) {
1610 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
1613 *password = newpass;
1620 bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tctx,
1621 const char *account_string,
1622 int policy_min_pw_len,
1624 const char *newpass,
1625 NTTIME last_password_change,
1626 bool handle_reject_reason)
1629 struct samr_ChangePasswordUser3 r;
1631 struct lsa_String server, account, account_bad;
1632 struct samr_CryptPassword nt_pass, lm_pass;
1633 struct samr_Password nt_verifier, lm_verifier;
1635 uint8_t old_nt_hash[16], new_nt_hash[16];
1636 uint8_t old_lm_hash[16], new_lm_hash[16];
1638 struct samr_DomInfo1 *dominfo = NULL;
1639 struct samr_ChangeReject *reject = NULL;
1641 torture_comment(tctx, "Testing ChangePasswordUser3\n");
1643 if (newpass == NULL) {
1645 if (policy_min_pw_len == 0) {
1646 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1648 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len);
1650 } while (check_password_quality(newpass) == false);
1652 torture_comment(tctx, "Using password '%s'\n", newpass);
1655 torture_assert(tctx, *password != NULL,
1656 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
1658 oldpass = *password;
1659 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1660 init_lsa_String(&account, account_string);
1662 E_md4hash(oldpass, old_nt_hash);
1663 E_md4hash(newpass, new_nt_hash);
1665 E_deshash(oldpass, old_lm_hash);
1666 E_deshash(newpass, new_lm_hash);
1668 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1669 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1670 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1672 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1673 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1674 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1676 /* Break the verification */
1677 nt_verifier.hash[0]++;
1679 r.in.server = &server;
1680 r.in.account = &account;
1681 r.in.nt_password = &nt_pass;
1682 r.in.nt_verifier = &nt_verifier;
1684 r.in.lm_password = &lm_pass;
1685 r.in.lm_verifier = &lm_verifier;
1686 r.in.password3 = NULL;
1687 r.out.dominfo = &dominfo;
1688 r.out.reject = &reject;
1690 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1691 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1692 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1693 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1698 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1699 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1700 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1702 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1703 /* Break the NT hash */
1705 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1706 /* Unbreak it again */
1708 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1710 r.in.server = &server;
1711 r.in.account = &account;
1712 r.in.nt_password = &nt_pass;
1713 r.in.nt_verifier = &nt_verifier;
1715 r.in.lm_password = &lm_pass;
1716 r.in.lm_verifier = &lm_verifier;
1717 r.in.password3 = NULL;
1718 r.out.dominfo = &dominfo;
1719 r.out.reject = &reject;
1721 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1722 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1723 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1724 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1729 /* This shouldn't be a valid name */
1730 init_lsa_String(&account_bad, talloc_asprintf(tctx, "%sXX", account_string));
1732 r.in.account = &account_bad;
1733 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1734 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1735 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
1740 E_md4hash(oldpass, old_nt_hash);
1741 E_md4hash(newpass, new_nt_hash);
1743 E_deshash(oldpass, old_lm_hash);
1744 E_deshash(newpass, new_lm_hash);
1746 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1747 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1748 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1750 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1751 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1752 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1754 r.in.server = &server;
1755 r.in.account = &account;
1756 r.in.nt_password = &nt_pass;
1757 r.in.nt_verifier = &nt_verifier;
1759 r.in.lm_password = &lm_pass;
1760 r.in.lm_verifier = &lm_verifier;
1761 r.in.password3 = NULL;
1762 r.out.dominfo = &dominfo;
1763 r.out.reject = &reject;
1765 unix_to_nt_time(&t, time(NULL));
1767 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1769 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1772 && handle_reject_reason
1773 && (!null_nttime(last_password_change) || !dominfo->min_password_age)) {
1774 if (dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
1776 if (reject && (reject->reason != SAMR_REJECT_OTHER)) {
1777 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1778 SAMR_REJECT_OTHER, reject->reason);
1783 /* We tested the order of precendence which is as follows:
1792 if ((dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
1793 (last_password_change + dominfo->min_password_age > t)) {
1795 if (reject->reason != SAMR_REJECT_OTHER) {
1796 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1797 SAMR_REJECT_OTHER, reject->reason);
1801 } else if ((dominfo->min_password_length > 0) &&
1802 (strlen(newpass) < dominfo->min_password_length)) {
1804 if (reject->reason != SAMR_REJECT_TOO_SHORT) {
1805 printf("expected SAMR_REJECT_TOO_SHORT (%d), got %d\n",
1806 SAMR_REJECT_TOO_SHORT, reject->reason);
1810 } else if ((dominfo->password_history_length > 0) &&
1811 strequal(oldpass, newpass)) {
1813 if (reject->reason != SAMR_REJECT_IN_HISTORY) {
1814 printf("expected SAMR_REJECT_IN_HISTORY (%d), got %d\n",
1815 SAMR_REJECT_IN_HISTORY, reject->reason);
1818 } else if (dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
1820 if (reject->reason != SAMR_REJECT_COMPLEXITY) {
1821 printf("expected SAMR_REJECT_COMPLEXITY (%d), got %d\n",
1822 SAMR_REJECT_COMPLEXITY, reject->reason);
1828 if (reject->reason == SAMR_REJECT_TOO_SHORT) {
1829 /* retry with adjusted size */
1830 return test_ChangePasswordUser3(p, tctx, account_string,
1831 dominfo->min_password_length,
1832 password, NULL, 0, false);
1836 } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1837 if (reject && reject->reason != SAMR_REJECT_OTHER) {
1838 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1839 SAMR_REJECT_OTHER, reject->reason);
1842 /* Perhaps the server has a 'min password age' set? */
1845 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3");
1846 *password = talloc_strdup(tctx, newpass);
1852 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_context *tctx,
1853 const char *account_string,
1854 struct policy_handle *handle,
1858 struct samr_ChangePasswordUser3 r;
1859 struct samr_SetUserInfo s;
1860 union samr_UserInfo u;
1861 DATA_BLOB session_key;
1862 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
1863 uint8_t confounder[16];
1864 struct MD5Context ctx;
1867 struct lsa_String server, account;
1868 struct samr_CryptPassword nt_pass;
1869 struct samr_Password nt_verifier;
1870 DATA_BLOB new_random_pass;
1873 uint8_t old_nt_hash[16], new_nt_hash[16];
1875 struct samr_DomInfo1 *dominfo = NULL;
1876 struct samr_ChangeReject *reject = NULL;
1878 new_random_pass = samr_very_rand_pass(tctx, 128);
1880 torture_assert(tctx, *password != NULL,
1881 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
1883 oldpass = *password;
1884 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1885 init_lsa_String(&account, account_string);
1887 s.in.user_handle = handle;
1893 u.info25.info.fields_present = SAMR_FIELD_PASSWORD;
1895 set_pw_in_buffer(u.info25.password.data, &new_random_pass);
1897 status = dcerpc_fetch_session_key(p, &session_key);
1898 if (!NT_STATUS_IS_OK(status)) {
1899 printf("SetUserInfo level %u - no session key - %s\n",
1900 s.in.level, nt_errstr(status));
1904 generate_random_buffer((uint8_t *)confounder, 16);
1907 MD5Update(&ctx, confounder, 16);
1908 MD5Update(&ctx, session_key.data, session_key.length);
1909 MD5Final(confounded_session_key.data, &ctx);
1911 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
1912 memcpy(&u.info25.password.data[516], confounder, 16);
1914 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
1916 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1917 if (!NT_STATUS_IS_OK(status)) {
1918 printf("SetUserInfo level %u failed - %s\n",
1919 s.in.level, nt_errstr(status));
1923 torture_comment(tctx, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
1925 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
1927 new_random_pass = samr_very_rand_pass(tctx, 128);
1929 mdfour(new_nt_hash, new_random_pass.data, new_random_pass.length);
1931 set_pw_in_buffer(nt_pass.data, &new_random_pass);
1932 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1933 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1935 r.in.server = &server;
1936 r.in.account = &account;
1937 r.in.nt_password = &nt_pass;
1938 r.in.nt_verifier = &nt_verifier;
1940 r.in.lm_password = NULL;
1941 r.in.lm_verifier = NULL;
1942 r.in.password3 = NULL;
1943 r.out.dominfo = &dominfo;
1944 r.out.reject = &reject;
1946 unix_to_nt_time(&t, time(NULL));
1948 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1950 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1951 if (reject && reject->reason != SAMR_REJECT_OTHER) {
1952 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1953 SAMR_REJECT_OTHER, reject->reason);
1956 /* Perhaps the server has a 'min password age' set? */
1958 } else if (!NT_STATUS_IS_OK(status)) {
1959 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
1963 newpass = samr_rand_pass(tctx, 128);
1965 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
1967 E_md4hash(newpass, new_nt_hash);
1969 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1970 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1971 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1973 r.in.server = &server;
1974 r.in.account = &account;
1975 r.in.nt_password = &nt_pass;
1976 r.in.nt_verifier = &nt_verifier;
1978 r.in.lm_password = NULL;
1979 r.in.lm_verifier = NULL;
1980 r.in.password3 = NULL;
1981 r.out.dominfo = &dominfo;
1982 r.out.reject = &reject;
1984 unix_to_nt_time(&t, time(NULL));
1986 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1988 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1989 if (reject && reject->reason != SAMR_REJECT_OTHER) {
1990 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1991 SAMR_REJECT_OTHER, reject->reason);
1994 /* Perhaps the server has a 'min password age' set? */
1997 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3 (on second random password)");
1998 *password = talloc_strdup(tctx, newpass);
2005 static bool test_GetMembersInAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2006 struct policy_handle *alias_handle)
2008 struct samr_GetMembersInAlias r;
2009 struct lsa_SidArray sids;
2012 torture_comment(tctx, "Testing GetMembersInAlias\n");
2014 r.in.alias_handle = alias_handle;
2017 status = dcerpc_samr_GetMembersInAlias(p, tctx, &r);
2018 torture_assert_ntstatus_ok(tctx, status, "GetMembersInAlias");
2023 static bool test_AddMemberToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2024 struct policy_handle *alias_handle,
2025 const struct dom_sid *domain_sid)
2027 struct samr_AddAliasMember r;
2028 struct samr_DeleteAliasMember d;
2030 struct dom_sid *sid;
2032 sid = dom_sid_add_rid(tctx, domain_sid, 512);
2034 torture_comment(tctx, "testing AddAliasMember\n");
2035 r.in.alias_handle = alias_handle;
2038 status = dcerpc_samr_AddAliasMember(p, tctx, &r);
2039 torture_assert_ntstatus_ok(tctx, status, "AddAliasMember");
2041 d.in.alias_handle = alias_handle;
2044 status = dcerpc_samr_DeleteAliasMember(p, tctx, &d);
2045 torture_assert_ntstatus_ok(tctx, status, "DelAliasMember");
2050 static bool test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2051 struct policy_handle *alias_handle)
2053 struct samr_AddMultipleMembersToAlias a;
2054 struct samr_RemoveMultipleMembersFromAlias r;
2056 struct lsa_SidArray sids;
2058 torture_comment(tctx, "testing AddMultipleMembersToAlias\n");
2059 a.in.alias_handle = alias_handle;
2063 sids.sids = talloc_array(tctx, struct lsa_SidPtr, 3);
2065 sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2066 sids.sids[1].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-2");
2067 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-3");
2069 status = dcerpc_samr_AddMultipleMembersToAlias(p, tctx, &a);
2070 torture_assert_ntstatus_ok(tctx, status, "AddMultipleMembersToAlias");
2073 torture_comment(tctx, "testing RemoveMultipleMembersFromAlias\n");
2074 r.in.alias_handle = alias_handle;
2077 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2078 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2080 /* strange! removing twice doesn't give any error */
2081 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2082 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2084 /* but removing an alias that isn't there does */
2085 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-4");
2087 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2088 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, "RemoveMultipleMembersFromAlias");
2093 static bool test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2094 struct policy_handle *user_handle)
2096 struct samr_TestPrivateFunctionsUser r;
2099 torture_comment(tctx, "Testing TestPrivateFunctionsUser\n");
2101 r.in.user_handle = user_handle;
2103 status = dcerpc_samr_TestPrivateFunctionsUser(p, tctx, &r);
2104 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsUser");
2110 static bool test_user_ops(struct dcerpc_pipe *p,
2111 struct torture_context *tctx,
2112 struct policy_handle *user_handle,
2113 struct policy_handle *domain_handle,
2114 uint32_t base_acct_flags,
2115 const char *base_acct_name, enum torture_samr_choice which_ops)
2117 char *password = NULL;
2118 struct samr_QueryUserInfo q;
2124 const uint32_t password_fields[] = {
2125 SAMR_FIELD_PASSWORD,
2126 SAMR_FIELD_PASSWORD2,
2127 SAMR_FIELD_PASSWORD | SAMR_FIELD_PASSWORD2,
2131 status = test_LookupName(p, tctx, domain_handle, base_acct_name, &rid);
2132 if (!NT_STATUS_IS_OK(status)) {
2136 switch (which_ops) {
2137 case TORTURE_SAMR_USER_ATTRIBUTES:
2138 if (!test_QuerySecurity(p, tctx, user_handle)) {
2142 if (!test_QueryUserInfo(p, tctx, user_handle)) {
2146 if (!test_QueryUserInfo2(p, tctx, user_handle)) {
2150 if (!test_SetUserInfo(p, tctx, user_handle, base_acct_flags,
2155 if (!test_GetUserPwInfo(p, tctx, user_handle)) {
2159 if (!test_TestPrivateFunctionsUser(p, tctx, user_handle)) {
2163 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
2167 case TORTURE_SAMR_PASSWORDS:
2168 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
2169 char simple_pass[9];
2170 char *v = generate_random_str(tctx, 1);
2172 ZERO_STRUCT(simple_pass);
2173 memset(simple_pass, *v, sizeof(simple_pass) - 1);
2175 printf("Testing machine account password policy rules\n");
2177 /* Workstation trust accounts don't seem to need to honour password quality policy */
2178 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
2182 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
2186 /* reset again, to allow another 'user' password change */
2187 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
2191 /* Try a 'short' password */
2192 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
2196 /* Try a compleatly random password */
2197 if (!test_ChangePasswordRandomBytes(p, tctx, base_acct_name, user_handle, &password)) {
2202 for (i = 0; password_fields[i]; i++) {
2203 if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
2207 /* check it was set right */
2208 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
2213 for (i = 0; password_fields[i]; i++) {
2214 if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
2218 /* check it was set right */
2219 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
2224 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
2228 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
2232 q.in.user_handle = user_handle;
2235 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
2236 if (!NT_STATUS_IS_OK(status)) {
2237 printf("QueryUserInfo level %u failed - %s\n",
2238 q.in.level, nt_errstr(status));
2241 uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
2242 if ((q.out.info->info5.acct_flags) != expected_flags) {
2243 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2244 q.out.info->info5.acct_flags,
2248 if (q.out.info->info5.rid != rid) {
2249 printf("QuerUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
2250 q.out.info->info5.rid, rid);
2256 case TORTURE_SAMR_OTHER:
2257 /* We just need the account to exist */
2263 static bool test_alias_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
2264 struct policy_handle *alias_handle,
2265 const struct dom_sid *domain_sid)
2269 if (!test_QuerySecurity(p, tctx, alias_handle)) {
2273 if (!test_QueryAliasInfo(p, tctx, alias_handle)) {
2277 if (!test_SetAliasInfo(p, tctx, alias_handle)) {
2281 if (!test_AddMemberToAlias(p, tctx, alias_handle, domain_sid)) {
2285 if (torture_setting_bool(tctx, "samba4", false)) {
2286 printf("skipping MultipleMembers Alias tests against Samba4\n");
2290 if (!test_AddMultipleMembersToAlias(p, tctx, alias_handle)) {
2298 static bool test_DeleteUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2299 struct policy_handle *user_handle)
2301 struct samr_DeleteUser d;
2303 torture_comment(tctx, "Testing DeleteUser\n");
2305 d.in.user_handle = user_handle;
2306 d.out.user_handle = user_handle;
2308 status = dcerpc_samr_DeleteUser(p, tctx, &d);
2309 torture_assert_ntstatus_ok(tctx, status, "DeleteUser");
2314 bool test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2315 struct policy_handle *handle, const char *name)
2318 struct samr_DeleteUser d;
2319 struct policy_handle user_handle;
2322 status = test_LookupName(p, mem_ctx, handle, name, &rid);
2323 if (!NT_STATUS_IS_OK(status)) {
2327 status = test_OpenUser_byname(p, mem_ctx, handle, name, &user_handle);
2328 if (!NT_STATUS_IS_OK(status)) {
2332 d.in.user_handle = &user_handle;
2333 d.out.user_handle = &user_handle;
2334 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
2335 if (!NT_STATUS_IS_OK(status)) {
2342 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
2347 static bool test_DeleteGroup_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2348 struct policy_handle *handle, const char *name)
2351 struct samr_OpenGroup r;
2352 struct samr_DeleteDomainGroup d;
2353 struct policy_handle group_handle;
2356 status = test_LookupName(p, mem_ctx, handle, name, &rid);
2357 if (!NT_STATUS_IS_OK(status)) {
2361 r.in.domain_handle = handle;
2362 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2364 r.out.group_handle = &group_handle;
2365 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
2366 if (!NT_STATUS_IS_OK(status)) {
2370 d.in.group_handle = &group_handle;
2371 d.out.group_handle = &group_handle;
2372 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
2373 if (!NT_STATUS_IS_OK(status)) {
2380 printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
2385 static bool test_DeleteAlias_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2386 struct policy_handle *domain_handle, const char *name)
2389 struct samr_OpenAlias r;
2390 struct samr_DeleteDomAlias d;
2391 struct policy_handle alias_handle;
2394 printf("testing DeleteAlias_byname\n");
2396 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
2397 if (!NT_STATUS_IS_OK(status)) {
2401 r.in.domain_handle = domain_handle;
2402 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2404 r.out.alias_handle = &alias_handle;
2405 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
2406 if (!NT_STATUS_IS_OK(status)) {
2410 d.in.alias_handle = &alias_handle;
2411 d.out.alias_handle = &alias_handle;
2412 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
2413 if (!NT_STATUS_IS_OK(status)) {
2420 printf("DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
2424 static bool test_DeleteAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2425 struct policy_handle *alias_handle)
2427 struct samr_DeleteDomAlias d;
2430 printf("Testing DeleteAlias\n");
2432 d.in.alias_handle = alias_handle;
2433 d.out.alias_handle = alias_handle;
2435 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
2436 if (!NT_STATUS_IS_OK(status)) {
2437 printf("DeleteAlias failed - %s\n", nt_errstr(status));
2444 static bool test_CreateAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2445 struct policy_handle *domain_handle,
2446 struct policy_handle *alias_handle,
2447 const struct dom_sid *domain_sid)
2450 struct samr_CreateDomAlias r;
2451 struct lsa_String name;
2455 init_lsa_String(&name, TEST_ALIASNAME);
2456 r.in.domain_handle = domain_handle;
2457 r.in.alias_name = &name;
2458 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2459 r.out.alias_handle = alias_handle;
2462 printf("Testing CreateAlias (%s)\n", r.in.alias_name->string);
2464 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
2466 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
2467 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2468 printf("Server correctly refused create of '%s'\n", r.in.alias_name->string);
2471 printf("Server should have refused create of '%s', got %s instead\n", r.in.alias_name->string,
2477 if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
2478 if (!test_DeleteAlias_byname(p, tctx, domain_handle, r.in.alias_name->string)) {
2481 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
2484 if (!NT_STATUS_IS_OK(status)) {
2485 printf("CreateAlias failed - %s\n", nt_errstr(status));
2489 if (!test_alias_ops(p, tctx, alias_handle, domain_sid)) {
2496 static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2497 const char *acct_name,
2498 struct policy_handle *domain_handle, char **password)
2506 if (!test_ChangePasswordUser(p, mem_ctx, acct_name, domain_handle, password)) {
2510 if (!test_ChangePasswordUser2(p, mem_ctx, acct_name, password, 0, true)) {
2514 if (!test_OemChangePasswordUser2(p, mem_ctx, acct_name, domain_handle, password)) {
2518 /* test what happens when setting the old password again */
2519 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, *password, 0, true)) {
2524 char simple_pass[9];
2525 char *v = generate_random_str(mem_ctx, 1);
2527 ZERO_STRUCT(simple_pass);
2528 memset(simple_pass, *v, sizeof(simple_pass) - 1);
2530 /* test what happens when picking a simple password */
2531 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, simple_pass, 0, true)) {
2536 /* set samr_SetDomainInfo level 1 with min_length 5 */
2538 struct samr_QueryDomainInfo r;
2539 struct samr_SetDomainInfo s;
2540 uint16_t len_old, len;
2541 uint32_t pwd_prop_old;
2542 int64_t min_pwd_age_old;
2547 r.in.domain_handle = domain_handle;
2550 printf("testing samr_QueryDomainInfo level 1\n");
2551 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2552 if (!NT_STATUS_IS_OK(status)) {
2556 s.in.domain_handle = domain_handle;
2558 s.in.info = r.out.info;
2560 /* remember the old min length, so we can reset it */
2561 len_old = s.in.info->info1.min_password_length;
2562 s.in.info->info1.min_password_length = len;
2563 pwd_prop_old = s.in.info->info1.password_properties;
2564 /* turn off password complexity checks for this test */
2565 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
2567 min_pwd_age_old = s.in.info->info1.min_password_age;
2568 s.in.info->info1.min_password_age = 0;
2570 printf("testing samr_SetDomainInfo level 1\n");
2571 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2572 if (!NT_STATUS_IS_OK(status)) {
2576 printf("calling test_ChangePasswordUser3 with too short password\n");
2578 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, len - 1, password, NULL, 0, true)) {
2582 s.in.info->info1.min_password_length = len_old;
2583 s.in.info->info1.password_properties = pwd_prop_old;
2584 s.in.info->info1.min_password_age = min_pwd_age_old;
2586 printf("testing samr_SetDomainInfo level 1\n");
2587 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2588 if (!NT_STATUS_IS_OK(status)) {
2596 struct samr_OpenUser r;
2597 struct samr_QueryUserInfo q;
2598 struct samr_LookupNames n;
2599 struct policy_handle user_handle;
2601 n.in.domain_handle = domain_handle;
2603 n.in.names = talloc_array(mem_ctx, struct lsa_String, 1);
2604 n.in.names[0].string = acct_name;
2606 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
2607 if (!NT_STATUS_IS_OK(status)) {
2608 printf("LookupNames failed - %s\n", nt_errstr(status));
2612 r.in.domain_handle = domain_handle;
2613 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2614 r.in.rid = n.out.rids.ids[0];
2615 r.out.user_handle = &user_handle;
2617 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
2618 if (!NT_STATUS_IS_OK(status)) {
2619 printf("OpenUser(%u) failed - %s\n", n.out.rids.ids[0], nt_errstr(status));
2623 q.in.user_handle = &user_handle;
2626 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
2627 if (!NT_STATUS_IS_OK(status)) {
2628 printf("QueryUserInfo failed - %s\n", nt_errstr(status));
2632 printf("calling test_ChangePasswordUser3 with too early password change\n");
2634 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL,
2635 q.out.info->info5.last_password_change, true)) {
2640 /* we change passwords twice - this has the effect of verifying
2641 they were changed correctly for the final call */
2642 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, true)) {
2646 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, true)) {
2653 static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2654 struct policy_handle *domain_handle,
2655 struct policy_handle *user_handle_out,
2656 struct dom_sid *domain_sid,
2657 enum torture_samr_choice which_ops)
2660 TALLOC_CTX *user_ctx;
2663 struct samr_CreateUser r;
2664 struct samr_QueryUserInfo q;
2665 struct samr_DeleteUser d;
2668 /* This call creates a 'normal' account - check that it really does */
2669 const uint32_t acct_flags = ACB_NORMAL;
2670 struct lsa_String name;
2673 struct policy_handle user_handle;
2674 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
2675 init_lsa_String(&name, TEST_ACCOUNT_NAME);
2677 r.in.domain_handle = domain_handle;
2678 r.in.account_name = &name;
2679 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2680 r.out.user_handle = &user_handle;
2683 printf("Testing CreateUser(%s)\n", r.in.account_name->string);
2685 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
2687 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
2688 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
2689 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
2692 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
2698 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
2699 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
2700 talloc_free(user_ctx);
2703 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
2705 if (!NT_STATUS_IS_OK(status)) {
2706 talloc_free(user_ctx);
2707 printf("CreateUser failed - %s\n", nt_errstr(status));
2710 q.in.user_handle = &user_handle;
2713 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
2714 if (!NT_STATUS_IS_OK(status)) {
2715 printf("QueryUserInfo level %u failed - %s\n",
2716 q.in.level, nt_errstr(status));
2719 if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
2720 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2721 q.out.info->info16.acct_flags,
2727 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
2728 acct_flags, name.string, which_ops)) {
2732 if (user_handle_out) {
2733 *user_handle_out = user_handle;
2735 printf("Testing DeleteUser (createuser test)\n");
2737 d.in.user_handle = &user_handle;
2738 d.out.user_handle = &user_handle;
2740 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
2741 if (!NT_STATUS_IS_OK(status)) {
2742 printf("DeleteUser failed - %s\n", nt_errstr(status));
2749 talloc_free(user_ctx);
2755 static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
2756 struct policy_handle *domain_handle,
2757 struct dom_sid *domain_sid,
2758 enum torture_samr_choice which_ops)
2761 struct samr_CreateUser2 r;
2762 struct samr_QueryUserInfo q;
2763 struct samr_DeleteUser d;
2764 struct policy_handle user_handle;
2766 struct lsa_String name;
2771 uint32_t acct_flags;
2772 const char *account_name;
2774 } account_types[] = {
2775 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
2776 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2777 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2778 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
2779 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2780 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2781 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
2782 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2783 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2784 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
2785 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
2786 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
2787 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2788 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2789 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
2792 for (i = 0; account_types[i].account_name; i++) {
2793 TALLOC_CTX *user_ctx;
2794 uint32_t acct_flags = account_types[i].acct_flags;
2795 uint32_t access_granted;
2796 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
2797 init_lsa_String(&name, account_types[i].account_name);
2799 r.in.domain_handle = domain_handle;
2800 r.in.account_name = &name;
2801 r.in.acct_flags = acct_flags;
2802 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2803 r.out.user_handle = &user_handle;
2804 r.out.access_granted = &access_granted;
2807 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
2809 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
2811 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
2812 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
2813 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
2816 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
2823 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
2824 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
2825 talloc_free(user_ctx);
2829 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
2832 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
2833 printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
2834 nt_errstr(status), nt_errstr(account_types[i].nt_status));
2838 if (NT_STATUS_IS_OK(status)) {
2839 q.in.user_handle = &user_handle;
2842 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
2843 if (!NT_STATUS_IS_OK(status)) {
2844 printf("QueryUserInfo level %u failed - %s\n",
2845 q.in.level, nt_errstr(status));
2848 uint32_t expected_flags = (acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
2849 if (acct_flags == ACB_NORMAL) {
2850 expected_flags |= ACB_PW_EXPIRED;
2852 if ((q.out.info->info5.acct_flags) != expected_flags) {
2853 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2854 q.out.info->info5.acct_flags,
2858 switch (acct_flags) {
2860 if (q.out.info->info5.primary_gid != DOMAIN_RID_DCS) {
2861 printf("QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n",
2862 DOMAIN_RID_DCS, q.out.info->info5.primary_gid);
2867 if (q.out.info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
2868 printf("QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
2869 DOMAIN_RID_DOMAIN_MEMBERS, q.out.info->info5.primary_gid);
2874 if (q.out.info->info5.primary_gid != DOMAIN_RID_USERS) {
2875 printf("QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n",
2876 DOMAIN_RID_USERS, q.out.info->info5.primary_gid);
2883 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
2884 acct_flags, name.string, which_ops)) {
2888 printf("Testing DeleteUser (createuser2 test)\n");
2890 d.in.user_handle = &user_handle;
2891 d.out.user_handle = &user_handle;
2893 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
2894 if (!NT_STATUS_IS_OK(status)) {
2895 printf("DeleteUser failed - %s\n", nt_errstr(status));
2899 talloc_free(user_ctx);
2905 static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2906 struct policy_handle *handle)
2909 struct samr_QueryAliasInfo r;
2910 uint16_t levels[] = {1, 2, 3};
2914 for (i=0;i<ARRAY_SIZE(levels);i++) {
2915 printf("Testing QueryAliasInfo level %u\n", levels[i]);
2917 r.in.alias_handle = handle;
2918 r.in.level = levels[i];
2920 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
2921 if (!NT_STATUS_IS_OK(status)) {
2922 printf("QueryAliasInfo level %u failed - %s\n",
2923 levels[i], nt_errstr(status));
2931 static bool test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2932 struct policy_handle *handle)
2935 struct samr_QueryGroupInfo r;
2936 uint16_t levels[] = {1, 2, 3, 4, 5};
2940 for (i=0;i<ARRAY_SIZE(levels);i++) {
2941 printf("Testing QueryGroupInfo level %u\n", levels[i]);
2943 r.in.group_handle = handle;
2944 r.in.level = levels[i];
2946 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
2947 if (!NT_STATUS_IS_OK(status)) {
2948 printf("QueryGroupInfo level %u failed - %s\n",
2949 levels[i], nt_errstr(status));
2957 static bool test_QueryGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2958 struct policy_handle *handle)
2961 struct samr_QueryGroupMember r;
2964 printf("Testing QueryGroupMember\n");
2966 r.in.group_handle = handle;
2968 status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &r);
2969 if (!NT_STATUS_IS_OK(status)) {
2970 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
2978 static bool test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2979 struct policy_handle *handle)
2982 struct samr_QueryGroupInfo r;
2983 struct samr_SetGroupInfo s;
2984 uint16_t levels[] = {1, 2, 3, 4};
2985 uint16_t set_ok[] = {0, 1, 1, 1};
2989 for (i=0;i<ARRAY_SIZE(levels);i++) {
2990 printf("Testing QueryGroupInfo level %u\n", levels[i]);
2992 r.in.group_handle = handle;
2993 r.in.level = levels[i];
2995 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
2996 if (!NT_STATUS_IS_OK(status)) {
2997 printf("QueryGroupInfo level %u failed - %s\n",
2998 levels[i], nt_errstr(status));
3002 printf("Testing SetGroupInfo level %u\n", levels[i]);
3004 s.in.group_handle = handle;
3005 s.in.level = levels[i];
3006 s.in.info = r.out.info;
3009 /* disabled this, as it changes the name only from the point of view of samr,
3010 but leaves the name from the point of view of w2k3 internals (and ldap). This means
3011 the name is still reserved, so creating the old name fails, but deleting by the old name
3013 if (s.in.level == 2) {
3014 init_lsa_String(&s.in.info->string, "NewName");
3018 if (s.in.level == 4) {
3019 init_lsa_String(&s.in.info->description, "test description");
3022 status = dcerpc_samr_SetGroupInfo(p, mem_ctx, &s);
3024 if (!NT_STATUS_IS_OK(status)) {
3025 printf("SetGroupInfo level %u failed - %s\n",
3026 r.in.level, nt_errstr(status));
3031 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
3032 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
3033 r.in.level, nt_errstr(status));
3043 static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3044 struct policy_handle *handle)
3047 struct samr_QueryUserInfo r;
3048 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
3049 11, 12, 13, 14, 16, 17, 20, 21};
3053 for (i=0;i<ARRAY_SIZE(levels);i++) {
3054 printf("Testing QueryUserInfo level %u\n", levels[i]);
3056 r.in.user_handle = handle;
3057 r.in.level = levels[i];
3059 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
3060 if (!NT_STATUS_IS_OK(status)) {
3061 printf("QueryUserInfo level %u failed - %s\n",
3062 levels[i], nt_errstr(status));
3070 static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3071 struct policy_handle *handle)
3074 struct samr_QueryUserInfo2 r;
3075 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
3076 11, 12, 13, 14, 16, 17, 20, 21};
3080 for (i=0;i<ARRAY_SIZE(levels);i++) {
3081 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
3083 r.in.user_handle = handle;
3084 r.in.level = levels[i];
3086 status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r);
3087 if (!NT_STATUS_IS_OK(status)) {
3088 printf("QueryUserInfo2 level %u failed - %s\n",
3089 levels[i], nt_errstr(status));
3097 static bool test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3098 struct policy_handle *handle, uint32_t rid)
3101 struct samr_OpenUser r;
3102 struct policy_handle user_handle;
3105 printf("Testing OpenUser(%u)\n", rid);
3107 r.in.domain_handle = handle;
3108 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3110 r.out.user_handle = &user_handle;
3112 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3113 if (!NT_STATUS_IS_OK(status)) {
3114 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
3118 if (!test_QuerySecurity(p, mem_ctx, &user_handle)) {
3122 if (!test_QueryUserInfo(p, mem_ctx, &user_handle)) {
3126 if (!test_QueryUserInfo2(p, mem_ctx, &user_handle)) {
3130 if (!test_GetUserPwInfo(p, mem_ctx, &user_handle)) {
3134 if (!test_GetGroupsForUser(p,mem_ctx, &user_handle)) {
3138 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
3145 static bool test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3146 struct policy_handle *handle, uint32_t rid)
3149 struct samr_OpenGroup r;
3150 struct policy_handle group_handle;
3153 printf("Testing OpenGroup(%u)\n", rid);
3155 r.in.domain_handle = handle;
3156 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3158 r.out.group_handle = &group_handle;
3160 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
3161 if (!NT_STATUS_IS_OK(status)) {
3162 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
3166 if (!test_QuerySecurity(p, mem_ctx, &group_handle)) {
3170 if (!test_QueryGroupInfo(p, mem_ctx, &group_handle)) {
3174 if (!test_QueryGroupMember(p, mem_ctx, &group_handle)) {
3178 if (!test_samr_handle_Close(p, mem_ctx, &group_handle)) {
3185 static bool test_OpenAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
3186 struct policy_handle *handle, uint32_t rid)
3189 struct samr_OpenAlias r;
3190 struct policy_handle alias_handle;
3193 torture_comment(tctx, "Testing OpenAlias(%u)\n", rid);
3195 r.in.domain_handle = handle;
3196 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3198 r.out.alias_handle = &alias_handle;
3200 status = dcerpc_samr_OpenAlias(p, tctx, &r);
3201 if (!NT_STATUS_IS_OK(status)) {
3202 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
3206 if (!test_QuerySecurity(p, tctx, &alias_handle)) {
3210 if (!test_QueryAliasInfo(p, tctx, &alias_handle)) {
3214 if (!test_GetMembersInAlias(p, tctx, &alias_handle)) {
3218 if (!test_samr_handle_Close(p, tctx, &alias_handle)) {
3225 static bool check_mask(struct dcerpc_pipe *p, struct torture_context *tctx,
3226 struct policy_handle *handle, uint32_t rid,
3227 uint32_t acct_flag_mask)
3230 struct samr_OpenUser r;
3231 struct samr_QueryUserInfo q;
3232 struct policy_handle user_handle;
3235 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
3237 r.in.domain_handle = handle;
3238 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3240 r.out.user_handle = &user_handle;
3242 status = dcerpc_samr_OpenUser(p, tctx, &r);
3243 if (!NT_STATUS_IS_OK(status)) {
3244 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
3248 q.in.user_handle = &user_handle;
3251 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
3252 if (!NT_STATUS_IS_OK(status)) {
3253 printf("QueryUserInfo level 16 failed - %s\n",
3257 if ((acct_flag_mask & q.out.info->info16.acct_flags) == 0) {
3258 printf("Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
3259 acct_flag_mask, q.out.info->info16.acct_flags, rid);
3264 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
3271 static bool test_EnumDomainUsers(struct dcerpc_pipe *p, struct torture_context *tctx,
3272 struct policy_handle *handle)
3274 NTSTATUS status = STATUS_MORE_ENTRIES;
3275 struct samr_EnumDomainUsers r;
3276 uint32_t mask, resume_handle=0;
3279 struct samr_LookupNames n;
3280 struct samr_LookupRids lr ;
3281 struct lsa_Strings names;
3282 struct samr_Ids types;
3284 uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
3285 ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
3286 ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
3289 printf("Testing EnumDomainUsers\n");
3291 for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
3292 r.in.domain_handle = handle;
3293 r.in.resume_handle = &resume_handle;
3294 r.in.acct_flags = mask = masks[mask_idx];
3295 r.in.max_size = (uint32_t)-1;
3296 r.out.resume_handle = &resume_handle;
3298 status = dcerpc_samr_EnumDomainUsers(p, tctx, &r);
3299 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
3300 !NT_STATUS_IS_OK(status)) {
3301 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
3305 torture_assert(tctx, r.out.sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
3307 if (r.out.sam->count == 0) {
3311 for (i=0;i<r.out.sam->count;i++) {
3313 if (!check_mask(p, tctx, handle, r.out.sam->entries[i].idx, mask)) {
3316 } else if (!test_OpenUser(p, tctx, handle, r.out.sam->entries[i].idx)) {
3322 printf("Testing LookupNames\n");
3323 n.in.domain_handle = handle;
3324 n.in.num_names = r.out.sam->count;
3325 n.in.names = talloc_array(tctx, struct lsa_String, r.out.sam->count);
3326 for (i=0;i<r.out.sam->count;i++) {
3327 n.in.names[i].string = r.out.sam->entries[i].name.string;
3329 status = dcerpc_samr_LookupNames(p, tctx, &n);
3330 if (!NT_STATUS_IS_OK(status)) {
3331 printf("LookupNames failed - %s\n", nt_errstr(status));
3336 printf("Testing LookupRids\n");
3337 lr.in.domain_handle = handle;
3338 lr.in.num_rids = r.out.sam->count;
3339 lr.in.rids = talloc_array(tctx, uint32_t, r.out.sam->count);
3340 lr.out.names = &names;
3341 lr.out.types = &types;
3342 for (i=0;i<r.out.sam->count;i++) {
3343 lr.in.rids[i] = r.out.sam->entries[i].idx;
3345 status = dcerpc_samr_LookupRids(p, tctx, &lr);
3346 torture_assert_ntstatus_ok(tctx, status, "LookupRids");
3352 try blasting the server with a bunch of sync requests
3354 static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, struct torture_context *tctx,
3355 struct policy_handle *handle)
3358 struct samr_EnumDomainUsers r;
3359 uint32_t resume_handle=0;
3361 #define ASYNC_COUNT 100
3362 struct rpc_request *req[ASYNC_COUNT];
3364 if (!torture_setting_bool(tctx, "dangerous", false)) {
3365 torture_skip(tctx, "samr async test disabled - enable dangerous tests to use\n");
3368 torture_comment(tctx, "Testing EnumDomainUsers_async\n");
3370 r.in.domain_handle = handle;
3371 r.in.resume_handle = &resume_handle;
3372 r.in.acct_flags = 0;
3373 r.in.max_size = (uint32_t)-1;
3374 r.out.resume_handle = &resume_handle;
3376 for (i=0;i<ASYNC_COUNT;i++) {
3377 req[i] = dcerpc_samr_EnumDomainUsers_send(p, tctx, &r);
3380 for (i=0;i<ASYNC_COUNT;i++) {
3381 status = dcerpc_ndr_request_recv(req[i]);
3382 if (!NT_STATUS_IS_OK(status)) {
3383 printf("EnumDomainUsers[%d] failed - %s\n",
3384 i, nt_errstr(status));
3389 torture_comment(tctx, "%d async requests OK\n", i);
3394 static bool test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3395 struct policy_handle *handle)
3398 struct samr_EnumDomainGroups r;
3399 uint32_t resume_handle=0;
3403 printf("Testing EnumDomainGroups\n");
3405 r.in.domain_handle = handle;
3406 r.in.resume_handle = &resume_handle;
3407 r.in.max_size = (uint32_t)-1;
3408 r.out.resume_handle = &resume_handle;
3410 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
3411 if (!NT_STATUS_IS_OK(status)) {
3412 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
3420 for (i=0;i<r.out.sam->count;i++) {
3421 if (!test_OpenGroup(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
3429 static bool test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3430 struct policy_handle *handle)
3433 struct samr_EnumDomainAliases r;
3434 uint32_t resume_handle=0;
3438 printf("Testing EnumDomainAliases\n");
3440 r.in.domain_handle = handle;
3441 r.in.resume_handle = &resume_handle;
3442 r.in.acct_flags = (uint32_t)-1;
3443 r.out.resume_handle = &resume_handle;
3445 status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
3446 if (!NT_STATUS_IS_OK(status)) {
3447 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
3455 for (i=0;i<r.out.sam->count;i++) {
3456 if (!test_OpenAlias(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
3464 static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3465 struct policy_handle *handle)
3468 struct samr_GetDisplayEnumerationIndex r;
3470 uint16_t levels[] = {1, 2, 3, 4, 5};
3471 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
3472 struct lsa_String name;
3476 for (i=0;i<ARRAY_SIZE(levels);i++) {
3477 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
3479 init_lsa_String(&name, TEST_ACCOUNT_NAME);
3481 r.in.domain_handle = handle;
3482 r.in.level = levels[i];
3486 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
3489 !NT_STATUS_IS_OK(status) &&
3490 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3491 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
3492 levels[i], nt_errstr(status));
3496 init_lsa_String(&name, "zzzzzzzz");
3498 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
3500 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3501 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
3502 levels[i], nt_errstr(status));
3510 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3511 struct policy_handle *handle)
3514 struct samr_GetDisplayEnumerationIndex2 r;
3516 uint16_t levels[] = {1, 2, 3, 4, 5};
3517 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
3518 struct lsa_String name;
3522 for (i=0;i<ARRAY_SIZE(levels);i++) {
3523 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
3525 init_lsa_String(&name, TEST_ACCOUNT_NAME);
3527 r.in.domain_handle = handle;
3528 r.in.level = levels[i];
3532 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
3534 !NT_STATUS_IS_OK(status) &&
3535 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3536 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
3537 levels[i], nt_errstr(status));
3541 init_lsa_String(&name, "zzzzzzzz");
3543 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
3544 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3545 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
3546 levels[i], nt_errstr(status));
3554 #define STRING_EQUAL_QUERY(s1, s2, user) \
3555 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
3556 /* odd, but valid */ \
3557 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
3558 printf("%s mismatch for %s: %s != %s (%s)\n", \
3559 #s1, user.string, s1.string, s2.string, __location__); \
3562 #define INT_EQUAL_QUERY(s1, s2, user) \
3564 printf("%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
3565 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
3569 static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3570 struct samr_QueryDisplayInfo *querydisplayinfo,
3571 bool *seen_testuser)
3573 struct samr_OpenUser r;
3574 struct samr_QueryUserInfo q;
3575 struct policy_handle user_handle;
3578 r.in.domain_handle = querydisplayinfo->in.domain_handle;
3579 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3580 for (i = 0; ; i++) {
3581 switch (querydisplayinfo->in.level) {
3583 if (i >= querydisplayinfo->out.info.info1.count) {
3586 r.in.rid = querydisplayinfo->out.info.info1.entries[i].rid;
3589 if (i >= querydisplayinfo->out.info.info2.count) {
3592 r.in.rid = querydisplayinfo->out.info.info2.entries[i].rid;
3598 /* Not interested in validating just the account name */
3602 r.out.user_handle = &user_handle;
3604 switch (querydisplayinfo->in.level) {
3607 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3608 if (!NT_STATUS_IS_OK(status)) {
3609 printf("OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(status));
3614 q.in.user_handle = &user_handle;
3616 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
3617 if (!NT_STATUS_IS_OK(status)) {
3618 printf("QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(status));
3622 switch (querydisplayinfo->in.level) {
3624 if (seen_testuser && strcmp(q.out.info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
3625 *seen_testuser = true;
3627 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].full_name,
3628 q.out.info->info21.full_name, q.out.info->info21.account_name);
3629 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].account_name,
3630 q.out.info->info21.account_name, q.out.info->info21.account_name);
3631 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].description,
3632 q.out.info->info21.description, q.out.info->info21.account_name);
3633 INT_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].rid,
3634 q.out.info->info21.rid, q.out.info->info21.account_name);
3635 INT_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].acct_flags,
3636 q.out.info->info21.acct_flags, q.out.info->info21.account_name);
3640 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].account_name,
3641 q.out.info->info21.account_name, q.out.info->info21.account_name);
3642 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].description,
3643 q.out.info->info21.description, q.out.info->info21.account_name);
3644 INT_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].rid,
3645 q.out.info->info21.rid, q.out.info->info21.account_name);
3646 INT_EQUAL_QUERY((querydisplayinfo->out.info.info2.entries[i].acct_flags & ~ACB_NORMAL),
3647 q.out.info->info21.acct_flags, q.out.info->info21.account_name);
3649 if (!(querydisplayinfo->out.info.info2.entries[i].acct_flags & ACB_NORMAL)) {
3650 printf("Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
3651 q.out.info->info21.account_name.string);
3654 if (!(q.out.info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
3655 printf("Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
3656 q.out.info->info21.account_name.string,
3657 querydisplayinfo->out.info.info2.entries[i].acct_flags,
3658 q.out.info->info21.acct_flags);
3665 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
3672 static bool test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3673 struct policy_handle *handle)
3676 struct samr_QueryDisplayInfo r;
3677 struct samr_QueryDomainInfo dom_info;
3679 uint16_t levels[] = {1, 2, 3, 4, 5};
3681 bool seen_testuser = false;
3683 for (i=0;i<ARRAY_SIZE(levels);i++) {
3684 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
3687 status = STATUS_MORE_ENTRIES;
3688 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
3689 r.in.domain_handle = handle;
3690 r.in.level = levels[i];
3691 r.in.max_entries = 2;
3692 r.in.buf_size = (uint32_t)-1;
3694 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
3695 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(status)) {
3696 printf("QueryDisplayInfo level %u failed - %s\n",
3697 levels[i], nt_errstr(status));
3700 switch (r.in.level) {
3702 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, &seen_testuser)) {
3705 r.in.start_idx += r.out.info.info1.count;
3708 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, NULL)) {
3711 r.in.start_idx += r.out.info.info2.count;
3714 r.in.start_idx += r.out.info.info3.count;
3717 r.in.start_idx += r.out.info.info4.count;
3720 r.in.start_idx += r.out.info.info5.count;
3724 dom_info.in.domain_handle = handle;
3725 dom_info.in.level = 2;
3726 /* Check number of users returned is correct */
3727 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &dom_info);
3728 if (!NT_STATUS_IS_OK(status)) {
3729 printf("QueryDomainInfo level %u failed - %s\n",
3730 r.in.level, nt_errstr(status));
3734 switch (r.in.level) {
3737 if (dom_info.out.info->general.num_users < r.in.start_idx) {
3738 printf("QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
3739 r.in.start_idx, dom_info.out.info->general.num_groups,
3740 dom_info.out.info->general.domain_name.string);
3743 if (!seen_testuser) {
3744 struct policy_handle user_handle;
3745 if (NT_STATUS_IS_OK(test_OpenUser_byname(p, mem_ctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
3746 printf("Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
3747 dom_info.out.info->general.domain_name.string);
3749 test_samr_handle_Close(p, mem_ctx, &user_handle);
3755 if (dom_info.out.info->general.num_groups != r.in.start_idx) {
3756 printf("QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
3757 r.in.start_idx, dom_info.out.info->general.num_groups,
3758 dom_info.out.info->general.domain_name.string);
3770 static bool test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3771 struct policy_handle *handle)
3774 struct samr_QueryDisplayInfo2 r;
3776 uint16_t levels[] = {1, 2, 3, 4, 5};
3779 for (i=0;i<ARRAY_SIZE(levels);i++) {
3780 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
3782 r.in.domain_handle = handle;
3783 r.in.level = levels[i];
3785 r.in.max_entries = 1000;
3786 r.in.buf_size = (uint32_t)-1;
3788 status = dcerpc_samr_QueryDisplayInfo2(p, mem_ctx, &r);
3789 if (!NT_STATUS_IS_OK(status)) {
3790 printf("QueryDisplayInfo2 level %u failed - %s\n",
3791 levels[i], nt_errstr(status));
3799 static bool test_QueryDisplayInfo3(struct dcerpc_pipe *p, struct torture_context *tctx,
3800 struct policy_handle *handle)
3803 struct samr_QueryDisplayInfo3 r;
3805 uint16_t levels[] = {1, 2, 3, 4, 5};
3808 for (i=0;i<ARRAY_SIZE(levels);i++) {
3809 torture_comment(tctx, "Testing QueryDisplayInfo3 level %u\n", levels[i]);
3811 r.in.domain_handle = handle;
3812 r.in.level = levels[i];
3814 r.in.max_entries = 1000;
3815 r.in.buf_size = (uint32_t)-1;
3817 status = dcerpc_samr_QueryDisplayInfo3(p, tctx, &r);
3818 if (!NT_STATUS_IS_OK(status)) {
3819 printf("QueryDisplayInfo3 level %u failed - %s\n",
3820 levels[i], nt_errstr(status));
3829 static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3830 struct policy_handle *handle)
3833 struct samr_QueryDisplayInfo r;
3836 printf("Testing QueryDisplayInfo continuation\n");
3838 r.in.domain_handle = handle;
3841 r.in.max_entries = 1;
3842 r.in.buf_size = (uint32_t)-1;
3845 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
3846 if (NT_STATUS_IS_OK(status) && r.out.returned_size != 0) {
3847 if (r.out.info.info1.entries[0].idx != r.in.start_idx + 1) {
3848 printf("expected idx %d but got %d\n",
3850 r.out.info.info1.entries[0].idx);
3854 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
3855 !NT_STATUS_IS_OK(status)) {
3856 printf("QueryDisplayInfo level %u failed - %s\n",
3857 r.in.level, nt_errstr(status));
3862 } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
3863 NT_STATUS_IS_OK(status)) &&
3864 r.out.returned_size != 0);
3869 static bool test_QueryDomainInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
3870 struct policy_handle *handle)
3873 struct samr_QueryDomainInfo r;
3874 struct samr_SetDomainInfo s;
3875 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
3876 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
3879 const char *domain_comment = talloc_asprintf(tctx,
3880 "Tortured by Samba4 RPC-SAMR: %s",
3881 timestring(tctx, time(NULL)));
3883 s.in.domain_handle = handle;
3885 s.in.info = talloc(tctx, union samr_DomainInfo);
3887 s.in.info->oem.oem_information.string = domain_comment;
3888 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
3889 if (!NT_STATUS_IS_OK(status)) {
3890 printf("SetDomainInfo level %u (set comment) failed - %s\n",
3891 r.in.level, nt_errstr(status));
3895 for (i=0;i<ARRAY_SIZE(levels);i++) {
3896 torture_comment(tctx, "Testing QueryDomainInfo level %u\n", levels[i]);
3898 r.in.domain_handle = handle;
3899 r.in.level = levels[i];
3901 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
3902 if (!NT_STATUS_IS_OK(status)) {
3903 printf("QueryDomainInfo level %u failed - %s\n",
3904 r.in.level, nt_errstr(status));
3909 switch (levels[i]) {
3911 if (strcmp(r.out.info->general.oem_information.string, domain_comment) != 0) {
3912 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
3913 levels[i], r.out.info->general.oem_information.string, domain_comment);
3916 if (!r.out.info->general.primary.string) {
3917 printf("QueryDomainInfo level %u returned no PDC name\n",
3920 } else if (r.out.info->general.role == SAMR_ROLE_DOMAIN_PDC) {
3921 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), r.out.info->general.primary.string) != 0) {
3922 printf("QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
3923 levels[i], r.out.info->general.primary.string, dcerpc_server_name(p));
3928 if (strcmp(r.out.info->oem.oem_information.string, domain_comment) != 0) {
3929 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
3930 levels[i], r.out.info->oem.oem_information.string, domain_comment);
3935 if (!r.out.info->info6.primary.string) {
3936 printf("QueryDomainInfo level %u returned no PDC name\n",
3942 if (strcmp(r.out.info->general2.general.oem_information.string, domain_comment) != 0) {
3943 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
3944 levels[i], r.out.info->general2.general.oem_information.string, domain_comment);
3950 torture_comment(tctx, "Testing SetDomainInfo level %u\n", levels[i]);
3952 s.in.domain_handle = handle;
3953 s.in.level = levels[i];
3954 s.in.info = r.out.info;
3956 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
3958 if (!NT_STATUS_IS_OK(status)) {
3959 printf("SetDomainInfo level %u failed - %s\n",
3960 r.in.level, nt_errstr(status));
3965 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
3966 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
3967 r.in.level, nt_errstr(status));
3973 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
3974 if (!NT_STATUS_IS_OK(status)) {
3975 printf("QueryDomainInfo level %u failed - %s\n",
3976 r.in.level, nt_errstr(status));
3986 static bool test_QueryDomainInfo2(struct dcerpc_pipe *p, struct torture_context *tctx,
3987 struct policy_handle *handle)
3990 struct samr_QueryDomainInfo2 r;
3991 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
3995 for (i=0;i<ARRAY_SIZE(levels);i++) {
3996 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
3998 r.in.domain_handle = handle;
3999 r.in.level = levels[i];
4001 status = dcerpc_samr_QueryDomainInfo2(p, tctx, &r);
4002 if (!NT_STATUS_IS_OK(status)) {
4003 printf("QueryDomainInfo2 level %u failed - %s\n",
4004 r.in.level, nt_errstr(status));
4013 /* Test whether querydispinfo level 5 and enumdomgroups return the same
4014 set of group names. */
4015 static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx,
4016 struct policy_handle *handle)
4018 struct samr_EnumDomainGroups q1;
4019 struct samr_QueryDisplayInfo q2;
4021 uint32_t resume_handle=0;
4026 const char **names = NULL;
4028 torture_comment(tctx, "Testing coherency of querydispinfo vs enumdomgroups\n");
4030 q1.in.domain_handle = handle;
4031 q1.in.resume_handle = &resume_handle;
4033 q1.out.resume_handle = &resume_handle;
4035 status = STATUS_MORE_ENTRIES;
4036 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
4037 status = dcerpc_samr_EnumDomainGroups(p, tctx, &q1);
4039 if (!NT_STATUS_IS_OK(status) &&
4040 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
4043 for (i=0; i<q1.out.num_entries; i++) {
4044 add_string_to_array(tctx,
4045 q1.out.sam->entries[i].name.string,
4046 &names, &num_names);
4050 torture_assert_ntstatus_ok(tctx, status, "EnumDomainGroups");
4052 torture_assert(tctx, q1.out.sam, "EnumDomainGroups failed to return q1.out.sam");
4054 q2.in.domain_handle = handle;
4056 q2.in.start_idx = 0;
4057 q2.in.max_entries = 5;
4058 q2.in.buf_size = (uint32_t)-1;
4060 status = STATUS_MORE_ENTRIES;
4061 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
4062 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &q2);
4064 if (!NT_STATUS_IS_OK(status) &&
4065 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
4068 for (i=0; i<q2.out.info.info5.count; i++) {
4070 const char *name = q2.out.info.info5.entries[i].account_name.string;
4072 for (j=0; j<num_names; j++) {
4073 if (names[j] == NULL)
4075 if (strequal(names[j], name)) {
4083 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
4088 q2.in.start_idx += q2.out.info.info5.count;
4091 if (!NT_STATUS_IS_OK(status)) {
4092 printf("QueryDisplayInfo level 5 failed - %s\n",
4097 for (i=0; i<num_names; i++) {
4098 if (names[i] != NULL) {
4099 printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
4108 static bool test_DeleteDomainGroup(struct dcerpc_pipe *p, struct torture_context *tctx,
4109 struct policy_handle *group_handle)
4111 struct samr_DeleteDomainGroup d;
4114 torture_comment(tctx, "Testing DeleteDomainGroup\n");
4116 d.in.group_handle = group_handle;
4117 d.out.group_handle = group_handle;
4119 status = dcerpc_samr_DeleteDomainGroup(p, tctx, &d);
4120 torture_assert_ntstatus_ok(tctx, status, "DeleteDomainGroup");
4125 static bool test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
4126 struct policy_handle *domain_handle)
4128 struct samr_TestPrivateFunctionsDomain r;
4132 torture_comment(tctx, "Testing TestPrivateFunctionsDomain\n");
4134 r.in.domain_handle = domain_handle;
4136 status = dcerpc_samr_TestPrivateFunctionsDomain(p, tctx, &r);
4137 torture_assert_ntstatus_equal(tctx, NT_STATUS_NOT_IMPLEMENTED, status, "TestPrivateFunctionsDomain");
4142 static bool test_RidToSid(struct dcerpc_pipe *p, struct torture_context *tctx,
4143 struct dom_sid *domain_sid,
4144 struct policy_handle *domain_handle)
4146 struct samr_RidToSid r;
4149 struct dom_sid *calc_sid;
4150 int rids[] = { 0, 42, 512, 10200 };
4153 for (i=0;i<ARRAY_SIZE(rids);i++) {
4154 torture_comment(tctx, "Testing RidToSid\n");
4156 calc_sid = dom_sid_dup(tctx, domain_sid);
4157 r.in.domain_handle = domain_handle;
4160 status = dcerpc_samr_RidToSid(p, tctx, &r);
4161 if (!NT_STATUS_IS_OK(status)) {
4162 printf("RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
4165 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
4167 if (!dom_sid_equal(calc_sid, r.out.sid)) {
4168 printf("RidToSid for %d failed - got %s, expected %s\n", rids[i],
4169 dom_sid_string(tctx, r.out.sid),
4170 dom_sid_string(tctx, calc_sid));
4179 static bool test_GetBootKeyInformation(struct dcerpc_pipe *p, struct torture_context *tctx,
4180 struct policy_handle *domain_handle)
4182 struct samr_GetBootKeyInformation r;
4186 torture_comment(tctx, "Testing GetBootKeyInformation\n");
4188 r.in.domain_handle = domain_handle;
4190 status = dcerpc_samr_GetBootKeyInformation(p, tctx, &r);
4191 if (!NT_STATUS_IS_OK(status)) {
4192 /* w2k3 seems to fail this sometimes and pass it sometimes */
4193 torture_comment(tctx, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
4199 static bool test_AddGroupMember(struct dcerpc_pipe *p, struct torture_context *tctx,
4200 struct policy_handle *domain_handle,
4201 struct policy_handle *group_handle)
4204 struct samr_AddGroupMember r;
4205 struct samr_DeleteGroupMember d;
4206 struct samr_QueryGroupMember q;
4207 struct samr_SetMemberAttributesOfGroup s;
4210 status = test_LookupName(p, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
4211 torture_assert_ntstatus_ok(tctx, status, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME);
4213 r.in.group_handle = group_handle;
4215 r.in.flags = 0; /* ??? */
4217 torture_comment(tctx, "Testing AddGroupMember and DeleteGroupMember\n");
4219 d.in.group_handle = group_handle;
4222 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
4223 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_NOT_IN_GROUP, status, "DeleteGroupMember");
4225 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4226 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
4228 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4229 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_IN_GROUP, status, "AddGroupMember");
4231 if (torture_setting_bool(tctx, "samba4", false)) {
4232 torture_comment(tctx, "skipping SetMemberAttributesOfGroup test against Samba4\n");
4234 /* this one is quite strange. I am using random inputs in the
4235 hope of triggering an error that might give us a clue */
4237 s.in.group_handle = group_handle;
4238 s.in.unknown1 = random();
4239 s.in.unknown2 = random();
4241 status = dcerpc_samr_SetMemberAttributesOfGroup(p, tctx, &s);
4242 torture_assert_ntstatus_ok(tctx, status, "SetMemberAttributesOfGroup");
4245 q.in.group_handle = group_handle;
4247 status = dcerpc_samr_QueryGroupMember(p, tctx, &q);
4248 torture_assert_ntstatus_ok(tctx, status, "QueryGroupMember");
4250 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
4251 torture_assert_ntstatus_ok(tctx, status, "DeleteGroupMember");
4253 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4254 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
4260 static bool test_CreateDomainGroup(struct dcerpc_pipe *p,
4261 struct torture_context *tctx,
4262 struct policy_handle *domain_handle,
4263 struct policy_handle *group_handle,
4264 struct dom_sid *domain_sid)
4267 struct samr_CreateDomainGroup r;
4269 struct lsa_String name;
4272 init_lsa_String(&name, TEST_GROUPNAME);
4274 r.in.domain_handle = domain_handle;
4276 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4277 r.out.group_handle = group_handle;
4280 printf("Testing CreateDomainGroup(%s)\n", r.in.name->string);
4282 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
4284 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
4285 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
4286 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.name->string);
4289 printf("Server should have refused create of '%s', got %s instead\n", r.in.name->string,
4295 if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS)) {
4296 if (!test_DeleteGroup_byname(p, tctx, domain_handle, r.in.name->string)) {
4297 printf("CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
4301 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
4303 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
4304 if (!test_DeleteUser_byname(p, tctx, domain_handle, r.in.name->string)) {
4306 printf("CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
4310 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
4312 torture_assert_ntstatus_ok(tctx, status, "CreateDomainGroup");
4314 if (!test_AddGroupMember(p, tctx, domain_handle, group_handle)) {
4315 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
4319 if (!test_SetGroupInfo(p, tctx, group_handle)) {
4328 its not totally clear what this does. It seems to accept any sid you like.
4330 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p,
4331 struct torture_context *tctx,
4332 struct policy_handle *domain_handle)
4335 struct samr_RemoveMemberFromForeignDomain r;
4337 r.in.domain_handle = domain_handle;
4338 r.in.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-12-34-56-78");
4340 status = dcerpc_samr_RemoveMemberFromForeignDomain(p, tctx, &r);
4341 torture_assert_ntstatus_ok(tctx, status, "RemoveMemberFromForeignDomain");
4348 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
4349 struct policy_handle *handle);
4351 static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
4352 struct policy_handle *handle, struct dom_sid *sid,
4353 enum torture_samr_choice which_ops)
4356 struct samr_OpenDomain r;
4357 struct policy_handle domain_handle;
4358 struct policy_handle alias_handle;
4359 struct policy_handle user_handle;
4360 struct policy_handle group_handle;
4363 ZERO_STRUCT(alias_handle);
4364 ZERO_STRUCT(user_handle);
4365 ZERO_STRUCT(group_handle);
4366 ZERO_STRUCT(domain_handle);
4368 torture_comment(tctx, "Testing OpenDomain of %s\n", dom_sid_string(tctx, sid));
4370 r.in.connect_handle = handle;
4371 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4373 r.out.domain_handle = &domain_handle;
4375 status = dcerpc_samr_OpenDomain(p, tctx, &r);
4376 torture_assert_ntstatus_ok(tctx, status, "OpenDomain");
4378 /* run the domain tests with the main handle closed - this tests
4379 the servers reference counting */
4380 ret &= test_samr_handle_Close(p, tctx, handle);
4382 switch (which_ops) {
4383 case TORTURE_SAMR_USER_ATTRIBUTES:
4384 case TORTURE_SAMR_PASSWORDS:
4385 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops);
4386 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops);
4387 /* This test needs 'complex' users to validate */
4388 ret &= test_QueryDisplayInfo(p, tctx, &domain_handle);
4390 printf("Testing PASSWORDS or ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
4393 case TORTURE_SAMR_OTHER:
4394 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops);
4396 printf("Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid));
4398 ret &= test_QuerySecurity(p, tctx, &domain_handle);
4399 ret &= test_RemoveMemberFromForeignDomain(p, tctx, &domain_handle);
4400 ret &= test_CreateAlias(p, tctx, &domain_handle, &alias_handle, sid);
4401 ret &= test_CreateDomainGroup(p, tctx, &domain_handle, &group_handle, sid);
4402 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
4403 ret &= test_QueryDomainInfo2(p, tctx, &domain_handle);
4404 ret &= test_EnumDomainUsers(p, tctx, &domain_handle);
4405 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
4406 ret &= test_EnumDomainGroups(p, tctx, &domain_handle);
4407 ret &= test_EnumDomainAliases(p, tctx, &domain_handle);
4408 ret &= test_QueryDisplayInfo2(p, tctx, &domain_handle);
4409 ret &= test_QueryDisplayInfo3(p, tctx, &domain_handle);
4410 ret &= test_QueryDisplayInfo_continue(p, tctx, &domain_handle);
4412 if (torture_setting_bool(tctx, "samba4", false)) {
4413 torture_comment(tctx, "skipping GetDisplayEnumerationIndex test against Samba4\n");
4415 ret &= test_GetDisplayEnumerationIndex(p, tctx, &domain_handle);
4416 ret &= test_GetDisplayEnumerationIndex2(p, tctx, &domain_handle);
4418 ret &= test_GroupList(p, tctx, &domain_handle);
4419 ret &= test_TestPrivateFunctionsDomain(p, tctx, &domain_handle);
4420 ret &= test_RidToSid(p, tctx, sid, &domain_handle);
4421 ret &= test_GetBootKeyInformation(p, tctx, &domain_handle);
4423 torture_comment(tctx, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx, sid));
4428 if (!policy_handle_empty(&user_handle) &&
4429 !test_DeleteUser(p, tctx, &user_handle)) {
4433 if (!policy_handle_empty(&alias_handle) &&
4434 !test_DeleteAlias(p, tctx, &alias_handle)) {
4438 if (!policy_handle_empty(&group_handle) &&
4439 !test_DeleteDomainGroup(p, tctx, &group_handle)) {
4443 ret &= test_samr_handle_Close(p, tctx, &domain_handle);
4445 /* reconnect the main handle */
4446 ret &= test_Connect(p, tctx, handle);
4449 printf("Testing domain %s failed!\n", dom_sid_string(tctx, sid));
4455 static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
4456 struct policy_handle *handle, const char *domain,
4457 enum torture_samr_choice which_ops)
4460 struct samr_LookupDomain r;
4461 struct lsa_String n1;
4462 struct lsa_String n2;
4465 torture_comment(tctx, "Testing LookupDomain(%s)\n", domain);
4467 /* check for correct error codes */
4468 r.in.connect_handle = handle;
4469 r.in.domain_name = &n2;
4472 status = dcerpc_samr_LookupDomain(p, tctx, &r);
4473 torture_assert_ntstatus_equal(tctx, NT_STATUS_INVALID_PARAMETER, status, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
4475 init_lsa_String(&n2, "xxNODOMAINxx");
4477 status = dcerpc_samr_LookupDomain(p, tctx, &r);
4478 torture_assert_ntstatus_equal(tctx, NT_STATUS_NO_SUCH_DOMAIN, status, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
4480 r.in.connect_handle = handle;
4482 init_lsa_String(&n1, domain);
4483 r.in.domain_name = &n1;
4485 status = dcerpc_samr_LookupDomain(p, tctx, &r);
4486 torture_assert_ntstatus_ok(tctx, status, "LookupDomain");
4488 if (!test_GetDomPwInfo(p, tctx, &n1)) {
4492 if (!test_OpenDomain(p, tctx, handle, r.out.sid, which_ops)) {
4500 static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
4501 struct policy_handle *handle, enum torture_samr_choice which_ops)
4504 struct samr_EnumDomains r;
4505 uint32_t resume_handle = 0;
4509 r.in.connect_handle = handle;
4510 r.in.resume_handle = &resume_handle;
4511 r.in.buf_size = (uint32_t)-1;
4512 r.out.resume_handle = &resume_handle;
4514 status = dcerpc_samr_EnumDomains(p, tctx, &r);
4515 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
4521 for (i=0;i<r.out.sam->count;i++) {
4522 if (!test_LookupDomain(p, tctx, handle,
4523 r.out.sam->entries[i].name.string, which_ops)) {
4528 status = dcerpc_samr_EnumDomains(p, tctx, &r);
4529 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
4535 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
4536 struct policy_handle *handle)
4539 struct samr_Connect r;
4540 struct samr_Connect2 r2;
4541 struct samr_Connect3 r3;
4542 struct samr_Connect4 r4;
4543 struct samr_Connect5 r5;
4544 union samr_ConnectInfo info;
4545 struct policy_handle h;
4546 bool ret = true, got_handle = false;
4548 torture_comment(tctx, "testing samr_Connect\n");
4550 r.in.system_name = 0;
4551 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4552 r.out.connect_handle = &h;
4554 status = dcerpc_samr_Connect(p, tctx, &r);
4555 if (!NT_STATUS_IS_OK(status)) {
4556 torture_comment(tctx, "Connect failed - %s\n", nt_errstr(status));
4563 torture_comment(tctx, "testing samr_Connect2\n");
4565 r2.in.system_name = NULL;
4566 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4567 r2.out.connect_handle = &h;
4569 status = dcerpc_samr_Connect2(p, tctx, &r2);
4570 if (!NT_STATUS_IS_OK(status)) {
4571 torture_comment(tctx, "Connect2 failed - %s\n", nt_errstr(status));
4575 test_samr_handle_Close(p, tctx, handle);
4581 torture_comment(tctx, "testing samr_Connect3\n");
4583 r3.in.system_name = NULL;
4585 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4586 r3.out.connect_handle = &h;
4588 status = dcerpc_samr_Connect3(p, tctx, &r3);
4589 if (!NT_STATUS_IS_OK(status)) {
4590 printf("Connect3 failed - %s\n", nt_errstr(status));
4594 test_samr_handle_Close(p, tctx, handle);
4600 torture_comment(tctx, "testing samr_Connect4\n");
4602 r4.in.system_name = "";
4603 r4.in.client_version = 0;
4604 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4605 r4.out.connect_handle = &h;
4607 status = dcerpc_samr_Connect4(p, tctx, &r4);
4608 if (!NT_STATUS_IS_OK(status)) {
4609 printf("Connect4 failed - %s\n", nt_errstr(status));
4613 test_samr_handle_Close(p, tctx, handle);
4619 torture_comment(tctx, "testing samr_Connect5\n");
4621 info.info1.client_version = 0;
4622 info.info1.unknown2 = 0;
4624 r5.in.system_name = "";
4625 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4628 r5.out.info = &info;
4629 r5.out.connect_handle = &h;
4631 status = dcerpc_samr_Connect5(p, tctx, &r5);
4632 if (!NT_STATUS_IS_OK(status)) {
4633 printf("Connect5 failed - %s\n", nt_errstr(status));
4637 test_samr_handle_Close(p, tctx, handle);
4647 bool torture_rpc_samr(struct torture_context *torture)
4650 struct dcerpc_pipe *p;
4652 struct policy_handle handle;
4654 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4655 if (!NT_STATUS_IS_OK(status)) {
4659 ret &= test_Connect(p, torture, &handle);
4661 ret &= test_QuerySecurity(p, torture, &handle);
4663 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_OTHER);
4665 ret &= test_SetDsrmPassword(p, torture, &handle);
4667 ret &= test_Shutdown(p, torture, &handle);
4669 ret &= test_samr_handle_Close(p, torture, &handle);
4675 bool torture_rpc_samr_users(struct torture_context *torture)
4678 struct dcerpc_pipe *p;
4680 struct policy_handle handle;
4682 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4683 if (!NT_STATUS_IS_OK(status)) {
4687 ret &= test_Connect(p, torture, &handle);
4689 ret &= test_QuerySecurity(p, torture, &handle);
4691 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_USER_ATTRIBUTES);
4693 ret &= test_SetDsrmPassword(p, torture, &handle);
4695 ret &= test_Shutdown(p, torture, &handle);
4697 ret &= test_samr_handle_Close(p, torture, &handle);
4703 bool torture_rpc_samr_passwords(struct torture_context *torture)
4706 struct dcerpc_pipe *p;
4708 struct policy_handle handle;
4710 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4711 if (!NT_STATUS_IS_OK(status)) {
4715 ret &= test_Connect(p, torture, &handle);
4717 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_PASSWORDS);
4719 ret &= test_samr_handle_Close(p, torture, &handle);