2 Unix SMB/CIFS implementation.
3 test suite for samr rpc operations
5 Copyright (C) Andrew Tridgell 2003
6 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "torture/torture.h"
24 #include "system/time.h"
25 #include "librpc/gen_ndr/lsa.h"
26 #include "librpc/gen_ndr/ndr_samr_c.h"
27 #include "../lib/crypto/crypto.h"
28 #include "libcli/auth/libcli_auth.h"
29 #include "libcli/security/security.h"
30 #include "torture/rpc/rpc.h"
32 #define TEST_ACCOUNT_NAME "samrtorturetest"
33 #define TEST_ALIASNAME "samrtorturetestalias"
34 #define TEST_GROUPNAME "samrtorturetestgroup"
35 #define TEST_MACHINENAME "samrtestmach$"
36 #define TEST_DOMAINNAME "samrtestdom$"
38 enum torture_samr_choice {
39 TORTURE_SAMR_PASSWORDS,
40 TORTURE_SAMR_USER_ATTRIBUTES,
44 static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
45 struct policy_handle *handle);
47 static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
48 struct policy_handle *handle);
50 static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
51 struct policy_handle *handle);
53 static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
54 const char *acct_name,
55 struct policy_handle *domain_handle, char **password);
57 static void init_lsa_String(struct lsa_String *string, const char *s)
62 static void init_lsa_BinaryString(struct lsa_BinaryString *string, const char *s, uint32_t length)
64 string->length = length;
65 string->size = length;
66 string->array = (uint16_t *)discard_const(s);
69 bool test_samr_handle_Close(struct dcerpc_pipe *p, struct torture_context *tctx,
70 struct policy_handle *handle)
76 r.out.handle = handle;
78 status = dcerpc_samr_Close(p, tctx, &r);
79 torture_assert_ntstatus_ok(tctx, status, "Close");
84 static bool test_Shutdown(struct dcerpc_pipe *p, struct torture_context *tctx,
85 struct policy_handle *handle)
88 struct samr_Shutdown r;
90 if (!torture_setting_bool(tctx, "dangerous", false)) {
91 torture_skip(tctx, "samr_Shutdown disabled - enable dangerous tests to use\n");
95 r.in.connect_handle = handle;
97 torture_comment(tctx, "testing samr_Shutdown\n");
99 status = dcerpc_samr_Shutdown(p, tctx, &r);
100 torture_assert_ntstatus_ok(tctx, status, "samr_Shutdown");
105 static bool test_SetDsrmPassword(struct dcerpc_pipe *p, struct torture_context *tctx,
106 struct policy_handle *handle)
109 struct samr_SetDsrmPassword r;
110 struct lsa_String string;
111 struct samr_Password hash;
113 if (!torture_setting_bool(tctx, "dangerous", false)) {
114 torture_skip(tctx, "samr_SetDsrmPassword disabled - enable dangerous tests to use");
117 E_md4hash("TeSTDSRM123", hash.hash);
119 init_lsa_String(&string, "Administrator");
125 torture_comment(tctx, "testing samr_SetDsrmPassword\n");
127 status = dcerpc_samr_SetDsrmPassword(p, tctx, &r);
128 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_SUPPORTED, "samr_SetDsrmPassword");
134 static bool test_QuerySecurity(struct dcerpc_pipe *p,
135 struct torture_context *tctx,
136 struct policy_handle *handle)
139 struct samr_QuerySecurity r;
140 struct samr_SetSecurity s;
141 struct sec_desc_buf *sdbuf = NULL;
143 r.in.handle = handle;
145 r.out.sdbuf = &sdbuf;
147 status = dcerpc_samr_QuerySecurity(p, tctx, &r);
148 torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
150 torture_assert(tctx, sdbuf != NULL, "sdbuf is NULL");
152 s.in.handle = handle;
156 if (torture_setting_bool(tctx, "samba4", false)) {
157 torture_skip(tctx, "skipping SetSecurity test against Samba4\n");
160 status = dcerpc_samr_SetSecurity(p, tctx, &s);
161 torture_assert_ntstatus_ok(tctx, status, "SetSecurity");
163 status = dcerpc_samr_QuerySecurity(p, tctx, &r);
164 torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
170 static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
171 struct policy_handle *handle, uint32_t base_acct_flags,
172 const char *base_account_name)
175 struct samr_SetUserInfo s;
176 struct samr_SetUserInfo2 s2;
177 struct samr_QueryUserInfo q;
178 struct samr_QueryUserInfo q0;
179 union samr_UserInfo u;
181 const char *test_account_name;
183 uint32_t user_extra_flags = 0;
184 if (base_acct_flags == ACB_NORMAL) {
185 /* When created, accounts are expired by default */
186 user_extra_flags = ACB_PW_EXPIRED;
189 s.in.user_handle = handle;
192 s2.in.user_handle = handle;
195 q.in.user_handle = handle;
199 #define TESTCALL(call, r) \
200 status = dcerpc_samr_ ##call(p, tctx, &r); \
201 if (!NT_STATUS_IS_OK(status)) { \
202 torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
203 r.in.level, nt_errstr(status), __location__); \
208 #define STRING_EQUAL(s1, s2, field) \
209 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
210 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
211 #field, s2, __location__); \
216 #define MEM_EQUAL(s1, s2, length, field) \
217 if ((s1 && !s2) || (s2 && !s1) || memcmp(s1, s2, length)) { \
218 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
219 #field, (const char *)s2, __location__); \
224 #define INT_EQUAL(i1, i2, field) \
226 torture_comment(tctx, "Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \
227 #field, (unsigned long long)i2, (unsigned long long)i1, __location__); \
232 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
233 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
235 TESTCALL(QueryUserInfo, q) \
237 s2.in.level = lvl1; \
240 ZERO_STRUCT(u.info21); \
241 u.info21.fields_present = fpval; \
243 init_lsa_String(&u.info ## lvl1.field1, value); \
244 TESTCALL(SetUserInfo, s) \
245 TESTCALL(SetUserInfo2, s2) \
246 init_lsa_String(&u.info ## lvl1.field1, ""); \
247 TESTCALL(QueryUserInfo, q); \
249 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
251 TESTCALL(QueryUserInfo, q) \
253 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
256 #define TEST_USERINFO_BINARYSTRING(lvl1, field1, lvl2, field2, value, fpval) do { \
257 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
259 TESTCALL(QueryUserInfo, q) \
261 s2.in.level = lvl1; \
264 ZERO_STRUCT(u.info21); \
265 u.info21.fields_present = fpval; \
267 init_lsa_BinaryString(&u.info ## lvl1.field1, value, strlen(value)); \
268 TESTCALL(SetUserInfo, s) \
269 TESTCALL(SetUserInfo2, s2) \
270 init_lsa_BinaryString(&u.info ## lvl1.field1, "", 1); \
271 TESTCALL(QueryUserInfo, q); \
273 MEM_EQUAL(u.info ## lvl1.field1.array, value, strlen(value), field1); \
275 TESTCALL(QueryUserInfo, q) \
277 MEM_EQUAL(u.info ## lvl2.field2.array, value, strlen(value), field2); \
280 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
281 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
283 TESTCALL(QueryUserInfo, q) \
285 s2.in.level = lvl1; \
288 uint8_t *bits = u.info21.logon_hours.bits; \
289 ZERO_STRUCT(u.info21); \
290 if (fpval == SAMR_FIELD_LOGON_HOURS) { \
291 u.info21.logon_hours.units_per_week = 168; \
292 u.info21.logon_hours.bits = bits; \
294 u.info21.fields_present = fpval; \
296 u.info ## lvl1.field1 = value; \
297 TESTCALL(SetUserInfo, s) \
298 TESTCALL(SetUserInfo2, s2) \
299 u.info ## lvl1.field1 = 0; \
300 TESTCALL(QueryUserInfo, q); \
302 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
304 TESTCALL(QueryUserInfo, q) \
306 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
309 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
310 TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
314 do { TESTCALL(QueryUserInfo, q0) } while (0);
316 TEST_USERINFO_STRING(2, comment, 1, comment, "xx2-1 comment", 0);
317 TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
318 TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment",
321 test_account_name = talloc_asprintf(tctx, "%sxx7-1", base_account_name);
322 TEST_USERINFO_STRING(7, account_name, 1, account_name, base_account_name, 0);
323 test_account_name = talloc_asprintf(tctx, "%sxx7-3", base_account_name);
324 TEST_USERINFO_STRING(7, account_name, 3, account_name, base_account_name, 0);
325 test_account_name = talloc_asprintf(tctx, "%sxx7-5", base_account_name);
326 TEST_USERINFO_STRING(7, account_name, 5, account_name, base_account_name, 0);
327 test_account_name = talloc_asprintf(tctx, "%sxx7-6", base_account_name);
328 TEST_USERINFO_STRING(7, account_name, 6, account_name, base_account_name, 0);
329 test_account_name = talloc_asprintf(tctx, "%sxx7-7", base_account_name);
330 TEST_USERINFO_STRING(7, account_name, 7, account_name, base_account_name, 0);
331 test_account_name = talloc_asprintf(tctx, "%sxx7-21", base_account_name);
332 TEST_USERINFO_STRING(7, account_name, 21, account_name, base_account_name, 0);
333 test_account_name = base_account_name;
334 TEST_USERINFO_STRING(21, account_name, 21, account_name, base_account_name,
335 SAMR_FIELD_ACCOUNT_NAME);
337 TEST_USERINFO_STRING(6, full_name, 1, full_name, "xx6-1 full_name", 0);
338 TEST_USERINFO_STRING(6, full_name, 3, full_name, "xx6-3 full_name", 0);
339 TEST_USERINFO_STRING(6, full_name, 5, full_name, "xx6-5 full_name", 0);
340 TEST_USERINFO_STRING(6, full_name, 6, full_name, "xx6-6 full_name", 0);
341 TEST_USERINFO_STRING(6, full_name, 8, full_name, "xx6-8 full_name", 0);
342 TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
343 TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
344 TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name",
345 SAMR_FIELD_FULL_NAME);
347 TEST_USERINFO_STRING(6, full_name, 1, full_name, "", 0);
348 TEST_USERINFO_STRING(6, full_name, 3, full_name, "", 0);
349 TEST_USERINFO_STRING(6, full_name, 5, full_name, "", 0);
350 TEST_USERINFO_STRING(6, full_name, 6, full_name, "", 0);
351 TEST_USERINFO_STRING(6, full_name, 8, full_name, "", 0);
352 TEST_USERINFO_STRING(6, full_name, 21, full_name, "", 0);
353 TEST_USERINFO_STRING(8, full_name, 21, full_name, "", 0);
354 TEST_USERINFO_STRING(21, full_name, 21, full_name, "",
355 SAMR_FIELD_FULL_NAME);
357 TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
358 TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
359 TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
360 TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script",
361 SAMR_FIELD_LOGON_SCRIPT);
363 TEST_USERINFO_STRING(12, profile_path, 3, profile_path, "xx12-3 profile_path", 0);
364 TEST_USERINFO_STRING(12, profile_path, 5, profile_path, "xx12-5 profile_path", 0);
365 TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
366 TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path",
367 SAMR_FIELD_PROFILE_PATH);
369 TEST_USERINFO_STRING(10, home_directory, 3, home_directory, "xx10-3 home_directory", 0);
370 TEST_USERINFO_STRING(10, home_directory, 5, home_directory, "xx10-5 home_directory", 0);
371 TEST_USERINFO_STRING(10, home_directory, 21, home_directory, "xx10-21 home_directory", 0);
372 TEST_USERINFO_STRING(21, home_directory, 21, home_directory, "xx21-21 home_directory",
373 SAMR_FIELD_HOME_DIRECTORY);
374 TEST_USERINFO_STRING(21, home_directory, 10, home_directory, "xx21-10 home_directory",
375 SAMR_FIELD_HOME_DIRECTORY);
377 TEST_USERINFO_STRING(10, home_drive, 3, home_drive, "xx10-3 home_drive", 0);
378 TEST_USERINFO_STRING(10, home_drive, 5, home_drive, "xx10-5 home_drive", 0);
379 TEST_USERINFO_STRING(10, home_drive, 21, home_drive, "xx10-21 home_drive", 0);
380 TEST_USERINFO_STRING(21, home_drive, 21, home_drive, "xx21-21 home_drive",
381 SAMR_FIELD_HOME_DRIVE);
382 TEST_USERINFO_STRING(21, home_drive, 10, home_drive, "xx21-10 home_drive",
383 SAMR_FIELD_HOME_DRIVE);
385 TEST_USERINFO_STRING(13, description, 1, description, "xx13-1 description", 0);
386 TEST_USERINFO_STRING(13, description, 5, description, "xx13-5 description", 0);
387 TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
388 TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description",
389 SAMR_FIELD_DESCRIPTION);
391 TEST_USERINFO_STRING(14, workstations, 3, workstations, "14workstation3", 0);
392 TEST_USERINFO_STRING(14, workstations, 5, workstations, "14workstation4", 0);
393 TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
394 TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21",
395 SAMR_FIELD_WORKSTATIONS);
396 TEST_USERINFO_STRING(21, workstations, 3, workstations, "21workstation3",
397 SAMR_FIELD_WORKSTATIONS);
398 TEST_USERINFO_STRING(21, workstations, 5, workstations, "21workstation5",
399 SAMR_FIELD_WORKSTATIONS);
400 TEST_USERINFO_STRING(21, workstations, 14, workstations, "21workstation14",
401 SAMR_FIELD_WORKSTATIONS);
403 TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
404 TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "xx21-21 parameters",
405 SAMR_FIELD_PARAMETERS);
406 TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "xx21-20 parameters",
407 SAMR_FIELD_PARAMETERS);
409 TEST_USERINFO_INT(2, country_code, 2, country_code, __LINE__, 0);
410 TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
411 TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__,
412 SAMR_FIELD_COUNTRY_CODE);
413 TEST_USERINFO_INT(21, country_code, 2, country_code, __LINE__,
414 SAMR_FIELD_COUNTRY_CODE);
416 TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
417 TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__,
418 SAMR_FIELD_CODE_PAGE);
419 TEST_USERINFO_INT(21, code_page, 2, code_page, __LINE__,
420 SAMR_FIELD_CODE_PAGE);
422 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, __LINE__, 0);
423 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, __LINE__, 0);
424 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, __LINE__,
425 SAMR_FIELD_ACCT_EXPIRY);
426 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, __LINE__,
427 SAMR_FIELD_ACCT_EXPIRY);
428 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, __LINE__,
429 SAMR_FIELD_ACCT_EXPIRY);
431 TEST_USERINFO_INT(4, logon_hours.bits[3], 3, logon_hours.bits[3], 1, 0);
432 TEST_USERINFO_INT(4, logon_hours.bits[3], 5, logon_hours.bits[3], 2, 0);
433 TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
434 TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4,
435 SAMR_FIELD_LOGON_HOURS);
437 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
438 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
439 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
441 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
442 (base_acct_flags | ACB_DISABLED),
443 (base_acct_flags | ACB_DISABLED | user_extra_flags),
446 /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
447 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
448 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
449 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
451 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
452 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
453 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
457 /* The 'autolock' flag doesn't stick - check this */
458 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
459 (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK),
460 (base_acct_flags | ACB_DISABLED | user_extra_flags),
463 /* Removing the 'disabled' flag doesn't stick - check this */
464 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
466 (base_acct_flags | ACB_DISABLED | user_extra_flags),
469 /* The 'store plaintext' flag does stick */
470 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
471 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED),
472 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags),
474 /* The 'use DES' flag does stick */
475 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
476 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY),
477 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags),
479 /* The 'don't require kerberos pre-authentication flag does stick */
480 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
481 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH),
482 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags),
484 /* The 'no kerberos PAC required' flag sticks */
485 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
486 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD),
487 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags),
490 TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags,
491 (base_acct_flags | ACB_DISABLED),
492 (base_acct_flags | ACB_DISABLED | user_extra_flags),
493 SAMR_FIELD_ACCT_FLAGS);
496 /* these fail with win2003 - it appears you can't set the primary gid?
497 the set succeeds, but the gid isn't changed. Very weird! */
498 TEST_USERINFO_INT(9, primary_gid, 1, primary_gid, 513);
499 TEST_USERINFO_INT(9, primary_gid, 3, primary_gid, 513);
500 TEST_USERINFO_INT(9, primary_gid, 5, primary_gid, 513);
501 TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
508 generate a random password for password change tests
510 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
512 size_t len = MAX(8, min_len) + (random() % 6);
513 char *s = generate_random_str(mem_ctx, len);
514 printf("Generated password '%s'\n", s);
519 generate a random password for password change tests
521 static DATA_BLOB samr_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
524 DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
525 generate_random_buffer(password.data, password.length);
527 for (i=0; i < len; i++) {
528 if (((uint16_t *)password.data)[i] == 0) {
529 ((uint16_t *)password.data)[i] = 1;
537 generate a random password for password change tests (fixed length)
539 static char *samr_rand_pass_fixed_len(TALLOC_CTX *mem_ctx, int len)
541 char *s = generate_random_str(mem_ctx, len);
542 printf("Generated password '%s'\n", s);
546 static bool test_SetUserPass(struct dcerpc_pipe *p, struct torture_context *tctx,
547 struct policy_handle *handle, char **password)
550 struct samr_SetUserInfo s;
551 union samr_UserInfo u;
553 DATA_BLOB session_key;
555 struct samr_GetUserPwInfo pwp;
556 struct samr_PwInfo info;
557 int policy_min_pw_len = 0;
558 pwp.in.user_handle = handle;
559 pwp.out.info = &info;
561 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
562 if (NT_STATUS_IS_OK(status)) {
563 policy_min_pw_len = pwp.out.info->min_password_length;
565 newpass = samr_rand_pass(tctx, policy_min_pw_len);
567 s.in.user_handle = handle;
571 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
572 /* w2k3 ignores this length */
573 u.info24.pw_len = strlen_m(newpass) * 2;
575 status = dcerpc_fetch_session_key(p, &session_key);
576 if (!NT_STATUS_IS_OK(status)) {
577 printf("SetUserInfo level %u - no session key - %s\n",
578 s.in.level, nt_errstr(status));
582 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
584 torture_comment(tctx, "Testing SetUserInfo level 24 (set password)\n");
586 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
587 if (!NT_STATUS_IS_OK(status)) {
588 printf("SetUserInfo level %u failed - %s\n",
589 s.in.level, nt_errstr(status));
599 static bool test_SetUserPass_23(struct dcerpc_pipe *p, struct torture_context *tctx,
600 struct policy_handle *handle, uint32_t fields_present,
604 struct samr_SetUserInfo s;
605 union samr_UserInfo u;
607 DATA_BLOB session_key;
609 struct samr_GetUserPwInfo pwp;
610 struct samr_PwInfo info;
611 int policy_min_pw_len = 0;
612 pwp.in.user_handle = handle;
613 pwp.out.info = &info;
615 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
616 if (NT_STATUS_IS_OK(status)) {
617 policy_min_pw_len = pwp.out.info->min_password_length;
619 newpass = samr_rand_pass(tctx, policy_min_pw_len);
621 s.in.user_handle = handle;
627 u.info23.info.fields_present = fields_present;
629 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
631 status = dcerpc_fetch_session_key(p, &session_key);
632 if (!NT_STATUS_IS_OK(status)) {
633 printf("SetUserInfo level %u - no session key - %s\n",
634 s.in.level, nt_errstr(status));
638 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
640 torture_comment(tctx, "Testing SetUserInfo level 23 (set password)\n");
642 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
643 if (!NT_STATUS_IS_OK(status)) {
644 printf("SetUserInfo level %u failed - %s\n",
645 s.in.level, nt_errstr(status));
651 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
653 status = dcerpc_fetch_session_key(p, &session_key);
654 if (!NT_STATUS_IS_OK(status)) {
655 printf("SetUserInfo level %u - no session key - %s\n",
656 s.in.level, nt_errstr(status));
660 /* This should break the key nicely */
661 session_key.length--;
662 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
664 torture_comment(tctx, "Testing SetUserInfo level 23 (set password) with wrong password\n");
666 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
667 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
668 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
669 s.in.level, nt_errstr(status));
677 static bool test_SetUserPassEx(struct dcerpc_pipe *p, struct torture_context *tctx,
678 struct policy_handle *handle, bool makeshort,
682 struct samr_SetUserInfo s;
683 union samr_UserInfo u;
685 DATA_BLOB session_key;
686 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
687 uint8_t confounder[16];
689 struct MD5Context ctx;
690 struct samr_GetUserPwInfo pwp;
691 struct samr_PwInfo info;
692 int policy_min_pw_len = 0;
693 pwp.in.user_handle = handle;
694 pwp.out.info = &info;
696 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
697 if (NT_STATUS_IS_OK(status)) {
698 policy_min_pw_len = pwp.out.info->min_password_length;
700 if (makeshort && policy_min_pw_len) {
701 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len - 1);
703 newpass = samr_rand_pass(tctx, policy_min_pw_len);
706 s.in.user_handle = handle;
710 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
711 u.info26.pw_len = strlen(newpass);
713 status = dcerpc_fetch_session_key(p, &session_key);
714 if (!NT_STATUS_IS_OK(status)) {
715 printf("SetUserInfo level %u - no session key - %s\n",
716 s.in.level, nt_errstr(status));
720 generate_random_buffer((uint8_t *)confounder, 16);
723 MD5Update(&ctx, confounder, 16);
724 MD5Update(&ctx, session_key.data, session_key.length);
725 MD5Final(confounded_session_key.data, &ctx);
727 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
728 memcpy(&u.info26.password.data[516], confounder, 16);
730 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex)\n");
732 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
733 if (!NT_STATUS_IS_OK(status)) {
734 printf("SetUserInfo level %u failed - %s\n",
735 s.in.level, nt_errstr(status));
741 /* This should break the key nicely */
742 confounded_session_key.data[0]++;
744 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
745 memcpy(&u.info26.password.data[516], confounder, 16);
747 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
749 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
750 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
751 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
752 s.in.level, nt_errstr(status));
761 static bool test_SetUserPass_25(struct dcerpc_pipe *p, struct torture_context *tctx,
762 struct policy_handle *handle, uint32_t fields_present,
766 struct samr_SetUserInfo s;
767 union samr_UserInfo u;
769 DATA_BLOB session_key;
770 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
771 struct MD5Context ctx;
772 uint8_t confounder[16];
774 struct samr_GetUserPwInfo pwp;
775 struct samr_PwInfo info;
776 int policy_min_pw_len = 0;
777 pwp.in.user_handle = handle;
778 pwp.out.info = &info;
780 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
781 if (NT_STATUS_IS_OK(status)) {
782 policy_min_pw_len = pwp.out.info->min_password_length;
784 newpass = samr_rand_pass(tctx, policy_min_pw_len);
786 s.in.user_handle = handle;
792 u.info25.info.fields_present = fields_present;
794 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
796 status = dcerpc_fetch_session_key(p, &session_key);
797 if (!NT_STATUS_IS_OK(status)) {
798 printf("SetUserInfo level %u - no session key - %s\n",
799 s.in.level, nt_errstr(status));
803 generate_random_buffer((uint8_t *)confounder, 16);
806 MD5Update(&ctx, confounder, 16);
807 MD5Update(&ctx, session_key.data, session_key.length);
808 MD5Final(confounded_session_key.data, &ctx);
810 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
811 memcpy(&u.info25.password.data[516], confounder, 16);
813 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex)\n");
815 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
816 if (!NT_STATUS_IS_OK(status)) {
817 printf("SetUserInfo level %u failed - %s\n",
818 s.in.level, nt_errstr(status));
824 /* This should break the key nicely */
825 confounded_session_key.data[0]++;
827 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
828 memcpy(&u.info25.password.data[516], confounder, 16);
830 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
832 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
833 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
834 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
835 s.in.level, nt_errstr(status));
842 static bool test_SetAliasInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
843 struct policy_handle *handle)
846 struct samr_SetAliasInfo r;
847 struct samr_QueryAliasInfo q;
848 uint16_t levels[] = {2, 3};
852 /* Ignoring switch level 1, as that includes the number of members for the alias
853 * and setting this to a wrong value might have negative consequences
856 for (i=0;i<ARRAY_SIZE(levels);i++) {
857 torture_comment(tctx, "Testing SetAliasInfo level %u\n", levels[i]);
859 r.in.alias_handle = handle;
860 r.in.level = levels[i];
861 r.in.info = talloc(tctx, union samr_AliasInfo);
862 switch (r.in.level) {
863 case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
864 case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
865 "Test Description, should test I18N as well"); break;
866 case ALIASINFOALL: printf("ALIASINFOALL ignored\n"); break;
869 status = dcerpc_samr_SetAliasInfo(p, tctx, &r);
870 if (!NT_STATUS_IS_OK(status)) {
871 printf("SetAliasInfo level %u failed - %s\n",
872 levels[i], nt_errstr(status));
876 q.in.alias_handle = handle;
877 q.in.level = levels[i];
879 status = dcerpc_samr_QueryAliasInfo(p, tctx, &q);
880 if (!NT_STATUS_IS_OK(status)) {
881 printf("QueryAliasInfo level %u failed - %s\n",
882 levels[i], nt_errstr(status));
890 static bool test_GetGroupsForUser(struct dcerpc_pipe *p, struct torture_context *tctx,
891 struct policy_handle *user_handle)
893 struct samr_GetGroupsForUser r;
894 struct samr_RidWithAttributeArray *rids = NULL;
897 torture_comment(tctx, "testing GetGroupsForUser\n");
899 r.in.user_handle = user_handle;
902 status = dcerpc_samr_GetGroupsForUser(p, tctx, &r);
903 torture_assert_ntstatus_ok(tctx, status, "GetGroupsForUser");
909 static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
910 struct lsa_String *domain_name)
913 struct samr_GetDomPwInfo r;
914 struct samr_PwInfo info;
916 r.in.domain_name = domain_name;
919 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
921 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
922 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
924 r.in.domain_name->string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
925 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
927 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
928 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
930 r.in.domain_name->string = "\\\\__NONAME__";
931 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
933 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
934 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
936 r.in.domain_name->string = "\\\\Builtin";
937 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
939 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
940 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
945 static bool test_GetUserPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
946 struct policy_handle *handle)
949 struct samr_GetUserPwInfo r;
950 struct samr_PwInfo info;
952 torture_comment(tctx, "Testing GetUserPwInfo\n");
954 r.in.user_handle = handle;
957 status = dcerpc_samr_GetUserPwInfo(p, tctx, &r);
958 torture_assert_ntstatus_ok(tctx, status, "GetUserPwInfo");
963 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, struct torture_context *tctx,
964 struct policy_handle *domain_handle, const char *name,
968 struct samr_LookupNames n;
969 struct lsa_String sname[2];
971 init_lsa_String(&sname[0], name);
973 n.in.domain_handle = domain_handle;
976 status = dcerpc_samr_LookupNames(p, tctx, &n);
977 if (NT_STATUS_IS_OK(status)) {
978 *rid = n.out.rids.ids[0];
983 init_lsa_String(&sname[1], "xxNONAMExx");
985 status = dcerpc_samr_LookupNames(p, tctx, &n);
986 if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
987 printf("LookupNames[2] failed - %s\n", nt_errstr(status));
988 if (NT_STATUS_IS_OK(status)) {
989 return NT_STATUS_UNSUCCESSFUL;
995 status = dcerpc_samr_LookupNames(p, tctx, &n);
996 if (!NT_STATUS_IS_OK(status)) {
997 printf("LookupNames[0] failed - %s\n", nt_errstr(status));
1001 init_lsa_String(&sname[0], "xxNONAMExx");
1003 status = dcerpc_samr_LookupNames(p, tctx, &n);
1004 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1005 printf("LookupNames[1 bad name] failed - %s\n", nt_errstr(status));
1006 if (NT_STATUS_IS_OK(status)) {
1007 return NT_STATUS_UNSUCCESSFUL;
1012 init_lsa_String(&sname[0], "xxNONAMExx");
1013 init_lsa_String(&sname[1], "xxNONAME2xx");
1015 status = dcerpc_samr_LookupNames(p, tctx, &n);
1016 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1017 printf("LookupNames[2 bad names] failed - %s\n", nt_errstr(status));
1018 if (NT_STATUS_IS_OK(status)) {
1019 return NT_STATUS_UNSUCCESSFUL;
1024 return NT_STATUS_OK;
1027 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1028 struct policy_handle *domain_handle,
1029 const char *name, struct policy_handle *user_handle)
1032 struct samr_OpenUser r;
1035 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
1036 if (!NT_STATUS_IS_OK(status)) {
1040 r.in.domain_handle = domain_handle;
1041 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1043 r.out.user_handle = user_handle;
1044 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
1045 if (!NT_STATUS_IS_OK(status)) {
1046 printf("OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(status));
1053 static bool test_ChangePasswordNT3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1054 struct policy_handle *handle)
1057 struct samr_ChangePasswordUser r;
1059 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1060 struct policy_handle user_handle;
1061 char *oldpass = "test";
1062 char *newpass = "test2";
1063 uint8_t old_nt_hash[16], new_nt_hash[16];
1064 uint8_t old_lm_hash[16], new_lm_hash[16];
1066 status = test_OpenUser_byname(p, mem_ctx, handle, "testuser", &user_handle);
1067 if (!NT_STATUS_IS_OK(status)) {
1071 printf("Testing ChangePasswordUser for user 'testuser'\n");
1073 printf("old password: %s\n", oldpass);
1074 printf("new password: %s\n", newpass);
1076 E_md4hash(oldpass, old_nt_hash);
1077 E_md4hash(newpass, new_nt_hash);
1078 E_deshash(oldpass, old_lm_hash);
1079 E_deshash(newpass, new_lm_hash);
1081 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1082 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1083 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1084 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1085 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1086 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1088 r.in.handle = &user_handle;
1089 r.in.lm_present = 1;
1090 r.in.old_lm_crypted = &hash1;
1091 r.in.new_lm_crypted = &hash2;
1092 r.in.nt_present = 1;
1093 r.in.old_nt_crypted = &hash3;
1094 r.in.new_nt_crypted = &hash4;
1095 r.in.cross1_present = 1;
1096 r.in.nt_cross = &hash5;
1097 r.in.cross2_present = 1;
1098 r.in.lm_cross = &hash6;
1100 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1101 if (!NT_STATUS_IS_OK(status)) {
1102 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1106 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1114 static bool test_ChangePasswordUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1115 const char *acct_name,
1116 struct policy_handle *handle, char **password)
1119 struct samr_ChangePasswordUser r;
1121 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1122 struct policy_handle user_handle;
1124 uint8_t old_nt_hash[16], new_nt_hash[16];
1125 uint8_t old_lm_hash[16], new_lm_hash[16];
1126 bool changed = true;
1129 struct samr_GetUserPwInfo pwp;
1130 struct samr_PwInfo info;
1131 int policy_min_pw_len = 0;
1133 status = test_OpenUser_byname(p, tctx, handle, acct_name, &user_handle);
1134 if (!NT_STATUS_IS_OK(status)) {
1137 pwp.in.user_handle = &user_handle;
1138 pwp.out.info = &info;
1140 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1141 if (NT_STATUS_IS_OK(status)) {
1142 policy_min_pw_len = pwp.out.info->min_password_length;
1144 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1146 torture_comment(tctx, "Testing ChangePasswordUser\n");
1148 torture_assert(tctx, *password != NULL,
1149 "Failing ChangePasswordUser as old password was NULL. Previous test failed?");
1151 oldpass = *password;
1153 E_md4hash(oldpass, old_nt_hash);
1154 E_md4hash(newpass, new_nt_hash);
1155 E_deshash(oldpass, old_lm_hash);
1156 E_deshash(newpass, new_lm_hash);
1158 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1159 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1160 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1161 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1162 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1163 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1165 r.in.user_handle = &user_handle;
1166 r.in.lm_present = 1;
1167 /* Break the LM hash */
1169 r.in.old_lm_crypted = &hash1;
1170 r.in.new_lm_crypted = &hash2;
1171 r.in.nt_present = 1;
1172 r.in.old_nt_crypted = &hash3;
1173 r.in.new_nt_crypted = &hash4;
1174 r.in.cross1_present = 1;
1175 r.in.nt_cross = &hash5;
1176 r.in.cross2_present = 1;
1177 r.in.lm_cross = &hash6;
1179 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1180 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1181 "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash");
1183 /* Unbreak the LM hash */
1186 r.in.user_handle = &user_handle;
1187 r.in.lm_present = 1;
1188 r.in.old_lm_crypted = &hash1;
1189 r.in.new_lm_crypted = &hash2;
1190 /* Break the NT hash */
1192 r.in.nt_present = 1;
1193 r.in.old_nt_crypted = &hash3;
1194 r.in.new_nt_crypted = &hash4;
1195 r.in.cross1_present = 1;
1196 r.in.nt_cross = &hash5;
1197 r.in.cross2_present = 1;
1198 r.in.lm_cross = &hash6;
1200 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1201 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1202 "expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash");
1204 /* Unbreak the NT hash */
1207 r.in.user_handle = &user_handle;
1208 r.in.lm_present = 1;
1209 r.in.old_lm_crypted = &hash1;
1210 r.in.new_lm_crypted = &hash2;
1211 r.in.nt_present = 1;
1212 r.in.old_nt_crypted = &hash3;
1213 r.in.new_nt_crypted = &hash4;
1214 r.in.cross1_present = 1;
1215 r.in.nt_cross = &hash5;
1216 r.in.cross2_present = 1;
1217 /* Break the LM cross */
1219 r.in.lm_cross = &hash6;
1221 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1222 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1223 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status));
1227 /* Unbreak the LM cross */
1230 r.in.user_handle = &user_handle;
1231 r.in.lm_present = 1;
1232 r.in.old_lm_crypted = &hash1;
1233 r.in.new_lm_crypted = &hash2;
1234 r.in.nt_present = 1;
1235 r.in.old_nt_crypted = &hash3;
1236 r.in.new_nt_crypted = &hash4;
1237 r.in.cross1_present = 1;
1238 /* Break the NT cross */
1240 r.in.nt_cross = &hash5;
1241 r.in.cross2_present = 1;
1242 r.in.lm_cross = &hash6;
1244 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1245 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1246 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status));
1250 /* Unbreak the NT cross */
1254 /* Reset the hashes to not broken values */
1255 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1256 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1257 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1258 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1259 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1260 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1262 r.in.user_handle = &user_handle;
1263 r.in.lm_present = 1;
1264 r.in.old_lm_crypted = &hash1;
1265 r.in.new_lm_crypted = &hash2;
1266 r.in.nt_present = 1;
1267 r.in.old_nt_crypted = &hash3;
1268 r.in.new_nt_crypted = &hash4;
1269 r.in.cross1_present = 1;
1270 r.in.nt_cross = &hash5;
1271 r.in.cross2_present = 0;
1272 r.in.lm_cross = NULL;
1274 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1275 if (NT_STATUS_IS_OK(status)) {
1277 *password = newpass;
1278 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1279 printf("ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(status));
1284 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1286 E_md4hash(oldpass, old_nt_hash);
1287 E_md4hash(newpass, new_nt_hash);
1288 E_deshash(oldpass, old_lm_hash);
1289 E_deshash(newpass, new_lm_hash);
1292 /* Reset the hashes to not broken values */
1293 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1294 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1295 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1296 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1297 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1298 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1300 r.in.user_handle = &user_handle;
1301 r.in.lm_present = 1;
1302 r.in.old_lm_crypted = &hash1;
1303 r.in.new_lm_crypted = &hash2;
1304 r.in.nt_present = 1;
1305 r.in.old_nt_crypted = &hash3;
1306 r.in.new_nt_crypted = &hash4;
1307 r.in.cross1_present = 0;
1308 r.in.nt_cross = NULL;
1309 r.in.cross2_present = 1;
1310 r.in.lm_cross = &hash6;
1312 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1313 if (NT_STATUS_IS_OK(status)) {
1315 *password = newpass;
1316 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1317 printf("ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status));
1322 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1324 E_md4hash(oldpass, old_nt_hash);
1325 E_md4hash(newpass, new_nt_hash);
1326 E_deshash(oldpass, old_lm_hash);
1327 E_deshash(newpass, new_lm_hash);
1330 /* Reset the hashes to not broken values */
1331 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1332 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1333 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1334 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1335 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1336 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1338 r.in.user_handle = &user_handle;
1339 r.in.lm_present = 1;
1340 r.in.old_lm_crypted = &hash1;
1341 r.in.new_lm_crypted = &hash2;
1342 r.in.nt_present = 1;
1343 r.in.old_nt_crypted = &hash3;
1344 r.in.new_nt_crypted = &hash4;
1345 r.in.cross1_present = 1;
1346 r.in.nt_cross = &hash5;
1347 r.in.cross2_present = 1;
1348 r.in.lm_cross = &hash6;
1350 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1351 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1352 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1353 } else if (!NT_STATUS_IS_OK(status)) {
1354 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1358 *password = newpass;
1361 r.in.user_handle = &user_handle;
1362 r.in.lm_present = 1;
1363 r.in.old_lm_crypted = &hash1;
1364 r.in.new_lm_crypted = &hash2;
1365 r.in.nt_present = 1;
1366 r.in.old_nt_crypted = &hash3;
1367 r.in.new_nt_crypted = &hash4;
1368 r.in.cross1_present = 1;
1369 r.in.nt_cross = &hash5;
1370 r.in.cross2_present = 1;
1371 r.in.lm_cross = &hash6;
1374 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1375 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1376 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1377 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1378 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status));
1384 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
1392 static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
1393 const char *acct_name,
1394 struct policy_handle *handle, char **password)
1397 struct samr_OemChangePasswordUser2 r;
1399 struct samr_Password lm_verifier;
1400 struct samr_CryptPassword lm_pass;
1401 struct lsa_AsciiString server, account, account_bad;
1404 uint8_t old_lm_hash[16], new_lm_hash[16];
1406 struct samr_GetDomPwInfo dom_pw_info;
1407 struct samr_PwInfo info;
1408 int policy_min_pw_len = 0;
1410 struct lsa_String domain_name;
1412 domain_name.string = "";
1413 dom_pw_info.in.domain_name = &domain_name;
1414 dom_pw_info.out.info = &info;
1416 torture_comment(tctx, "Testing OemChangePasswordUser2\n");
1418 torture_assert(tctx, *password != NULL,
1419 "Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?");
1421 oldpass = *password;
1423 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
1424 if (NT_STATUS_IS_OK(status)) {
1425 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
1428 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1430 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1431 account.string = acct_name;
1433 E_deshash(oldpass, old_lm_hash);
1434 E_deshash(newpass, new_lm_hash);
1436 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1437 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1438 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1440 r.in.server = &server;
1441 r.in.account = &account;
1442 r.in.password = &lm_pass;
1443 r.in.hash = &lm_verifier;
1445 /* Break the verification */
1446 lm_verifier.hash[0]++;
1448 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1450 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1451 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1452 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1457 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1458 /* Break the old password */
1460 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1461 /* unbreak it for the next operation */
1463 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1465 r.in.server = &server;
1466 r.in.account = &account;
1467 r.in.password = &lm_pass;
1468 r.in.hash = &lm_verifier;
1470 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1472 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1473 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1474 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1479 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1480 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1482 r.in.server = &server;
1483 r.in.account = &account;
1484 r.in.password = &lm_pass;
1487 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1489 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1490 && !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1491 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
1496 /* This shouldn't be a valid name */
1497 account_bad.string = TEST_ACCOUNT_NAME "XX";
1498 r.in.account = &account_bad;
1500 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1502 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1503 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
1508 /* This shouldn't be a valid name */
1509 account_bad.string = TEST_ACCOUNT_NAME "XX";
1510 r.in.account = &account_bad;
1511 r.in.password = &lm_pass;
1512 r.in.hash = &lm_verifier;
1514 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1516 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1517 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1522 /* This shouldn't be a valid name */
1523 account_bad.string = TEST_ACCOUNT_NAME "XX";
1524 r.in.account = &account_bad;
1525 r.in.password = NULL;
1526 r.in.hash = &lm_verifier;
1528 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1530 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1531 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
1536 E_deshash(oldpass, old_lm_hash);
1537 E_deshash(newpass, new_lm_hash);
1539 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1540 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1541 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1543 r.in.server = &server;
1544 r.in.account = &account;
1545 r.in.password = &lm_pass;
1546 r.in.hash = &lm_verifier;
1548 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1549 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1550 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1551 } else if (!NT_STATUS_IS_OK(status)) {
1552 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
1555 *password = newpass;
1562 static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
1563 const char *acct_name,
1565 char *newpass, bool allow_password_restriction)
1568 struct samr_ChangePasswordUser2 r;
1570 struct lsa_String server, account;
1571 struct samr_CryptPassword nt_pass, lm_pass;
1572 struct samr_Password nt_verifier, lm_verifier;
1574 uint8_t old_nt_hash[16], new_nt_hash[16];
1575 uint8_t old_lm_hash[16], new_lm_hash[16];
1577 struct samr_GetDomPwInfo dom_pw_info;
1578 struct samr_PwInfo info;
1580 struct lsa_String domain_name;
1582 domain_name.string = "";
1583 dom_pw_info.in.domain_name = &domain_name;
1584 dom_pw_info.out.info = &info;
1586 torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name);
1588 torture_assert(tctx, *password != NULL,
1589 "Failing ChangePasswordUser2 as old password was NULL. Previous test failed?");
1590 oldpass = *password;
1593 int policy_min_pw_len = 0;
1594 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
1595 if (NT_STATUS_IS_OK(status)) {
1596 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
1599 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1602 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1603 init_lsa_String(&account, acct_name);
1605 E_md4hash(oldpass, old_nt_hash);
1606 E_md4hash(newpass, new_nt_hash);
1608 E_deshash(oldpass, old_lm_hash);
1609 E_deshash(newpass, new_lm_hash);
1611 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
1612 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1613 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1615 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1616 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1617 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1619 r.in.server = &server;
1620 r.in.account = &account;
1621 r.in.nt_password = &nt_pass;
1622 r.in.nt_verifier = &nt_verifier;
1624 r.in.lm_password = &lm_pass;
1625 r.in.lm_verifier = &lm_verifier;
1627 status = dcerpc_samr_ChangePasswordUser2(p, tctx, &r);
1628 if (allow_password_restriction && NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1629 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1630 } else if (!NT_STATUS_IS_OK(status)) {
1631 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
1634 *password = newpass;
1641 bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tctx,
1642 const char *account_string,
1643 int policy_min_pw_len,
1645 const char *newpass,
1646 NTTIME last_password_change,
1647 bool handle_reject_reason)
1650 struct samr_ChangePasswordUser3 r;
1652 struct lsa_String server, account, account_bad;
1653 struct samr_CryptPassword nt_pass, lm_pass;
1654 struct samr_Password nt_verifier, lm_verifier;
1656 uint8_t old_nt_hash[16], new_nt_hash[16];
1657 uint8_t old_lm_hash[16], new_lm_hash[16];
1659 struct samr_DomInfo1 *dominfo = NULL;
1660 struct samr_ChangeReject *reject = NULL;
1662 torture_comment(tctx, "Testing ChangePasswordUser3\n");
1664 if (newpass == NULL) {
1666 if (policy_min_pw_len == 0) {
1667 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1669 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len);
1671 } while (check_password_quality(newpass) == false);
1673 torture_comment(tctx, "Using password '%s'\n", newpass);
1676 torture_assert(tctx, *password != NULL,
1677 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
1679 oldpass = *password;
1680 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1681 init_lsa_String(&account, account_string);
1683 E_md4hash(oldpass, old_nt_hash);
1684 E_md4hash(newpass, new_nt_hash);
1686 E_deshash(oldpass, old_lm_hash);
1687 E_deshash(newpass, new_lm_hash);
1689 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1690 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1691 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1693 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1694 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1695 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1697 /* Break the verification */
1698 nt_verifier.hash[0]++;
1700 r.in.server = &server;
1701 r.in.account = &account;
1702 r.in.nt_password = &nt_pass;
1703 r.in.nt_verifier = &nt_verifier;
1705 r.in.lm_password = &lm_pass;
1706 r.in.lm_verifier = &lm_verifier;
1707 r.in.password3 = NULL;
1708 r.out.dominfo = &dominfo;
1709 r.out.reject = &reject;
1711 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1712 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1713 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1714 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1719 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1720 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1721 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1723 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1724 /* Break the NT hash */
1726 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1727 /* Unbreak it again */
1729 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1731 r.in.server = &server;
1732 r.in.account = &account;
1733 r.in.nt_password = &nt_pass;
1734 r.in.nt_verifier = &nt_verifier;
1736 r.in.lm_password = &lm_pass;
1737 r.in.lm_verifier = &lm_verifier;
1738 r.in.password3 = NULL;
1739 r.out.dominfo = &dominfo;
1740 r.out.reject = &reject;
1742 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1743 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1744 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1745 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1750 /* This shouldn't be a valid name */
1751 init_lsa_String(&account_bad, talloc_asprintf(tctx, "%sXX", account_string));
1753 r.in.account = &account_bad;
1754 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1755 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1756 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
1761 E_md4hash(oldpass, old_nt_hash);
1762 E_md4hash(newpass, new_nt_hash);
1764 E_deshash(oldpass, old_lm_hash);
1765 E_deshash(newpass, new_lm_hash);
1767 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1768 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1769 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1771 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1772 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1773 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1775 r.in.server = &server;
1776 r.in.account = &account;
1777 r.in.nt_password = &nt_pass;
1778 r.in.nt_verifier = &nt_verifier;
1780 r.in.lm_password = &lm_pass;
1781 r.in.lm_verifier = &lm_verifier;
1782 r.in.password3 = NULL;
1783 r.out.dominfo = &dominfo;
1784 r.out.reject = &reject;
1786 unix_to_nt_time(&t, time(NULL));
1788 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1790 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1793 && handle_reject_reason
1794 && (!null_nttime(last_password_change) || !dominfo->min_password_age)) {
1795 if (dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
1797 if (reject && (reject->reason != SAMR_REJECT_OTHER)) {
1798 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1799 SAMR_REJECT_OTHER, reject->reason);
1804 /* We tested the order of precendence which is as follows:
1813 if ((dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
1814 (last_password_change + dominfo->min_password_age > t)) {
1816 if (reject->reason != SAMR_REJECT_OTHER) {
1817 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1818 SAMR_REJECT_OTHER, reject->reason);
1822 } else if ((dominfo->min_password_length > 0) &&
1823 (strlen(newpass) < dominfo->min_password_length)) {
1825 if (reject->reason != SAMR_REJECT_TOO_SHORT) {
1826 printf("expected SAMR_REJECT_TOO_SHORT (%d), got %d\n",
1827 SAMR_REJECT_TOO_SHORT, reject->reason);
1831 } else if ((dominfo->password_history_length > 0) &&
1832 strequal(oldpass, newpass)) {
1834 if (reject->reason != SAMR_REJECT_IN_HISTORY) {
1835 printf("expected SAMR_REJECT_IN_HISTORY (%d), got %d\n",
1836 SAMR_REJECT_IN_HISTORY, reject->reason);
1839 } else if (dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
1841 if (reject->reason != SAMR_REJECT_COMPLEXITY) {
1842 printf("expected SAMR_REJECT_COMPLEXITY (%d), got %d\n",
1843 SAMR_REJECT_COMPLEXITY, reject->reason);
1849 if (reject->reason == SAMR_REJECT_TOO_SHORT) {
1850 /* retry with adjusted size */
1851 return test_ChangePasswordUser3(p, tctx, account_string,
1852 dominfo->min_password_length,
1853 password, NULL, 0, false);
1857 } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1858 if (reject && reject->reason != SAMR_REJECT_OTHER) {
1859 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1860 SAMR_REJECT_OTHER, reject->reason);
1863 /* Perhaps the server has a 'min password age' set? */
1866 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3");
1867 *password = talloc_strdup(tctx, newpass);
1873 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_context *tctx,
1874 const char *account_string,
1875 struct policy_handle *handle,
1879 struct samr_ChangePasswordUser3 r;
1880 struct samr_SetUserInfo s;
1881 union samr_UserInfo u;
1882 DATA_BLOB session_key;
1883 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
1884 uint8_t confounder[16];
1885 struct MD5Context ctx;
1888 struct lsa_String server, account;
1889 struct samr_CryptPassword nt_pass;
1890 struct samr_Password nt_verifier;
1891 DATA_BLOB new_random_pass;
1894 uint8_t old_nt_hash[16], new_nt_hash[16];
1896 struct samr_DomInfo1 *dominfo = NULL;
1897 struct samr_ChangeReject *reject = NULL;
1899 new_random_pass = samr_very_rand_pass(tctx, 128);
1901 torture_assert(tctx, *password != NULL,
1902 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
1904 oldpass = *password;
1905 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1906 init_lsa_String(&account, account_string);
1908 s.in.user_handle = handle;
1914 u.info25.info.fields_present = SAMR_FIELD_PASSWORD;
1916 set_pw_in_buffer(u.info25.password.data, &new_random_pass);
1918 status = dcerpc_fetch_session_key(p, &session_key);
1919 if (!NT_STATUS_IS_OK(status)) {
1920 printf("SetUserInfo level %u - no session key - %s\n",
1921 s.in.level, nt_errstr(status));
1925 generate_random_buffer((uint8_t *)confounder, 16);
1928 MD5Update(&ctx, confounder, 16);
1929 MD5Update(&ctx, session_key.data, session_key.length);
1930 MD5Final(confounded_session_key.data, &ctx);
1932 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
1933 memcpy(&u.info25.password.data[516], confounder, 16);
1935 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
1937 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1938 if (!NT_STATUS_IS_OK(status)) {
1939 printf("SetUserInfo level %u failed - %s\n",
1940 s.in.level, nt_errstr(status));
1944 torture_comment(tctx, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
1946 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
1948 new_random_pass = samr_very_rand_pass(tctx, 128);
1950 mdfour(new_nt_hash, new_random_pass.data, new_random_pass.length);
1952 set_pw_in_buffer(nt_pass.data, &new_random_pass);
1953 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1954 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1956 r.in.server = &server;
1957 r.in.account = &account;
1958 r.in.nt_password = &nt_pass;
1959 r.in.nt_verifier = &nt_verifier;
1961 r.in.lm_password = NULL;
1962 r.in.lm_verifier = NULL;
1963 r.in.password3 = NULL;
1964 r.out.dominfo = &dominfo;
1965 r.out.reject = &reject;
1967 unix_to_nt_time(&t, time(NULL));
1969 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1971 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1972 if (reject && reject->reason != SAMR_REJECT_OTHER) {
1973 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1974 SAMR_REJECT_OTHER, reject->reason);
1977 /* Perhaps the server has a 'min password age' set? */
1979 } else if (!NT_STATUS_IS_OK(status)) {
1980 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
1984 newpass = samr_rand_pass(tctx, 128);
1986 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
1988 E_md4hash(newpass, new_nt_hash);
1990 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1991 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1992 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1994 r.in.server = &server;
1995 r.in.account = &account;
1996 r.in.nt_password = &nt_pass;
1997 r.in.nt_verifier = &nt_verifier;
1999 r.in.lm_password = NULL;
2000 r.in.lm_verifier = NULL;
2001 r.in.password3 = NULL;
2002 r.out.dominfo = &dominfo;
2003 r.out.reject = &reject;
2005 unix_to_nt_time(&t, time(NULL));
2007 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2009 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2010 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2011 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2012 SAMR_REJECT_OTHER, reject->reason);
2015 /* Perhaps the server has a 'min password age' set? */
2018 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3 (on second random password)");
2019 *password = talloc_strdup(tctx, newpass);
2026 static bool test_GetMembersInAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2027 struct policy_handle *alias_handle)
2029 struct samr_GetMembersInAlias r;
2030 struct lsa_SidArray sids;
2033 torture_comment(tctx, "Testing GetMembersInAlias\n");
2035 r.in.alias_handle = alias_handle;
2038 status = dcerpc_samr_GetMembersInAlias(p, tctx, &r);
2039 torture_assert_ntstatus_ok(tctx, status, "GetMembersInAlias");
2044 static bool test_AddMemberToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2045 struct policy_handle *alias_handle,
2046 const struct dom_sid *domain_sid)
2048 struct samr_AddAliasMember r;
2049 struct samr_DeleteAliasMember d;
2051 struct dom_sid *sid;
2053 sid = dom_sid_add_rid(tctx, domain_sid, 512);
2055 torture_comment(tctx, "testing AddAliasMember\n");
2056 r.in.alias_handle = alias_handle;
2059 status = dcerpc_samr_AddAliasMember(p, tctx, &r);
2060 torture_assert_ntstatus_ok(tctx, status, "AddAliasMember");
2062 d.in.alias_handle = alias_handle;
2065 status = dcerpc_samr_DeleteAliasMember(p, tctx, &d);
2066 torture_assert_ntstatus_ok(tctx, status, "DelAliasMember");
2071 static bool test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2072 struct policy_handle *alias_handle)
2074 struct samr_AddMultipleMembersToAlias a;
2075 struct samr_RemoveMultipleMembersFromAlias r;
2077 struct lsa_SidArray sids;
2079 torture_comment(tctx, "testing AddMultipleMembersToAlias\n");
2080 a.in.alias_handle = alias_handle;
2084 sids.sids = talloc_array(tctx, struct lsa_SidPtr, 3);
2086 sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2087 sids.sids[1].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-2");
2088 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-3");
2090 status = dcerpc_samr_AddMultipleMembersToAlias(p, tctx, &a);
2091 torture_assert_ntstatus_ok(tctx, status, "AddMultipleMembersToAlias");
2094 torture_comment(tctx, "testing RemoveMultipleMembersFromAlias\n");
2095 r.in.alias_handle = alias_handle;
2098 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2099 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2101 /* strange! removing twice doesn't give any error */
2102 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2103 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2105 /* but removing an alias that isn't there does */
2106 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-4");
2108 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2109 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, "RemoveMultipleMembersFromAlias");
2114 static bool test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2115 struct policy_handle *user_handle)
2117 struct samr_TestPrivateFunctionsUser r;
2120 torture_comment(tctx, "Testing TestPrivateFunctionsUser\n");
2122 r.in.user_handle = user_handle;
2124 status = dcerpc_samr_TestPrivateFunctionsUser(p, tctx, &r);
2125 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsUser");
2131 static bool test_user_ops(struct dcerpc_pipe *p,
2132 struct torture_context *tctx,
2133 struct policy_handle *user_handle,
2134 struct policy_handle *domain_handle,
2135 uint32_t base_acct_flags,
2136 const char *base_acct_name, enum torture_samr_choice which_ops)
2138 char *password = NULL;
2139 struct samr_QueryUserInfo q;
2145 const uint32_t password_fields[] = {
2146 SAMR_FIELD_PASSWORD,
2147 SAMR_FIELD_PASSWORD2,
2148 SAMR_FIELD_PASSWORD | SAMR_FIELD_PASSWORD2,
2152 status = test_LookupName(p, tctx, domain_handle, base_acct_name, &rid);
2153 if (!NT_STATUS_IS_OK(status)) {
2157 switch (which_ops) {
2158 case TORTURE_SAMR_USER_ATTRIBUTES:
2159 if (!test_QuerySecurity(p, tctx, user_handle)) {
2163 if (!test_QueryUserInfo(p, tctx, user_handle)) {
2167 if (!test_QueryUserInfo2(p, tctx, user_handle)) {
2171 if (!test_SetUserInfo(p, tctx, user_handle, base_acct_flags,
2176 if (!test_GetUserPwInfo(p, tctx, user_handle)) {
2180 if (!test_TestPrivateFunctionsUser(p, tctx, user_handle)) {
2184 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
2188 case TORTURE_SAMR_PASSWORDS:
2189 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
2190 char simple_pass[9];
2191 char *v = generate_random_str(tctx, 1);
2193 ZERO_STRUCT(simple_pass);
2194 memset(simple_pass, *v, sizeof(simple_pass) - 1);
2196 printf("Testing machine account password policy rules\n");
2198 /* Workstation trust accounts don't seem to need to honour password quality policy */
2199 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
2203 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
2207 /* reset again, to allow another 'user' password change */
2208 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
2212 /* Try a 'short' password */
2213 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
2217 /* Try a compleatly random password */
2218 if (!test_ChangePasswordRandomBytes(p, tctx, base_acct_name, user_handle, &password)) {
2223 for (i = 0; password_fields[i]; i++) {
2224 if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
2228 /* check it was set right */
2229 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
2234 for (i = 0; password_fields[i]; i++) {
2235 if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
2239 /* check it was set right */
2240 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
2245 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
2249 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
2253 q.in.user_handle = user_handle;
2256 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
2257 if (!NT_STATUS_IS_OK(status)) {
2258 printf("QueryUserInfo level %u failed - %s\n",
2259 q.in.level, nt_errstr(status));
2262 uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
2263 if ((q.out.info->info5.acct_flags) != expected_flags) {
2264 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2265 q.out.info->info5.acct_flags,
2269 if (q.out.info->info5.rid != rid) {
2270 printf("QuerUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
2271 q.out.info->info5.rid, rid);
2277 case TORTURE_SAMR_OTHER:
2278 /* We just need the account to exist */
2284 static bool test_alias_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
2285 struct policy_handle *alias_handle,
2286 const struct dom_sid *domain_sid)
2290 if (!test_QuerySecurity(p, tctx, alias_handle)) {
2294 if (!test_QueryAliasInfo(p, tctx, alias_handle)) {
2298 if (!test_SetAliasInfo(p, tctx, alias_handle)) {
2302 if (!test_AddMemberToAlias(p, tctx, alias_handle, domain_sid)) {
2306 if (torture_setting_bool(tctx, "samba4", false)) {
2307 printf("skipping MultipleMembers Alias tests against Samba4\n");
2311 if (!test_AddMultipleMembersToAlias(p, tctx, alias_handle)) {
2319 static bool test_DeleteUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2320 struct policy_handle *user_handle)
2322 struct samr_DeleteUser d;
2324 torture_comment(tctx, "Testing DeleteUser\n");
2326 d.in.user_handle = user_handle;
2327 d.out.user_handle = user_handle;
2329 status = dcerpc_samr_DeleteUser(p, tctx, &d);
2330 torture_assert_ntstatus_ok(tctx, status, "DeleteUser");
2335 bool test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2336 struct policy_handle *handle, const char *name)
2339 struct samr_DeleteUser d;
2340 struct policy_handle user_handle;
2343 status = test_LookupName(p, mem_ctx, handle, name, &rid);
2344 if (!NT_STATUS_IS_OK(status)) {
2348 status = test_OpenUser_byname(p, mem_ctx, handle, name, &user_handle);
2349 if (!NT_STATUS_IS_OK(status)) {
2353 d.in.user_handle = &user_handle;
2354 d.out.user_handle = &user_handle;
2355 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
2356 if (!NT_STATUS_IS_OK(status)) {
2363 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
2368 static bool test_DeleteGroup_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2369 struct policy_handle *handle, const char *name)
2372 struct samr_OpenGroup r;
2373 struct samr_DeleteDomainGroup d;
2374 struct policy_handle group_handle;
2377 status = test_LookupName(p, mem_ctx, handle, name, &rid);
2378 if (!NT_STATUS_IS_OK(status)) {
2382 r.in.domain_handle = handle;
2383 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2385 r.out.group_handle = &group_handle;
2386 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
2387 if (!NT_STATUS_IS_OK(status)) {
2391 d.in.group_handle = &group_handle;
2392 d.out.group_handle = &group_handle;
2393 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
2394 if (!NT_STATUS_IS_OK(status)) {
2401 printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
2406 static bool test_DeleteAlias_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2407 struct policy_handle *domain_handle, const char *name)
2410 struct samr_OpenAlias r;
2411 struct samr_DeleteDomAlias d;
2412 struct policy_handle alias_handle;
2415 printf("testing DeleteAlias_byname\n");
2417 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
2418 if (!NT_STATUS_IS_OK(status)) {
2422 r.in.domain_handle = domain_handle;
2423 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2425 r.out.alias_handle = &alias_handle;
2426 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
2427 if (!NT_STATUS_IS_OK(status)) {
2431 d.in.alias_handle = &alias_handle;
2432 d.out.alias_handle = &alias_handle;
2433 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
2434 if (!NT_STATUS_IS_OK(status)) {
2441 printf("DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
2445 static bool test_DeleteAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2446 struct policy_handle *alias_handle)
2448 struct samr_DeleteDomAlias d;
2451 printf("Testing DeleteAlias\n");
2453 d.in.alias_handle = alias_handle;
2454 d.out.alias_handle = alias_handle;
2456 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
2457 if (!NT_STATUS_IS_OK(status)) {
2458 printf("DeleteAlias failed - %s\n", nt_errstr(status));
2465 static bool test_CreateAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2466 struct policy_handle *domain_handle,
2467 struct policy_handle *alias_handle,
2468 const struct dom_sid *domain_sid)
2471 struct samr_CreateDomAlias r;
2472 struct lsa_String name;
2476 init_lsa_String(&name, TEST_ALIASNAME);
2477 r.in.domain_handle = domain_handle;
2478 r.in.alias_name = &name;
2479 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2480 r.out.alias_handle = alias_handle;
2483 printf("Testing CreateAlias (%s)\n", r.in.alias_name->string);
2485 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
2487 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
2488 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2489 printf("Server correctly refused create of '%s'\n", r.in.alias_name->string);
2492 printf("Server should have refused create of '%s', got %s instead\n", r.in.alias_name->string,
2498 if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
2499 if (!test_DeleteAlias_byname(p, tctx, domain_handle, r.in.alias_name->string)) {
2502 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
2505 if (!NT_STATUS_IS_OK(status)) {
2506 printf("CreateAlias failed - %s\n", nt_errstr(status));
2510 if (!test_alias_ops(p, tctx, alias_handle, domain_sid)) {
2517 static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2518 const char *acct_name,
2519 struct policy_handle *domain_handle, char **password)
2527 if (!test_ChangePasswordUser(p, mem_ctx, acct_name, domain_handle, password)) {
2531 if (!test_ChangePasswordUser2(p, mem_ctx, acct_name, password, 0, true)) {
2535 if (!test_OemChangePasswordUser2(p, mem_ctx, acct_name, domain_handle, password)) {
2539 /* test what happens when setting the old password again */
2540 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, *password, 0, true)) {
2545 char simple_pass[9];
2546 char *v = generate_random_str(mem_ctx, 1);
2548 ZERO_STRUCT(simple_pass);
2549 memset(simple_pass, *v, sizeof(simple_pass) - 1);
2551 /* test what happens when picking a simple password */
2552 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, simple_pass, 0, true)) {
2557 /* set samr_SetDomainInfo level 1 with min_length 5 */
2559 struct samr_QueryDomainInfo r;
2560 union samr_DomainInfo *info = NULL;
2561 struct samr_SetDomainInfo s;
2562 uint16_t len_old, len;
2563 uint32_t pwd_prop_old;
2564 int64_t min_pwd_age_old;
2569 r.in.domain_handle = domain_handle;
2573 printf("testing samr_QueryDomainInfo level 1\n");
2574 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2575 if (!NT_STATUS_IS_OK(status)) {
2579 s.in.domain_handle = domain_handle;
2583 /* remember the old min length, so we can reset it */
2584 len_old = s.in.info->info1.min_password_length;
2585 s.in.info->info1.min_password_length = len;
2586 pwd_prop_old = s.in.info->info1.password_properties;
2587 /* turn off password complexity checks for this test */
2588 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
2590 min_pwd_age_old = s.in.info->info1.min_password_age;
2591 s.in.info->info1.min_password_age = 0;
2593 printf("testing samr_SetDomainInfo level 1\n");
2594 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2595 if (!NT_STATUS_IS_OK(status)) {
2599 printf("calling test_ChangePasswordUser3 with too short password\n");
2601 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, len - 1, password, NULL, 0, true)) {
2605 s.in.info->info1.min_password_length = len_old;
2606 s.in.info->info1.password_properties = pwd_prop_old;
2607 s.in.info->info1.min_password_age = min_pwd_age_old;
2609 printf("testing samr_SetDomainInfo level 1\n");
2610 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2611 if (!NT_STATUS_IS_OK(status)) {
2619 struct samr_OpenUser r;
2620 struct samr_QueryUserInfo q;
2621 struct samr_LookupNames n;
2622 struct policy_handle user_handle;
2624 n.in.domain_handle = domain_handle;
2626 n.in.names = talloc_array(mem_ctx, struct lsa_String, 1);
2627 n.in.names[0].string = acct_name;
2629 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
2630 if (!NT_STATUS_IS_OK(status)) {
2631 printf("LookupNames failed - %s\n", nt_errstr(status));
2635 r.in.domain_handle = domain_handle;
2636 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2637 r.in.rid = n.out.rids.ids[0];
2638 r.out.user_handle = &user_handle;
2640 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
2641 if (!NT_STATUS_IS_OK(status)) {
2642 printf("OpenUser(%u) failed - %s\n", n.out.rids.ids[0], nt_errstr(status));
2646 q.in.user_handle = &user_handle;
2649 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
2650 if (!NT_STATUS_IS_OK(status)) {
2651 printf("QueryUserInfo failed - %s\n", nt_errstr(status));
2655 printf("calling test_ChangePasswordUser3 with too early password change\n");
2657 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL,
2658 q.out.info->info5.last_password_change, true)) {
2663 /* we change passwords twice - this has the effect of verifying
2664 they were changed correctly for the final call */
2665 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, true)) {
2669 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, true)) {
2676 static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2677 struct policy_handle *domain_handle,
2678 struct policy_handle *user_handle_out,
2679 struct dom_sid *domain_sid,
2680 enum torture_samr_choice which_ops)
2683 TALLOC_CTX *user_ctx;
2686 struct samr_CreateUser r;
2687 struct samr_QueryUserInfo q;
2688 struct samr_DeleteUser d;
2691 /* This call creates a 'normal' account - check that it really does */
2692 const uint32_t acct_flags = ACB_NORMAL;
2693 struct lsa_String name;
2696 struct policy_handle user_handle;
2697 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
2698 init_lsa_String(&name, TEST_ACCOUNT_NAME);
2700 r.in.domain_handle = domain_handle;
2701 r.in.account_name = &name;
2702 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2703 r.out.user_handle = &user_handle;
2706 printf("Testing CreateUser(%s)\n", r.in.account_name->string);
2708 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
2710 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
2711 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
2712 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
2715 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
2721 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
2722 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
2723 talloc_free(user_ctx);
2726 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
2728 if (!NT_STATUS_IS_OK(status)) {
2729 talloc_free(user_ctx);
2730 printf("CreateUser failed - %s\n", nt_errstr(status));
2733 q.in.user_handle = &user_handle;
2736 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
2737 if (!NT_STATUS_IS_OK(status)) {
2738 printf("QueryUserInfo level %u failed - %s\n",
2739 q.in.level, nt_errstr(status));
2742 if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
2743 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2744 q.out.info->info16.acct_flags,
2750 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
2751 acct_flags, name.string, which_ops)) {
2755 if (user_handle_out) {
2756 *user_handle_out = user_handle;
2758 printf("Testing DeleteUser (createuser test)\n");
2760 d.in.user_handle = &user_handle;
2761 d.out.user_handle = &user_handle;
2763 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
2764 if (!NT_STATUS_IS_OK(status)) {
2765 printf("DeleteUser failed - %s\n", nt_errstr(status));
2772 talloc_free(user_ctx);
2778 static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
2779 struct policy_handle *domain_handle,
2780 struct dom_sid *domain_sid,
2781 enum torture_samr_choice which_ops)
2784 struct samr_CreateUser2 r;
2785 struct samr_QueryUserInfo q;
2786 struct samr_DeleteUser d;
2787 struct policy_handle user_handle;
2789 struct lsa_String name;
2794 uint32_t acct_flags;
2795 const char *account_name;
2797 } account_types[] = {
2798 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
2799 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2800 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2801 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
2802 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2803 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2804 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
2805 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2806 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2807 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
2808 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
2809 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
2810 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2811 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2812 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
2815 for (i = 0; account_types[i].account_name; i++) {
2816 TALLOC_CTX *user_ctx;
2817 uint32_t acct_flags = account_types[i].acct_flags;
2818 uint32_t access_granted;
2819 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
2820 init_lsa_String(&name, account_types[i].account_name);
2822 r.in.domain_handle = domain_handle;
2823 r.in.account_name = &name;
2824 r.in.acct_flags = acct_flags;
2825 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2826 r.out.user_handle = &user_handle;
2827 r.out.access_granted = &access_granted;
2830 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
2832 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
2834 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
2835 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
2836 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
2839 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
2846 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
2847 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
2848 talloc_free(user_ctx);
2852 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
2855 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
2856 printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
2857 nt_errstr(status), nt_errstr(account_types[i].nt_status));
2861 if (NT_STATUS_IS_OK(status)) {
2862 q.in.user_handle = &user_handle;
2865 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
2866 if (!NT_STATUS_IS_OK(status)) {
2867 printf("QueryUserInfo level %u failed - %s\n",
2868 q.in.level, nt_errstr(status));
2871 uint32_t expected_flags = (acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
2872 if (acct_flags == ACB_NORMAL) {
2873 expected_flags |= ACB_PW_EXPIRED;
2875 if ((q.out.info->info5.acct_flags) != expected_flags) {
2876 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2877 q.out.info->info5.acct_flags,
2881 switch (acct_flags) {
2883 if (q.out.info->info5.primary_gid != DOMAIN_RID_DCS) {
2884 printf("QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n",
2885 DOMAIN_RID_DCS, q.out.info->info5.primary_gid);
2890 if (q.out.info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
2891 printf("QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
2892 DOMAIN_RID_DOMAIN_MEMBERS, q.out.info->info5.primary_gid);
2897 if (q.out.info->info5.primary_gid != DOMAIN_RID_USERS) {
2898 printf("QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n",
2899 DOMAIN_RID_USERS, q.out.info->info5.primary_gid);
2906 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
2907 acct_flags, name.string, which_ops)) {
2911 printf("Testing DeleteUser (createuser2 test)\n");
2913 d.in.user_handle = &user_handle;
2914 d.out.user_handle = &user_handle;
2916 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
2917 if (!NT_STATUS_IS_OK(status)) {
2918 printf("DeleteUser failed - %s\n", nt_errstr(status));
2922 talloc_free(user_ctx);
2928 static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2929 struct policy_handle *handle)
2932 struct samr_QueryAliasInfo r;
2933 uint16_t levels[] = {1, 2, 3};
2937 for (i=0;i<ARRAY_SIZE(levels);i++) {
2938 printf("Testing QueryAliasInfo level %u\n", levels[i]);
2940 r.in.alias_handle = handle;
2941 r.in.level = levels[i];
2943 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
2944 if (!NT_STATUS_IS_OK(status)) {
2945 printf("QueryAliasInfo level %u failed - %s\n",
2946 levels[i], nt_errstr(status));
2954 static bool test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2955 struct policy_handle *handle)
2958 struct samr_QueryGroupInfo r;
2959 uint16_t levels[] = {1, 2, 3, 4, 5};
2963 for (i=0;i<ARRAY_SIZE(levels);i++) {
2964 printf("Testing QueryGroupInfo level %u\n", levels[i]);
2966 r.in.group_handle = handle;
2967 r.in.level = levels[i];
2969 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
2970 if (!NT_STATUS_IS_OK(status)) {
2971 printf("QueryGroupInfo level %u failed - %s\n",
2972 levels[i], nt_errstr(status));
2980 static bool test_QueryGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2981 struct policy_handle *handle)
2984 struct samr_QueryGroupMember r;
2985 struct samr_RidTypeArray *rids = NULL;
2988 printf("Testing QueryGroupMember\n");
2990 r.in.group_handle = handle;
2993 status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &r);
2994 if (!NT_STATUS_IS_OK(status)) {
2995 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
3003 static bool test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3004 struct policy_handle *handle)
3007 struct samr_QueryGroupInfo r;
3008 struct samr_SetGroupInfo s;
3009 uint16_t levels[] = {1, 2, 3, 4};
3010 uint16_t set_ok[] = {0, 1, 1, 1};
3014 for (i=0;i<ARRAY_SIZE(levels);i++) {
3015 printf("Testing QueryGroupInfo level %u\n", levels[i]);
3017 r.in.group_handle = handle;
3018 r.in.level = levels[i];
3020 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
3021 if (!NT_STATUS_IS_OK(status)) {
3022 printf("QueryGroupInfo level %u failed - %s\n",
3023 levels[i], nt_errstr(status));
3027 printf("Testing SetGroupInfo level %u\n", levels[i]);
3029 s.in.group_handle = handle;
3030 s.in.level = levels[i];
3031 s.in.info = r.out.info;
3034 /* disabled this, as it changes the name only from the point of view of samr,
3035 but leaves the name from the point of view of w2k3 internals (and ldap). This means
3036 the name is still reserved, so creating the old name fails, but deleting by the old name
3038 if (s.in.level == 2) {
3039 init_lsa_String(&s.in.info->string, "NewName");
3043 if (s.in.level == 4) {
3044 init_lsa_String(&s.in.info->description, "test description");
3047 status = dcerpc_samr_SetGroupInfo(p, mem_ctx, &s);
3049 if (!NT_STATUS_IS_OK(status)) {
3050 printf("SetGroupInfo level %u failed - %s\n",
3051 r.in.level, nt_errstr(status));
3056 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
3057 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
3058 r.in.level, nt_errstr(status));
3068 static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3069 struct policy_handle *handle)
3072 struct samr_QueryUserInfo r;
3073 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
3074 11, 12, 13, 14, 16, 17, 20, 21};
3078 for (i=0;i<ARRAY_SIZE(levels);i++) {
3079 printf("Testing QueryUserInfo level %u\n", levels[i]);
3081 r.in.user_handle = handle;
3082 r.in.level = levels[i];
3084 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
3085 if (!NT_STATUS_IS_OK(status)) {
3086 printf("QueryUserInfo level %u failed - %s\n",
3087 levels[i], nt_errstr(status));
3095 static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3096 struct policy_handle *handle)
3099 struct samr_QueryUserInfo2 r;
3100 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
3101 11, 12, 13, 14, 16, 17, 20, 21};
3105 for (i=0;i<ARRAY_SIZE(levels);i++) {
3106 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
3108 r.in.user_handle = handle;
3109 r.in.level = levels[i];
3111 status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r);
3112 if (!NT_STATUS_IS_OK(status)) {
3113 printf("QueryUserInfo2 level %u failed - %s\n",
3114 levels[i], nt_errstr(status));
3122 static bool test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3123 struct policy_handle *handle, uint32_t rid)
3126 struct samr_OpenUser r;
3127 struct policy_handle user_handle;
3130 printf("Testing OpenUser(%u)\n", rid);
3132 r.in.domain_handle = handle;
3133 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3135 r.out.user_handle = &user_handle;
3137 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3138 if (!NT_STATUS_IS_OK(status)) {
3139 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
3143 if (!test_QuerySecurity(p, mem_ctx, &user_handle)) {
3147 if (!test_QueryUserInfo(p, mem_ctx, &user_handle)) {
3151 if (!test_QueryUserInfo2(p, mem_ctx, &user_handle)) {
3155 if (!test_GetUserPwInfo(p, mem_ctx, &user_handle)) {
3159 if (!test_GetGroupsForUser(p,mem_ctx, &user_handle)) {
3163 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
3170 static bool test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3171 struct policy_handle *handle, uint32_t rid)
3174 struct samr_OpenGroup r;
3175 struct policy_handle group_handle;
3178 printf("Testing OpenGroup(%u)\n", rid);
3180 r.in.domain_handle = handle;
3181 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3183 r.out.group_handle = &group_handle;
3185 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
3186 if (!NT_STATUS_IS_OK(status)) {
3187 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
3191 if (!test_QuerySecurity(p, mem_ctx, &group_handle)) {
3195 if (!test_QueryGroupInfo(p, mem_ctx, &group_handle)) {
3199 if (!test_QueryGroupMember(p, mem_ctx, &group_handle)) {
3203 if (!test_samr_handle_Close(p, mem_ctx, &group_handle)) {
3210 static bool test_OpenAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
3211 struct policy_handle *handle, uint32_t rid)
3214 struct samr_OpenAlias r;
3215 struct policy_handle alias_handle;
3218 torture_comment(tctx, "Testing OpenAlias(%u)\n", rid);
3220 r.in.domain_handle = handle;
3221 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3223 r.out.alias_handle = &alias_handle;
3225 status = dcerpc_samr_OpenAlias(p, tctx, &r);
3226 if (!NT_STATUS_IS_OK(status)) {
3227 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
3231 if (!test_QuerySecurity(p, tctx, &alias_handle)) {
3235 if (!test_QueryAliasInfo(p, tctx, &alias_handle)) {
3239 if (!test_GetMembersInAlias(p, tctx, &alias_handle)) {
3243 if (!test_samr_handle_Close(p, tctx, &alias_handle)) {
3250 static bool check_mask(struct dcerpc_pipe *p, struct torture_context *tctx,
3251 struct policy_handle *handle, uint32_t rid,
3252 uint32_t acct_flag_mask)
3255 struct samr_OpenUser r;
3256 struct samr_QueryUserInfo q;
3257 struct policy_handle user_handle;
3260 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
3262 r.in.domain_handle = handle;
3263 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3265 r.out.user_handle = &user_handle;
3267 status = dcerpc_samr_OpenUser(p, tctx, &r);
3268 if (!NT_STATUS_IS_OK(status)) {
3269 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
3273 q.in.user_handle = &user_handle;
3276 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
3277 if (!NT_STATUS_IS_OK(status)) {
3278 printf("QueryUserInfo level 16 failed - %s\n",
3282 if ((acct_flag_mask & q.out.info->info16.acct_flags) == 0) {
3283 printf("Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
3284 acct_flag_mask, q.out.info->info16.acct_flags, rid);
3289 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
3296 static bool test_EnumDomainUsers(struct dcerpc_pipe *p, struct torture_context *tctx,
3297 struct policy_handle *handle)
3299 NTSTATUS status = STATUS_MORE_ENTRIES;
3300 struct samr_EnumDomainUsers r;
3301 uint32_t mask, resume_handle=0;
3304 struct samr_LookupNames n;
3305 struct samr_LookupRids lr ;
3306 struct lsa_Strings names;
3307 struct samr_Ids types;
3309 uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
3310 ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
3311 ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
3314 printf("Testing EnumDomainUsers\n");
3316 for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
3317 r.in.domain_handle = handle;
3318 r.in.resume_handle = &resume_handle;
3319 r.in.acct_flags = mask = masks[mask_idx];
3320 r.in.max_size = (uint32_t)-1;
3321 r.out.resume_handle = &resume_handle;
3323 status = dcerpc_samr_EnumDomainUsers(p, tctx, &r);
3324 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
3325 !NT_STATUS_IS_OK(status)) {
3326 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
3330 torture_assert(tctx, r.out.sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
3332 if (r.out.sam->count == 0) {
3336 for (i=0;i<r.out.sam->count;i++) {
3338 if (!check_mask(p, tctx, handle, r.out.sam->entries[i].idx, mask)) {
3341 } else if (!test_OpenUser(p, tctx, handle, r.out.sam->entries[i].idx)) {
3347 printf("Testing LookupNames\n");
3348 n.in.domain_handle = handle;
3349 n.in.num_names = r.out.sam->count;
3350 n.in.names = talloc_array(tctx, struct lsa_String, r.out.sam->count);
3351 for (i=0;i<r.out.sam->count;i++) {
3352 n.in.names[i].string = r.out.sam->entries[i].name.string;
3354 status = dcerpc_samr_LookupNames(p, tctx, &n);
3355 if (!NT_STATUS_IS_OK(status)) {
3356 printf("LookupNames failed - %s\n", nt_errstr(status));
3361 printf("Testing LookupRids\n");
3362 lr.in.domain_handle = handle;
3363 lr.in.num_rids = r.out.sam->count;
3364 lr.in.rids = talloc_array(tctx, uint32_t, r.out.sam->count);
3365 lr.out.names = &names;
3366 lr.out.types = &types;
3367 for (i=0;i<r.out.sam->count;i++) {
3368 lr.in.rids[i] = r.out.sam->entries[i].idx;
3370 status = dcerpc_samr_LookupRids(p, tctx, &lr);
3371 torture_assert_ntstatus_ok(tctx, status, "LookupRids");
3377 try blasting the server with a bunch of sync requests
3379 static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, struct torture_context *tctx,
3380 struct policy_handle *handle)
3383 struct samr_EnumDomainUsers r;
3384 uint32_t resume_handle=0;
3386 #define ASYNC_COUNT 100
3387 struct rpc_request *req[ASYNC_COUNT];
3389 if (!torture_setting_bool(tctx, "dangerous", false)) {
3390 torture_skip(tctx, "samr async test disabled - enable dangerous tests to use\n");
3393 torture_comment(tctx, "Testing EnumDomainUsers_async\n");
3395 r.in.domain_handle = handle;
3396 r.in.resume_handle = &resume_handle;
3397 r.in.acct_flags = 0;
3398 r.in.max_size = (uint32_t)-1;
3399 r.out.resume_handle = &resume_handle;
3401 for (i=0;i<ASYNC_COUNT;i++) {
3402 req[i] = dcerpc_samr_EnumDomainUsers_send(p, tctx, &r);
3405 for (i=0;i<ASYNC_COUNT;i++) {
3406 status = dcerpc_ndr_request_recv(req[i]);
3407 if (!NT_STATUS_IS_OK(status)) {
3408 printf("EnumDomainUsers[%d] failed - %s\n",
3409 i, nt_errstr(status));
3414 torture_comment(tctx, "%d async requests OK\n", i);
3419 static bool test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3420 struct policy_handle *handle)
3423 struct samr_EnumDomainGroups r;
3424 uint32_t resume_handle=0;
3428 printf("Testing EnumDomainGroups\n");
3430 r.in.domain_handle = handle;
3431 r.in.resume_handle = &resume_handle;
3432 r.in.max_size = (uint32_t)-1;
3433 r.out.resume_handle = &resume_handle;
3435 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
3436 if (!NT_STATUS_IS_OK(status)) {
3437 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
3445 for (i=0;i<r.out.sam->count;i++) {
3446 if (!test_OpenGroup(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
3454 static bool test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3455 struct policy_handle *handle)
3458 struct samr_EnumDomainAliases r;
3459 uint32_t resume_handle=0;
3460 struct samr_SamArray *sam = NULL;
3461 uint32_t num_entries = 0;
3465 printf("Testing EnumDomainAliases\n");
3467 r.in.domain_handle = handle;
3468 r.in.resume_handle = &resume_handle;
3469 r.in.max_size = (uint32_t)-1;
3471 r.out.num_entries = &num_entries;
3472 r.out.resume_handle = &resume_handle;
3474 status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
3475 if (!NT_STATUS_IS_OK(status)) {
3476 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
3484 for (i=0;i<sam->count;i++) {
3485 if (!test_OpenAlias(p, mem_ctx, handle, sam->entries[i].idx)) {
3493 static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3494 struct policy_handle *handle)
3497 struct samr_GetDisplayEnumerationIndex r;
3499 uint16_t levels[] = {1, 2, 3, 4, 5};
3500 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
3501 struct lsa_String name;
3505 for (i=0;i<ARRAY_SIZE(levels);i++) {
3506 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
3508 init_lsa_String(&name, TEST_ACCOUNT_NAME);
3510 r.in.domain_handle = handle;
3511 r.in.level = levels[i];
3515 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
3518 !NT_STATUS_IS_OK(status) &&
3519 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3520 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
3521 levels[i], nt_errstr(status));
3525 init_lsa_String(&name, "zzzzzzzz");
3527 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
3529 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3530 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
3531 levels[i], nt_errstr(status));
3539 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3540 struct policy_handle *handle)
3543 struct samr_GetDisplayEnumerationIndex2 r;
3545 uint16_t levels[] = {1, 2, 3, 4, 5};
3546 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
3547 struct lsa_String name;
3551 for (i=0;i<ARRAY_SIZE(levels);i++) {
3552 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
3554 init_lsa_String(&name, TEST_ACCOUNT_NAME);
3556 r.in.domain_handle = handle;
3557 r.in.level = levels[i];
3561 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
3563 !NT_STATUS_IS_OK(status) &&
3564 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3565 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
3566 levels[i], nt_errstr(status));
3570 init_lsa_String(&name, "zzzzzzzz");
3572 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
3573 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3574 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
3575 levels[i], nt_errstr(status));
3583 #define STRING_EQUAL_QUERY(s1, s2, user) \
3584 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
3585 /* odd, but valid */ \
3586 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
3587 printf("%s mismatch for %s: %s != %s (%s)\n", \
3588 #s1, user.string, s1.string, s2.string, __location__); \
3591 #define INT_EQUAL_QUERY(s1, s2, user) \
3593 printf("%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
3594 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
3598 static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3599 struct samr_QueryDisplayInfo *querydisplayinfo,
3600 bool *seen_testuser)
3602 struct samr_OpenUser r;
3603 struct samr_QueryUserInfo q;
3604 struct policy_handle user_handle;
3607 r.in.domain_handle = querydisplayinfo->in.domain_handle;
3608 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3609 for (i = 0; ; i++) {
3610 switch (querydisplayinfo->in.level) {
3612 if (i >= querydisplayinfo->out.info->info1.count) {
3615 r.in.rid = querydisplayinfo->out.info->info1.entries[i].rid;
3618 if (i >= querydisplayinfo->out.info->info2.count) {
3621 r.in.rid = querydisplayinfo->out.info->info2.entries[i].rid;
3627 /* Not interested in validating just the account name */
3631 r.out.user_handle = &user_handle;
3633 switch (querydisplayinfo->in.level) {
3636 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3637 if (!NT_STATUS_IS_OK(status)) {
3638 printf("OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(status));
3643 q.in.user_handle = &user_handle;
3645 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
3646 if (!NT_STATUS_IS_OK(status)) {
3647 printf("QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(status));
3651 switch (querydisplayinfo->in.level) {
3653 if (seen_testuser && strcmp(q.out.info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
3654 *seen_testuser = true;
3656 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].full_name,
3657 q.out.info->info21.full_name, q.out.info->info21.account_name);
3658 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].account_name,
3659 q.out.info->info21.account_name, q.out.info->info21.account_name);
3660 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].description,
3661 q.out.info->info21.description, q.out.info->info21.account_name);
3662 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].rid,
3663 q.out.info->info21.rid, q.out.info->info21.account_name);
3664 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].acct_flags,
3665 q.out.info->info21.acct_flags, q.out.info->info21.account_name);
3669 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].account_name,
3670 q.out.info->info21.account_name, q.out.info->info21.account_name);
3671 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].description,
3672 q.out.info->info21.description, q.out.info->info21.account_name);
3673 INT_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].rid,
3674 q.out.info->info21.rid, q.out.info->info21.account_name);
3675 INT_EQUAL_QUERY((querydisplayinfo->out.info->info2.entries[i].acct_flags & ~ACB_NORMAL),
3676 q.out.info->info21.acct_flags, q.out.info->info21.account_name);
3678 if (!(querydisplayinfo->out.info->info2.entries[i].acct_flags & ACB_NORMAL)) {
3679 printf("Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
3680 q.out.info->info21.account_name.string);
3683 if (!(q.out.info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
3684 printf("Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
3685 q.out.info->info21.account_name.string,
3686 querydisplayinfo->out.info->info2.entries[i].acct_flags,
3687 q.out.info->info21.acct_flags);
3694 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
3701 static bool test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3702 struct policy_handle *handle)
3705 struct samr_QueryDisplayInfo r;
3706 struct samr_QueryDomainInfo dom_info;
3707 union samr_DomainInfo *info = NULL;
3709 uint16_t levels[] = {1, 2, 3, 4, 5};
3711 bool seen_testuser = false;
3712 uint32_t total_size;
3713 uint32_t returned_size;
3714 union samr_DispInfo disp_info;
3717 for (i=0;i<ARRAY_SIZE(levels);i++) {
3718 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
3721 status = STATUS_MORE_ENTRIES;
3722 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
3723 r.in.domain_handle = handle;
3724 r.in.level = levels[i];
3725 r.in.max_entries = 2;
3726 r.in.buf_size = (uint32_t)-1;
3727 r.out.total_size = &total_size;
3728 r.out.returned_size = &returned_size;
3729 r.out.info = &disp_info;
3731 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
3732 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(status)) {
3733 printf("QueryDisplayInfo level %u failed - %s\n",
3734 levels[i], nt_errstr(status));
3737 switch (r.in.level) {
3739 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, &seen_testuser)) {
3742 r.in.start_idx += r.out.info->info1.count;
3745 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, NULL)) {
3748 r.in.start_idx += r.out.info->info2.count;
3751 r.in.start_idx += r.out.info->info3.count;
3754 r.in.start_idx += r.out.info->info4.count;
3757 r.in.start_idx += r.out.info->info5.count;
3761 dom_info.in.domain_handle = handle;
3762 dom_info.in.level = 2;
3763 dom_info.out.info = &info;
3765 /* Check number of users returned is correct */
3766 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &dom_info);
3767 if (!NT_STATUS_IS_OK(status)) {
3768 printf("QueryDomainInfo level %u failed - %s\n",
3769 r.in.level, nt_errstr(status));
3773 switch (r.in.level) {
3776 if (info->general.num_users < r.in.start_idx) {
3777 printf("QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
3778 r.in.start_idx, info->general.num_groups,
3779 info->general.domain_name.string);
3782 if (!seen_testuser) {
3783 struct policy_handle user_handle;
3784 if (NT_STATUS_IS_OK(test_OpenUser_byname(p, mem_ctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
3785 printf("Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
3786 info->general.domain_name.string);
3788 test_samr_handle_Close(p, mem_ctx, &user_handle);
3794 if (info->general.num_groups != r.in.start_idx) {
3795 printf("QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
3796 r.in.start_idx, info->general.num_groups,
3797 info->general.domain_name.string);
3809 static bool test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3810 struct policy_handle *handle)
3813 struct samr_QueryDisplayInfo2 r;
3815 uint16_t levels[] = {1, 2, 3, 4, 5};
3817 uint32_t total_size;
3818 uint32_t returned_size;
3819 union samr_DispInfo info;
3821 for (i=0;i<ARRAY_SIZE(levels);i++) {
3822 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
3824 r.in.domain_handle = handle;
3825 r.in.level = levels[i];
3827 r.in.max_entries = 1000;
3828 r.in.buf_size = (uint32_t)-1;
3829 r.out.total_size = &total_size;
3830 r.out.returned_size = &returned_size;
3833 status = dcerpc_samr_QueryDisplayInfo2(p, mem_ctx, &r);
3834 if (!NT_STATUS_IS_OK(status)) {
3835 printf("QueryDisplayInfo2 level %u failed - %s\n",
3836 levels[i], nt_errstr(status));
3844 static bool test_QueryDisplayInfo3(struct dcerpc_pipe *p, struct torture_context *tctx,
3845 struct policy_handle *handle)
3848 struct samr_QueryDisplayInfo3 r;
3850 uint16_t levels[] = {1, 2, 3, 4, 5};
3852 uint32_t total_size;
3853 uint32_t returned_size;
3854 union samr_DispInfo info;
3856 for (i=0;i<ARRAY_SIZE(levels);i++) {
3857 torture_comment(tctx, "Testing QueryDisplayInfo3 level %u\n", levels[i]);
3859 r.in.domain_handle = handle;
3860 r.in.level = levels[i];
3862 r.in.max_entries = 1000;
3863 r.in.buf_size = (uint32_t)-1;
3864 r.out.total_size = &total_size;
3865 r.out.returned_size = &returned_size;
3868 status = dcerpc_samr_QueryDisplayInfo3(p, tctx, &r);
3869 if (!NT_STATUS_IS_OK(status)) {
3870 printf("QueryDisplayInfo3 level %u failed - %s\n",
3871 levels[i], nt_errstr(status));
3880 static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3881 struct policy_handle *handle)
3884 struct samr_QueryDisplayInfo r;
3886 uint32_t total_size;
3887 uint32_t returned_size;
3888 union samr_DispInfo info;
3890 printf("Testing QueryDisplayInfo continuation\n");
3892 r.in.domain_handle = handle;
3895 r.in.max_entries = 1;
3896 r.in.buf_size = (uint32_t)-1;
3897 r.out.total_size = &total_size;
3898 r.out.returned_size = &returned_size;
3902 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
3903 if (NT_STATUS_IS_OK(status) && *r.out.returned_size != 0) {
3904 if (r.out.info->info1.entries[0].idx != r.in.start_idx + 1) {
3905 printf("expected idx %d but got %d\n",
3907 r.out.info->info1.entries[0].idx);
3911 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
3912 !NT_STATUS_IS_OK(status)) {
3913 printf("QueryDisplayInfo level %u failed - %s\n",
3914 r.in.level, nt_errstr(status));
3919 } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
3920 NT_STATUS_IS_OK(status)) &&
3921 *r.out.returned_size != 0);
3926 static bool test_QueryDomainInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
3927 struct policy_handle *handle)
3930 struct samr_QueryDomainInfo r;
3931 union samr_DomainInfo *info = NULL;
3932 struct samr_SetDomainInfo s;
3933 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
3934 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
3937 const char *domain_comment = talloc_asprintf(tctx,
3938 "Tortured by Samba4 RPC-SAMR: %s",
3939 timestring(tctx, time(NULL)));
3941 s.in.domain_handle = handle;
3943 s.in.info = talloc(tctx, union samr_DomainInfo);
3945 s.in.info->oem.oem_information.string = domain_comment;
3946 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
3947 if (!NT_STATUS_IS_OK(status)) {
3948 printf("SetDomainInfo level %u (set comment) failed - %s\n",
3949 r.in.level, nt_errstr(status));
3953 for (i=0;i<ARRAY_SIZE(levels);i++) {
3954 torture_comment(tctx, "Testing QueryDomainInfo level %u\n", levels[i]);
3956 r.in.domain_handle = handle;
3957 r.in.level = levels[i];
3960 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
3961 if (!NT_STATUS_IS_OK(status)) {
3962 printf("QueryDomainInfo level %u failed - %s\n",
3963 r.in.level, nt_errstr(status));
3968 switch (levels[i]) {
3970 if (strcmp(info->general.oem_information.string, domain_comment) != 0) {
3971 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
3972 levels[i], info->general.oem_information.string, domain_comment);
3975 if (!info->general.primary.string) {
3976 printf("QueryDomainInfo level %u returned no PDC name\n",
3979 } else if (info->general.role == SAMR_ROLE_DOMAIN_PDC) {
3980 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), info->general.primary.string) != 0) {
3981 printf("QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
3982 levels[i], info->general.primary.string, dcerpc_server_name(p));
3987 if (strcmp(info->oem.oem_information.string, domain_comment) != 0) {
3988 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
3989 levels[i], info->oem.oem_information.string, domain_comment);
3994 if (!info->info6.primary.string) {
3995 printf("QueryDomainInfo level %u returned no PDC name\n",
4001 if (strcmp(info->general2.general.oem_information.string, domain_comment) != 0) {
4002 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
4003 levels[i], info->general2.general.oem_information.string, domain_comment);
4009 torture_comment(tctx, "Testing SetDomainInfo level %u\n", levels[i]);
4011 s.in.domain_handle = handle;
4012 s.in.level = levels[i];
4015 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
4017 if (!NT_STATUS_IS_OK(status)) {
4018 printf("SetDomainInfo level %u failed - %s\n",
4019 r.in.level, nt_errstr(status));
4024 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
4025 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
4026 r.in.level, nt_errstr(status));
4032 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
4033 if (!NT_STATUS_IS_OK(status)) {
4034 printf("QueryDomainInfo level %u failed - %s\n",
4035 r.in.level, nt_errstr(status));
4045 static bool test_QueryDomainInfo2(struct dcerpc_pipe *p, struct torture_context *tctx,
4046 struct policy_handle *handle)
4049 struct samr_QueryDomainInfo2 r;
4050 union samr_DomainInfo *info = NULL;
4051 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
4055 for (i=0;i<ARRAY_SIZE(levels);i++) {
4056 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
4058 r.in.domain_handle = handle;
4059 r.in.level = levels[i];
4062 status = dcerpc_samr_QueryDomainInfo2(p, tctx, &r);
4063 if (!NT_STATUS_IS_OK(status)) {
4064 printf("QueryDomainInfo2 level %u failed - %s\n",
4065 r.in.level, nt_errstr(status));
4074 /* Test whether querydispinfo level 5 and enumdomgroups return the same
4075 set of group names. */
4076 static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx,
4077 struct policy_handle *handle)
4079 struct samr_EnumDomainGroups q1;
4080 struct samr_QueryDisplayInfo q2;
4082 uint32_t resume_handle=0;
4085 uint32_t total_size;
4086 uint32_t returned_size;
4087 union samr_DispInfo info;
4090 const char **names = NULL;
4092 torture_comment(tctx, "Testing coherency of querydispinfo vs enumdomgroups\n");
4094 q1.in.domain_handle = handle;
4095 q1.in.resume_handle = &resume_handle;
4097 q1.out.resume_handle = &resume_handle;
4099 status = STATUS_MORE_ENTRIES;
4100 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
4101 status = dcerpc_samr_EnumDomainGroups(p, tctx, &q1);
4103 if (!NT_STATUS_IS_OK(status) &&
4104 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
4107 for (i=0; i<q1.out.num_entries; i++) {
4108 add_string_to_array(tctx,
4109 q1.out.sam->entries[i].name.string,
4110 &names, &num_names);
4114 torture_assert_ntstatus_ok(tctx, status, "EnumDomainGroups");
4116 torture_assert(tctx, q1.out.sam, "EnumDomainGroups failed to return q1.out.sam");
4118 q2.in.domain_handle = handle;
4120 q2.in.start_idx = 0;
4121 q2.in.max_entries = 5;
4122 q2.in.buf_size = (uint32_t)-1;
4123 q2.out.total_size = &total_size;
4124 q2.out.returned_size = &returned_size;
4125 q2.out.info = &info;
4127 status = STATUS_MORE_ENTRIES;
4128 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
4129 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &q2);
4131 if (!NT_STATUS_IS_OK(status) &&
4132 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
4135 for (i=0; i<q2.out.info->info5.count; i++) {
4137 const char *name = q2.out.info->info5.entries[i].account_name.string;
4139 for (j=0; j<num_names; j++) {
4140 if (names[j] == NULL)
4142 if (strequal(names[j], name)) {
4150 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
4155 q2.in.start_idx += q2.out.info->info5.count;
4158 if (!NT_STATUS_IS_OK(status)) {
4159 printf("QueryDisplayInfo level 5 failed - %s\n",
4164 for (i=0; i<num_names; i++) {
4165 if (names[i] != NULL) {
4166 printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
4175 static bool test_DeleteDomainGroup(struct dcerpc_pipe *p, struct torture_context *tctx,
4176 struct policy_handle *group_handle)
4178 struct samr_DeleteDomainGroup d;
4181 torture_comment(tctx, "Testing DeleteDomainGroup\n");
4183 d.in.group_handle = group_handle;
4184 d.out.group_handle = group_handle;
4186 status = dcerpc_samr_DeleteDomainGroup(p, tctx, &d);
4187 torture_assert_ntstatus_ok(tctx, status, "DeleteDomainGroup");
4192 static bool test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
4193 struct policy_handle *domain_handle)
4195 struct samr_TestPrivateFunctionsDomain r;
4199 torture_comment(tctx, "Testing TestPrivateFunctionsDomain\n");
4201 r.in.domain_handle = domain_handle;
4203 status = dcerpc_samr_TestPrivateFunctionsDomain(p, tctx, &r);
4204 torture_assert_ntstatus_equal(tctx, NT_STATUS_NOT_IMPLEMENTED, status, "TestPrivateFunctionsDomain");
4209 static bool test_RidToSid(struct dcerpc_pipe *p, struct torture_context *tctx,
4210 struct dom_sid *domain_sid,
4211 struct policy_handle *domain_handle)
4213 struct samr_RidToSid r;
4216 struct dom_sid *calc_sid, *out_sid;
4217 int rids[] = { 0, 42, 512, 10200 };
4220 for (i=0;i<ARRAY_SIZE(rids);i++) {
4221 torture_comment(tctx, "Testing RidToSid\n");
4223 calc_sid = dom_sid_dup(tctx, domain_sid);
4224 r.in.domain_handle = domain_handle;
4226 r.out.sid = &out_sid;
4228 status = dcerpc_samr_RidToSid(p, tctx, &r);
4229 if (!NT_STATUS_IS_OK(status)) {
4230 printf("RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
4233 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
4235 if (!dom_sid_equal(calc_sid, out_sid)) {
4236 printf("RidToSid for %d failed - got %s, expected %s\n", rids[i],
4237 dom_sid_string(tctx, out_sid),
4238 dom_sid_string(tctx, calc_sid));
4247 static bool test_GetBootKeyInformation(struct dcerpc_pipe *p, struct torture_context *tctx,
4248 struct policy_handle *domain_handle)
4250 struct samr_GetBootKeyInformation r;
4253 uint32_t unknown = 0;
4255 torture_comment(tctx, "Testing GetBootKeyInformation\n");
4257 r.in.domain_handle = domain_handle;
4258 r.out.unknown = &unknown;
4260 status = dcerpc_samr_GetBootKeyInformation(p, tctx, &r);
4261 if (!NT_STATUS_IS_OK(status)) {
4262 /* w2k3 seems to fail this sometimes and pass it sometimes */
4263 torture_comment(tctx, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
4269 static bool test_AddGroupMember(struct dcerpc_pipe *p, struct torture_context *tctx,
4270 struct policy_handle *domain_handle,
4271 struct policy_handle *group_handle)
4274 struct samr_AddGroupMember r;
4275 struct samr_DeleteGroupMember d;
4276 struct samr_QueryGroupMember q;
4277 struct samr_RidTypeArray *rids = NULL;
4278 struct samr_SetMemberAttributesOfGroup s;
4281 status = test_LookupName(p, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
4282 torture_assert_ntstatus_ok(tctx, status, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME);
4284 r.in.group_handle = group_handle;
4286 r.in.flags = 0; /* ??? */
4288 torture_comment(tctx, "Testing AddGroupMember and DeleteGroupMember\n");
4290 d.in.group_handle = group_handle;
4293 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
4294 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_NOT_IN_GROUP, status, "DeleteGroupMember");
4296 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4297 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
4299 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4300 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_IN_GROUP, status, "AddGroupMember");
4302 if (torture_setting_bool(tctx, "samba4", false)) {
4303 torture_comment(tctx, "skipping SetMemberAttributesOfGroup test against Samba4\n");
4305 /* this one is quite strange. I am using random inputs in the
4306 hope of triggering an error that might give us a clue */
4308 s.in.group_handle = group_handle;
4309 s.in.unknown1 = random();
4310 s.in.unknown2 = random();
4312 status = dcerpc_samr_SetMemberAttributesOfGroup(p, tctx, &s);
4313 torture_assert_ntstatus_ok(tctx, status, "SetMemberAttributesOfGroup");
4316 q.in.group_handle = group_handle;
4319 status = dcerpc_samr_QueryGroupMember(p, tctx, &q);
4320 torture_assert_ntstatus_ok(tctx, status, "QueryGroupMember");
4322 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
4323 torture_assert_ntstatus_ok(tctx, status, "DeleteGroupMember");
4325 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4326 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
4332 static bool test_CreateDomainGroup(struct dcerpc_pipe *p,
4333 struct torture_context *tctx,
4334 struct policy_handle *domain_handle,
4335 struct policy_handle *group_handle,
4336 struct dom_sid *domain_sid)
4339 struct samr_CreateDomainGroup r;
4341 struct lsa_String name;
4344 init_lsa_String(&name, TEST_GROUPNAME);
4346 r.in.domain_handle = domain_handle;
4348 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4349 r.out.group_handle = group_handle;
4352 printf("Testing CreateDomainGroup(%s)\n", r.in.name->string);
4354 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
4356 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
4357 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
4358 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.name->string);
4361 printf("Server should have refused create of '%s', got %s instead\n", r.in.name->string,
4367 if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS)) {
4368 if (!test_DeleteGroup_byname(p, tctx, domain_handle, r.in.name->string)) {
4369 printf("CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
4373 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
4375 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
4376 if (!test_DeleteUser_byname(p, tctx, domain_handle, r.in.name->string)) {
4378 printf("CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
4382 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
4384 torture_assert_ntstatus_ok(tctx, status, "CreateDomainGroup");
4386 if (!test_AddGroupMember(p, tctx, domain_handle, group_handle)) {
4387 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
4391 if (!test_SetGroupInfo(p, tctx, group_handle)) {
4400 its not totally clear what this does. It seems to accept any sid you like.
4402 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p,
4403 struct torture_context *tctx,
4404 struct policy_handle *domain_handle)
4407 struct samr_RemoveMemberFromForeignDomain r;
4409 r.in.domain_handle = domain_handle;
4410 r.in.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-12-34-56-78");
4412 status = dcerpc_samr_RemoveMemberFromForeignDomain(p, tctx, &r);
4413 torture_assert_ntstatus_ok(tctx, status, "RemoveMemberFromForeignDomain");
4420 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
4421 struct policy_handle *handle);
4423 static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
4424 struct policy_handle *handle, struct dom_sid *sid,
4425 enum torture_samr_choice which_ops)
4428 struct samr_OpenDomain r;
4429 struct policy_handle domain_handle;
4430 struct policy_handle alias_handle;
4431 struct policy_handle user_handle;
4432 struct policy_handle group_handle;
4435 ZERO_STRUCT(alias_handle);
4436 ZERO_STRUCT(user_handle);
4437 ZERO_STRUCT(group_handle);
4438 ZERO_STRUCT(domain_handle);
4440 torture_comment(tctx, "Testing OpenDomain of %s\n", dom_sid_string(tctx, sid));
4442 r.in.connect_handle = handle;
4443 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4445 r.out.domain_handle = &domain_handle;
4447 status = dcerpc_samr_OpenDomain(p, tctx, &r);
4448 torture_assert_ntstatus_ok(tctx, status, "OpenDomain");
4450 /* run the domain tests with the main handle closed - this tests
4451 the servers reference counting */
4452 ret &= test_samr_handle_Close(p, tctx, handle);
4454 switch (which_ops) {
4455 case TORTURE_SAMR_USER_ATTRIBUTES:
4456 case TORTURE_SAMR_PASSWORDS:
4457 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops);
4458 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops);
4459 /* This test needs 'complex' users to validate */
4460 ret &= test_QueryDisplayInfo(p, tctx, &domain_handle);
4462 printf("Testing PASSWORDS or ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
4465 case TORTURE_SAMR_OTHER:
4466 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops);
4468 printf("Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid));
4470 ret &= test_QuerySecurity(p, tctx, &domain_handle);
4471 ret &= test_RemoveMemberFromForeignDomain(p, tctx, &domain_handle);
4472 ret &= test_CreateAlias(p, tctx, &domain_handle, &alias_handle, sid);
4473 ret &= test_CreateDomainGroup(p, tctx, &domain_handle, &group_handle, sid);
4474 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
4475 ret &= test_QueryDomainInfo2(p, tctx, &domain_handle);
4476 ret &= test_EnumDomainUsers(p, tctx, &domain_handle);
4477 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
4478 ret &= test_EnumDomainGroups(p, tctx, &domain_handle);
4479 ret &= test_EnumDomainAliases(p, tctx, &domain_handle);
4480 ret &= test_QueryDisplayInfo2(p, tctx, &domain_handle);
4481 ret &= test_QueryDisplayInfo3(p, tctx, &domain_handle);
4482 ret &= test_QueryDisplayInfo_continue(p, tctx, &domain_handle);
4484 if (torture_setting_bool(tctx, "samba4", false)) {
4485 torture_comment(tctx, "skipping GetDisplayEnumerationIndex test against Samba4\n");
4487 ret &= test_GetDisplayEnumerationIndex(p, tctx, &domain_handle);
4488 ret &= test_GetDisplayEnumerationIndex2(p, tctx, &domain_handle);
4490 ret &= test_GroupList(p, tctx, &domain_handle);
4491 ret &= test_TestPrivateFunctionsDomain(p, tctx, &domain_handle);
4492 ret &= test_RidToSid(p, tctx, sid, &domain_handle);
4493 ret &= test_GetBootKeyInformation(p, tctx, &domain_handle);
4495 torture_comment(tctx, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx, sid));
4500 if (!policy_handle_empty(&user_handle) &&
4501 !test_DeleteUser(p, tctx, &user_handle)) {
4505 if (!policy_handle_empty(&alias_handle) &&
4506 !test_DeleteAlias(p, tctx, &alias_handle)) {
4510 if (!policy_handle_empty(&group_handle) &&
4511 !test_DeleteDomainGroup(p, tctx, &group_handle)) {
4515 ret &= test_samr_handle_Close(p, tctx, &domain_handle);
4517 /* reconnect the main handle */
4518 ret &= test_Connect(p, tctx, handle);
4521 printf("Testing domain %s failed!\n", dom_sid_string(tctx, sid));
4527 static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
4528 struct policy_handle *handle, const char *domain,
4529 enum torture_samr_choice which_ops)
4532 struct samr_LookupDomain r;
4533 struct lsa_String n1;
4534 struct lsa_String n2;
4537 torture_comment(tctx, "Testing LookupDomain(%s)\n", domain);
4539 /* check for correct error codes */
4540 r.in.connect_handle = handle;
4541 r.in.domain_name = &n2;
4544 status = dcerpc_samr_LookupDomain(p, tctx, &r);
4545 torture_assert_ntstatus_equal(tctx, NT_STATUS_INVALID_PARAMETER, status, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
4547 init_lsa_String(&n2, "xxNODOMAINxx");
4549 status = dcerpc_samr_LookupDomain(p, tctx, &r);
4550 torture_assert_ntstatus_equal(tctx, NT_STATUS_NO_SUCH_DOMAIN, status, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
4552 r.in.connect_handle = handle;
4554 init_lsa_String(&n1, domain);
4555 r.in.domain_name = &n1;
4557 status = dcerpc_samr_LookupDomain(p, tctx, &r);
4558 torture_assert_ntstatus_ok(tctx, status, "LookupDomain");
4560 if (!test_GetDomPwInfo(p, tctx, &n1)) {
4564 if (!test_OpenDomain(p, tctx, handle, r.out.sid, which_ops)) {
4572 static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
4573 struct policy_handle *handle, enum torture_samr_choice which_ops)
4576 struct samr_EnumDomains r;
4577 uint32_t resume_handle = 0;
4581 r.in.connect_handle = handle;
4582 r.in.resume_handle = &resume_handle;
4583 r.in.buf_size = (uint32_t)-1;
4584 r.out.resume_handle = &resume_handle;
4586 status = dcerpc_samr_EnumDomains(p, tctx, &r);
4587 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
4593 for (i=0;i<r.out.sam->count;i++) {
4594 if (!test_LookupDomain(p, tctx, handle,
4595 r.out.sam->entries[i].name.string, which_ops)) {
4600 status = dcerpc_samr_EnumDomains(p, tctx, &r);
4601 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
4607 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
4608 struct policy_handle *handle)
4611 struct samr_Connect r;
4612 struct samr_Connect2 r2;
4613 struct samr_Connect3 r3;
4614 struct samr_Connect4 r4;
4615 struct samr_Connect5 r5;
4616 union samr_ConnectInfo info;
4617 struct policy_handle h;
4618 uint32_t level_out = 0;
4619 bool ret = true, got_handle = false;
4621 torture_comment(tctx, "testing samr_Connect\n");
4623 r.in.system_name = 0;
4624 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4625 r.out.connect_handle = &h;
4627 status = dcerpc_samr_Connect(p, tctx, &r);
4628 if (!NT_STATUS_IS_OK(status)) {
4629 torture_comment(tctx, "Connect failed - %s\n", nt_errstr(status));
4636 torture_comment(tctx, "testing samr_Connect2\n");
4638 r2.in.system_name = NULL;
4639 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4640 r2.out.connect_handle = &h;
4642 status = dcerpc_samr_Connect2(p, tctx, &r2);
4643 if (!NT_STATUS_IS_OK(status)) {
4644 torture_comment(tctx, "Connect2 failed - %s\n", nt_errstr(status));
4648 test_samr_handle_Close(p, tctx, handle);
4654 torture_comment(tctx, "testing samr_Connect3\n");
4656 r3.in.system_name = NULL;
4658 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4659 r3.out.connect_handle = &h;
4661 status = dcerpc_samr_Connect3(p, tctx, &r3);
4662 if (!NT_STATUS_IS_OK(status)) {
4663 printf("Connect3 failed - %s\n", nt_errstr(status));
4667 test_samr_handle_Close(p, tctx, handle);
4673 torture_comment(tctx, "testing samr_Connect4\n");
4675 r4.in.system_name = "";
4676 r4.in.client_version = 0;
4677 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4678 r4.out.connect_handle = &h;
4680 status = dcerpc_samr_Connect4(p, tctx, &r4);
4681 if (!NT_STATUS_IS_OK(status)) {
4682 printf("Connect4 failed - %s\n", nt_errstr(status));
4686 test_samr_handle_Close(p, tctx, handle);
4692 torture_comment(tctx, "testing samr_Connect5\n");
4694 info.info1.client_version = 0;
4695 info.info1.unknown2 = 0;
4697 r5.in.system_name = "";
4698 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4700 r5.out.level_out = &level_out;
4701 r5.in.info_in = &info;
4702 r5.out.info_out = &info;
4703 r5.out.connect_handle = &h;
4705 status = dcerpc_samr_Connect5(p, tctx, &r5);
4706 if (!NT_STATUS_IS_OK(status)) {
4707 printf("Connect5 failed - %s\n", nt_errstr(status));
4711 test_samr_handle_Close(p, tctx, handle);
4721 bool torture_rpc_samr(struct torture_context *torture)
4724 struct dcerpc_pipe *p;
4726 struct policy_handle handle;
4728 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4729 if (!NT_STATUS_IS_OK(status)) {
4733 ret &= test_Connect(p, torture, &handle);
4735 ret &= test_QuerySecurity(p, torture, &handle);
4737 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_OTHER);
4739 ret &= test_SetDsrmPassword(p, torture, &handle);
4741 ret &= test_Shutdown(p, torture, &handle);
4743 ret &= test_samr_handle_Close(p, torture, &handle);
4749 bool torture_rpc_samr_users(struct torture_context *torture)
4752 struct dcerpc_pipe *p;
4754 struct policy_handle handle;
4756 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4757 if (!NT_STATUS_IS_OK(status)) {
4761 ret &= test_Connect(p, torture, &handle);
4763 ret &= test_QuerySecurity(p, torture, &handle);
4765 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_USER_ATTRIBUTES);
4767 ret &= test_SetDsrmPassword(p, torture, &handle);
4769 ret &= test_Shutdown(p, torture, &handle);
4771 ret &= test_samr_handle_Close(p, torture, &handle);
4777 bool torture_rpc_samr_passwords(struct torture_context *torture)
4780 struct dcerpc_pipe *p;
4782 struct policy_handle handle;
4784 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4785 if (!NT_STATUS_IS_OK(status)) {
4789 ret &= test_Connect(p, torture, &handle);
4791 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_PASSWORDS);
4793 ret &= test_samr_handle_Close(p, torture, &handle);