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;
142 r.in.handle = handle;
145 status = dcerpc_samr_QuerySecurity(p, tctx, &r);
146 torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
148 torture_assert(tctx, r.out.sdbuf != NULL, "sdbuf is NULL");
150 s.in.handle = handle;
152 s.in.sdbuf = r.out.sdbuf;
154 if (torture_setting_bool(tctx, "samba4", false)) {
155 torture_skip(tctx, "skipping SetSecurity test against Samba4\n");
158 status = dcerpc_samr_SetSecurity(p, tctx, &s);
159 torture_assert_ntstatus_ok(tctx, status, "SetSecurity");
161 status = dcerpc_samr_QuerySecurity(p, tctx, &r);
162 torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
168 static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
169 struct policy_handle *handle, uint32_t base_acct_flags,
170 const char *base_account_name)
173 struct samr_SetUserInfo s;
174 struct samr_SetUserInfo2 s2;
175 struct samr_QueryUserInfo q;
176 struct samr_QueryUserInfo q0;
177 union samr_UserInfo u;
179 const char *test_account_name;
181 uint32_t user_extra_flags = 0;
182 if (base_acct_flags == ACB_NORMAL) {
183 /* When created, accounts are expired by default */
184 user_extra_flags = ACB_PW_EXPIRED;
187 s.in.user_handle = handle;
190 s2.in.user_handle = handle;
193 q.in.user_handle = handle;
197 #define TESTCALL(call, r) \
198 status = dcerpc_samr_ ##call(p, tctx, &r); \
199 if (!NT_STATUS_IS_OK(status)) { \
200 torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
201 r.in.level, nt_errstr(status), __location__); \
206 #define STRING_EQUAL(s1, s2, field) \
207 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
208 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
209 #field, s2, __location__); \
214 #define MEM_EQUAL(s1, s2, length, field) \
215 if ((s1 && !s2) || (s2 && !s1) || memcmp(s1, s2, length)) { \
216 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
217 #field, (const char *)s2, __location__); \
222 #define INT_EQUAL(i1, i2, field) \
224 torture_comment(tctx, "Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \
225 #field, (unsigned long long)i2, (unsigned long long)i1, __location__); \
230 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
231 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
233 TESTCALL(QueryUserInfo, q) \
235 s2.in.level = lvl1; \
238 ZERO_STRUCT(u.info21); \
239 u.info21.fields_present = fpval; \
241 init_lsa_String(&u.info ## lvl1.field1, value); \
242 TESTCALL(SetUserInfo, s) \
243 TESTCALL(SetUserInfo2, s2) \
244 init_lsa_String(&u.info ## lvl1.field1, ""); \
245 TESTCALL(QueryUserInfo, q); \
247 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
249 TESTCALL(QueryUserInfo, q) \
251 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
254 #define TEST_USERINFO_BINARYSTRING(lvl1, field1, lvl2, field2, value, fpval) do { \
255 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
257 TESTCALL(QueryUserInfo, q) \
259 s2.in.level = lvl1; \
262 ZERO_STRUCT(u.info21); \
263 u.info21.fields_present = fpval; \
265 init_lsa_BinaryString(&u.info ## lvl1.field1, value, strlen(value)); \
266 TESTCALL(SetUserInfo, s) \
267 TESTCALL(SetUserInfo2, s2) \
268 init_lsa_BinaryString(&u.info ## lvl1.field1, "", 1); \
269 TESTCALL(QueryUserInfo, q); \
271 MEM_EQUAL(u.info ## lvl1.field1.array, value, strlen(value), field1); \
273 TESTCALL(QueryUserInfo, q) \
275 MEM_EQUAL(u.info ## lvl2.field2.array, value, strlen(value), field2); \
278 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
279 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
281 TESTCALL(QueryUserInfo, q) \
283 s2.in.level = lvl1; \
286 uint8_t *bits = u.info21.logon_hours.bits; \
287 ZERO_STRUCT(u.info21); \
288 if (fpval == SAMR_FIELD_LOGON_HOURS) { \
289 u.info21.logon_hours.units_per_week = 168; \
290 u.info21.logon_hours.bits = bits; \
292 u.info21.fields_present = fpval; \
294 u.info ## lvl1.field1 = value; \
295 TESTCALL(SetUserInfo, s) \
296 TESTCALL(SetUserInfo2, s2) \
297 u.info ## lvl1.field1 = 0; \
298 TESTCALL(QueryUserInfo, q); \
300 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
302 TESTCALL(QueryUserInfo, q) \
304 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
307 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
308 TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
312 do { TESTCALL(QueryUserInfo, q0) } while (0);
314 TEST_USERINFO_STRING(2, comment, 1, comment, "xx2-1 comment", 0);
315 TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
316 TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment",
319 test_account_name = talloc_asprintf(tctx, "%sxx7-1", base_account_name);
320 TEST_USERINFO_STRING(7, account_name, 1, account_name, base_account_name, 0);
321 test_account_name = talloc_asprintf(tctx, "%sxx7-3", base_account_name);
322 TEST_USERINFO_STRING(7, account_name, 3, account_name, base_account_name, 0);
323 test_account_name = talloc_asprintf(tctx, "%sxx7-5", base_account_name);
324 TEST_USERINFO_STRING(7, account_name, 5, account_name, base_account_name, 0);
325 test_account_name = talloc_asprintf(tctx, "%sxx7-6", base_account_name);
326 TEST_USERINFO_STRING(7, account_name, 6, account_name, base_account_name, 0);
327 test_account_name = talloc_asprintf(tctx, "%sxx7-7", base_account_name);
328 TEST_USERINFO_STRING(7, account_name, 7, account_name, base_account_name, 0);
329 test_account_name = talloc_asprintf(tctx, "%sxx7-21", base_account_name);
330 TEST_USERINFO_STRING(7, account_name, 21, account_name, base_account_name, 0);
331 test_account_name = base_account_name;
332 TEST_USERINFO_STRING(21, account_name, 21, account_name, base_account_name,
333 SAMR_FIELD_ACCOUNT_NAME);
335 TEST_USERINFO_STRING(6, full_name, 1, full_name, "xx6-1 full_name", 0);
336 TEST_USERINFO_STRING(6, full_name, 3, full_name, "xx6-3 full_name", 0);
337 TEST_USERINFO_STRING(6, full_name, 5, full_name, "xx6-5 full_name", 0);
338 TEST_USERINFO_STRING(6, full_name, 6, full_name, "xx6-6 full_name", 0);
339 TEST_USERINFO_STRING(6, full_name, 8, full_name, "xx6-8 full_name", 0);
340 TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
341 TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
342 TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name",
343 SAMR_FIELD_FULL_NAME);
345 TEST_USERINFO_STRING(6, full_name, 1, full_name, "", 0);
346 TEST_USERINFO_STRING(6, full_name, 3, full_name, "", 0);
347 TEST_USERINFO_STRING(6, full_name, 5, full_name, "", 0);
348 TEST_USERINFO_STRING(6, full_name, 6, full_name, "", 0);
349 TEST_USERINFO_STRING(6, full_name, 8, full_name, "", 0);
350 TEST_USERINFO_STRING(6, full_name, 21, full_name, "", 0);
351 TEST_USERINFO_STRING(8, full_name, 21, full_name, "", 0);
352 TEST_USERINFO_STRING(21, full_name, 21, full_name, "",
353 SAMR_FIELD_FULL_NAME);
355 TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
356 TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
357 TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
358 TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script",
359 SAMR_FIELD_LOGON_SCRIPT);
361 TEST_USERINFO_STRING(12, profile_path, 3, profile_path, "xx12-3 profile_path", 0);
362 TEST_USERINFO_STRING(12, profile_path, 5, profile_path, "xx12-5 profile_path", 0);
363 TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
364 TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path",
365 SAMR_FIELD_PROFILE_PATH);
367 TEST_USERINFO_STRING(10, home_directory, 3, home_directory, "xx10-3 home_directory", 0);
368 TEST_USERINFO_STRING(10, home_directory, 5, home_directory, "xx10-5 home_directory", 0);
369 TEST_USERINFO_STRING(10, home_directory, 21, home_directory, "xx10-21 home_directory", 0);
370 TEST_USERINFO_STRING(21, home_directory, 21, home_directory, "xx21-21 home_directory",
371 SAMR_FIELD_HOME_DIRECTORY);
372 TEST_USERINFO_STRING(21, home_directory, 10, home_directory, "xx21-10 home_directory",
373 SAMR_FIELD_HOME_DIRECTORY);
375 TEST_USERINFO_STRING(10, home_drive, 3, home_drive, "xx10-3 home_drive", 0);
376 TEST_USERINFO_STRING(10, home_drive, 5, home_drive, "xx10-5 home_drive", 0);
377 TEST_USERINFO_STRING(10, home_drive, 21, home_drive, "xx10-21 home_drive", 0);
378 TEST_USERINFO_STRING(21, home_drive, 21, home_drive, "xx21-21 home_drive",
379 SAMR_FIELD_HOME_DRIVE);
380 TEST_USERINFO_STRING(21, home_drive, 10, home_drive, "xx21-10 home_drive",
381 SAMR_FIELD_HOME_DRIVE);
383 TEST_USERINFO_STRING(13, description, 1, description, "xx13-1 description", 0);
384 TEST_USERINFO_STRING(13, description, 5, description, "xx13-5 description", 0);
385 TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
386 TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description",
387 SAMR_FIELD_DESCRIPTION);
389 TEST_USERINFO_STRING(14, workstations, 3, workstations, "14workstation3", 0);
390 TEST_USERINFO_STRING(14, workstations, 5, workstations, "14workstation4", 0);
391 TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
392 TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21",
393 SAMR_FIELD_WORKSTATIONS);
394 TEST_USERINFO_STRING(21, workstations, 3, workstations, "21workstation3",
395 SAMR_FIELD_WORKSTATIONS);
396 TEST_USERINFO_STRING(21, workstations, 5, workstations, "21workstation5",
397 SAMR_FIELD_WORKSTATIONS);
398 TEST_USERINFO_STRING(21, workstations, 14, workstations, "21workstation14",
399 SAMR_FIELD_WORKSTATIONS);
401 TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
402 TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "xx21-21 parameters",
403 SAMR_FIELD_PARAMETERS);
404 TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "xx21-20 parameters",
405 SAMR_FIELD_PARAMETERS);
407 TEST_USERINFO_INT(2, country_code, 2, country_code, __LINE__, 0);
408 TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
409 TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__,
410 SAMR_FIELD_COUNTRY_CODE);
411 TEST_USERINFO_INT(21, country_code, 2, country_code, __LINE__,
412 SAMR_FIELD_COUNTRY_CODE);
414 TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
415 TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__,
416 SAMR_FIELD_CODE_PAGE);
417 TEST_USERINFO_INT(21, code_page, 2, code_page, __LINE__,
418 SAMR_FIELD_CODE_PAGE);
420 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, __LINE__, 0);
421 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, __LINE__, 0);
422 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, __LINE__,
423 SAMR_FIELD_ACCT_EXPIRY);
424 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, __LINE__,
425 SAMR_FIELD_ACCT_EXPIRY);
426 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, __LINE__,
427 SAMR_FIELD_ACCT_EXPIRY);
429 TEST_USERINFO_INT(4, logon_hours.bits[3], 3, logon_hours.bits[3], 1, 0);
430 TEST_USERINFO_INT(4, logon_hours.bits[3], 5, logon_hours.bits[3], 2, 0);
431 TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
432 TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4,
433 SAMR_FIELD_LOGON_HOURS);
435 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
436 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
437 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
439 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
440 (base_acct_flags | ACB_DISABLED),
441 (base_acct_flags | ACB_DISABLED | user_extra_flags),
444 /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
445 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
446 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
447 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
449 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
450 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
451 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
455 /* The 'autolock' flag doesn't stick - check this */
456 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
457 (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK),
458 (base_acct_flags | ACB_DISABLED | user_extra_flags),
461 /* Removing the 'disabled' flag doesn't stick - check this */
462 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
464 (base_acct_flags | ACB_DISABLED | user_extra_flags),
467 /* The 'store plaintext' flag does stick */
468 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
469 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED),
470 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags),
472 /* The 'use DES' flag does stick */
473 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
474 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY),
475 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags),
477 /* The 'don't require kerberos pre-authentication flag does stick */
478 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
479 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH),
480 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags),
482 /* The 'no kerberos PAC required' flag sticks */
483 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
484 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD),
485 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags),
488 TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags,
489 (base_acct_flags | ACB_DISABLED),
490 (base_acct_flags | ACB_DISABLED | user_extra_flags),
491 SAMR_FIELD_ACCT_FLAGS);
494 /* these fail with win2003 - it appears you can't set the primary gid?
495 the set succeeds, but the gid isn't changed. Very weird! */
496 TEST_USERINFO_INT(9, primary_gid, 1, primary_gid, 513);
497 TEST_USERINFO_INT(9, primary_gid, 3, primary_gid, 513);
498 TEST_USERINFO_INT(9, primary_gid, 5, primary_gid, 513);
499 TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
506 generate a random password for password change tests
508 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
510 size_t len = MAX(8, min_len) + (random() % 6);
511 char *s = generate_random_str(mem_ctx, len);
512 printf("Generated password '%s'\n", s);
517 generate a random password for password change tests
519 static DATA_BLOB samr_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
522 DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
523 generate_random_buffer(password.data, password.length);
525 for (i=0; i < len; i++) {
526 if (((uint16_t *)password.data)[i] == 0) {
527 ((uint16_t *)password.data)[i] = 1;
535 generate a random password for password change tests (fixed length)
537 static char *samr_rand_pass_fixed_len(TALLOC_CTX *mem_ctx, int len)
539 char *s = generate_random_str(mem_ctx, len);
540 printf("Generated password '%s'\n", s);
544 static bool test_SetUserPass(struct dcerpc_pipe *p, struct torture_context *tctx,
545 struct policy_handle *handle, char **password)
548 struct samr_SetUserInfo s;
549 union samr_UserInfo u;
551 DATA_BLOB session_key;
553 struct samr_GetUserPwInfo pwp;
554 int policy_min_pw_len = 0;
555 pwp.in.user_handle = handle;
557 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
558 if (NT_STATUS_IS_OK(status)) {
559 policy_min_pw_len = pwp.out.info.min_password_length;
561 newpass = samr_rand_pass(tctx, policy_min_pw_len);
563 s.in.user_handle = handle;
567 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
568 /* w2k3 ignores this length */
569 u.info24.pw_len = strlen_m(newpass) * 2;
571 status = dcerpc_fetch_session_key(p, &session_key);
572 if (!NT_STATUS_IS_OK(status)) {
573 printf("SetUserInfo level %u - no session key - %s\n",
574 s.in.level, nt_errstr(status));
578 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
580 torture_comment(tctx, "Testing SetUserInfo level 24 (set password)\n");
582 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
583 if (!NT_STATUS_IS_OK(status)) {
584 printf("SetUserInfo level %u failed - %s\n",
585 s.in.level, nt_errstr(status));
595 static bool test_SetUserPass_23(struct dcerpc_pipe *p, struct torture_context *tctx,
596 struct policy_handle *handle, uint32_t fields_present,
600 struct samr_SetUserInfo s;
601 union samr_UserInfo u;
603 DATA_BLOB session_key;
605 struct samr_GetUserPwInfo pwp;
606 int policy_min_pw_len = 0;
607 pwp.in.user_handle = handle;
609 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
610 if (NT_STATUS_IS_OK(status)) {
611 policy_min_pw_len = pwp.out.info.min_password_length;
613 newpass = samr_rand_pass(tctx, policy_min_pw_len);
615 s.in.user_handle = handle;
621 u.info23.info.fields_present = fields_present;
623 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
625 status = dcerpc_fetch_session_key(p, &session_key);
626 if (!NT_STATUS_IS_OK(status)) {
627 printf("SetUserInfo level %u - no session key - %s\n",
628 s.in.level, nt_errstr(status));
632 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
634 torture_comment(tctx, "Testing SetUserInfo level 23 (set password)\n");
636 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
637 if (!NT_STATUS_IS_OK(status)) {
638 printf("SetUserInfo level %u failed - %s\n",
639 s.in.level, nt_errstr(status));
645 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
647 status = dcerpc_fetch_session_key(p, &session_key);
648 if (!NT_STATUS_IS_OK(status)) {
649 printf("SetUserInfo level %u - no session key - %s\n",
650 s.in.level, nt_errstr(status));
654 /* This should break the key nicely */
655 session_key.length--;
656 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
658 torture_comment(tctx, "Testing SetUserInfo level 23 (set password) with wrong password\n");
660 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
661 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
662 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
663 s.in.level, nt_errstr(status));
671 static bool test_SetUserPassEx(struct dcerpc_pipe *p, struct torture_context *tctx,
672 struct policy_handle *handle, bool makeshort,
676 struct samr_SetUserInfo s;
677 union samr_UserInfo u;
679 DATA_BLOB session_key;
680 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
681 uint8_t confounder[16];
683 struct MD5Context ctx;
684 struct samr_GetUserPwInfo pwp;
685 int policy_min_pw_len = 0;
686 pwp.in.user_handle = handle;
688 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
689 if (NT_STATUS_IS_OK(status)) {
690 policy_min_pw_len = pwp.out.info.min_password_length;
692 if (makeshort && policy_min_pw_len) {
693 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len - 1);
695 newpass = samr_rand_pass(tctx, policy_min_pw_len);
698 s.in.user_handle = handle;
702 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
703 u.info26.pw_len = strlen(newpass);
705 status = dcerpc_fetch_session_key(p, &session_key);
706 if (!NT_STATUS_IS_OK(status)) {
707 printf("SetUserInfo level %u - no session key - %s\n",
708 s.in.level, nt_errstr(status));
712 generate_random_buffer((uint8_t *)confounder, 16);
715 MD5Update(&ctx, confounder, 16);
716 MD5Update(&ctx, session_key.data, session_key.length);
717 MD5Final(confounded_session_key.data, &ctx);
719 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
720 memcpy(&u.info26.password.data[516], confounder, 16);
722 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex)\n");
724 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
725 if (!NT_STATUS_IS_OK(status)) {
726 printf("SetUserInfo level %u failed - %s\n",
727 s.in.level, nt_errstr(status));
733 /* This should break the key nicely */
734 confounded_session_key.data[0]++;
736 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
737 memcpy(&u.info26.password.data[516], confounder, 16);
739 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
741 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
742 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
743 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
744 s.in.level, nt_errstr(status));
753 static bool test_SetUserPass_25(struct dcerpc_pipe *p, struct torture_context *tctx,
754 struct policy_handle *handle, uint32_t fields_present,
758 struct samr_SetUserInfo s;
759 union samr_UserInfo u;
761 DATA_BLOB session_key;
762 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
763 struct MD5Context ctx;
764 uint8_t confounder[16];
766 struct samr_GetUserPwInfo pwp;
767 int policy_min_pw_len = 0;
768 pwp.in.user_handle = handle;
770 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
771 if (NT_STATUS_IS_OK(status)) {
772 policy_min_pw_len = pwp.out.info.min_password_length;
774 newpass = samr_rand_pass(tctx, policy_min_pw_len);
776 s.in.user_handle = handle;
782 u.info25.info.fields_present = fields_present;
784 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
786 status = dcerpc_fetch_session_key(p, &session_key);
787 if (!NT_STATUS_IS_OK(status)) {
788 printf("SetUserInfo level %u - no session key - %s\n",
789 s.in.level, nt_errstr(status));
793 generate_random_buffer((uint8_t *)confounder, 16);
796 MD5Update(&ctx, confounder, 16);
797 MD5Update(&ctx, session_key.data, session_key.length);
798 MD5Final(confounded_session_key.data, &ctx);
800 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
801 memcpy(&u.info25.password.data[516], confounder, 16);
803 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex)\n");
805 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
806 if (!NT_STATUS_IS_OK(status)) {
807 printf("SetUserInfo level %u failed - %s\n",
808 s.in.level, nt_errstr(status));
814 /* This should break the key nicely */
815 confounded_session_key.data[0]++;
817 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
818 memcpy(&u.info25.password.data[516], confounder, 16);
820 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
822 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
823 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
824 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
825 s.in.level, nt_errstr(status));
832 static bool test_SetAliasInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
833 struct policy_handle *handle)
836 struct samr_SetAliasInfo r;
837 struct samr_QueryAliasInfo q;
838 uint16_t levels[] = {2, 3};
842 /* Ignoring switch level 1, as that includes the number of members for the alias
843 * and setting this to a wrong value might have negative consequences
846 for (i=0;i<ARRAY_SIZE(levels);i++) {
847 torture_comment(tctx, "Testing SetAliasInfo level %u\n", levels[i]);
849 r.in.alias_handle = handle;
850 r.in.level = levels[i];
851 r.in.info = talloc(tctx, union samr_AliasInfo);
852 switch (r.in.level) {
853 case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
854 case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
855 "Test Description, should test I18N as well"); break;
856 case ALIASINFOALL: printf("ALIASINFOALL ignored\n"); break;
859 status = dcerpc_samr_SetAliasInfo(p, tctx, &r);
860 if (!NT_STATUS_IS_OK(status)) {
861 printf("SetAliasInfo level %u failed - %s\n",
862 levels[i], nt_errstr(status));
866 q.in.alias_handle = handle;
867 q.in.level = levels[i];
869 status = dcerpc_samr_QueryAliasInfo(p, tctx, &q);
870 if (!NT_STATUS_IS_OK(status)) {
871 printf("QueryAliasInfo level %u failed - %s\n",
872 levels[i], nt_errstr(status));
880 static bool test_GetGroupsForUser(struct dcerpc_pipe *p, struct torture_context *tctx,
881 struct policy_handle *user_handle)
883 struct samr_GetGroupsForUser r;
886 torture_comment(tctx, "testing GetGroupsForUser\n");
888 r.in.user_handle = user_handle;
890 status = dcerpc_samr_GetGroupsForUser(p, tctx, &r);
891 torture_assert_ntstatus_ok(tctx, status, "GetGroupsForUser");
897 static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
898 struct lsa_String *domain_name)
901 struct samr_GetDomPwInfo r;
903 r.in.domain_name = domain_name;
904 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
906 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
907 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
909 r.in.domain_name->string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
910 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
912 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
913 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
915 r.in.domain_name->string = "\\\\__NONAME__";
916 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
918 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
919 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
921 r.in.domain_name->string = "\\\\Builtin";
922 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
924 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
925 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
930 static bool test_GetUserPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
931 struct policy_handle *handle)
934 struct samr_GetUserPwInfo r;
936 torture_comment(tctx, "Testing GetUserPwInfo\n");
938 r.in.user_handle = handle;
940 status = dcerpc_samr_GetUserPwInfo(p, tctx, &r);
941 torture_assert_ntstatus_ok(tctx, status, "GetUserPwInfo");
946 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, struct torture_context *tctx,
947 struct policy_handle *domain_handle, const char *name,
951 struct samr_LookupNames n;
952 struct lsa_String sname[2];
954 init_lsa_String(&sname[0], name);
956 n.in.domain_handle = domain_handle;
959 status = dcerpc_samr_LookupNames(p, tctx, &n);
960 if (NT_STATUS_IS_OK(status)) {
961 *rid = n.out.rids.ids[0];
966 init_lsa_String(&sname[1], "xxNONAMExx");
968 status = dcerpc_samr_LookupNames(p, tctx, &n);
969 if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
970 printf("LookupNames[2] failed - %s\n", nt_errstr(status));
971 if (NT_STATUS_IS_OK(status)) {
972 return NT_STATUS_UNSUCCESSFUL;
978 status = dcerpc_samr_LookupNames(p, tctx, &n);
979 if (!NT_STATUS_IS_OK(status)) {
980 printf("LookupNames[0] failed - %s\n", nt_errstr(status));
984 init_lsa_String(&sname[0], "xxNONAMExx");
986 status = dcerpc_samr_LookupNames(p, tctx, &n);
987 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
988 printf("LookupNames[1 bad name] failed - %s\n", nt_errstr(status));
989 if (NT_STATUS_IS_OK(status)) {
990 return NT_STATUS_UNSUCCESSFUL;
995 init_lsa_String(&sname[0], "xxNONAMExx");
996 init_lsa_String(&sname[1], "xxNONAME2xx");
998 status = dcerpc_samr_LookupNames(p, tctx, &n);
999 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1000 printf("LookupNames[2 bad names] failed - %s\n", nt_errstr(status));
1001 if (NT_STATUS_IS_OK(status)) {
1002 return NT_STATUS_UNSUCCESSFUL;
1007 return NT_STATUS_OK;
1010 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1011 struct policy_handle *domain_handle,
1012 const char *name, struct policy_handle *user_handle)
1015 struct samr_OpenUser r;
1018 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
1019 if (!NT_STATUS_IS_OK(status)) {
1023 r.in.domain_handle = domain_handle;
1024 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1026 r.out.user_handle = user_handle;
1027 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
1028 if (!NT_STATUS_IS_OK(status)) {
1029 printf("OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(status));
1036 static bool test_ChangePasswordNT3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1037 struct policy_handle *handle)
1040 struct samr_ChangePasswordUser r;
1042 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1043 struct policy_handle user_handle;
1044 char *oldpass = "test";
1045 char *newpass = "test2";
1046 uint8_t old_nt_hash[16], new_nt_hash[16];
1047 uint8_t old_lm_hash[16], new_lm_hash[16];
1049 status = test_OpenUser_byname(p, mem_ctx, handle, "testuser", &user_handle);
1050 if (!NT_STATUS_IS_OK(status)) {
1054 printf("Testing ChangePasswordUser for user 'testuser'\n");
1056 printf("old password: %s\n", oldpass);
1057 printf("new password: %s\n", newpass);
1059 E_md4hash(oldpass, old_nt_hash);
1060 E_md4hash(newpass, new_nt_hash);
1061 E_deshash(oldpass, old_lm_hash);
1062 E_deshash(newpass, new_lm_hash);
1064 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1065 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1066 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1067 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1068 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1069 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1071 r.in.handle = &user_handle;
1072 r.in.lm_present = 1;
1073 r.in.old_lm_crypted = &hash1;
1074 r.in.new_lm_crypted = &hash2;
1075 r.in.nt_present = 1;
1076 r.in.old_nt_crypted = &hash3;
1077 r.in.new_nt_crypted = &hash4;
1078 r.in.cross1_present = 1;
1079 r.in.nt_cross = &hash5;
1080 r.in.cross2_present = 1;
1081 r.in.lm_cross = &hash6;
1083 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1084 if (!NT_STATUS_IS_OK(status)) {
1085 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1089 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1097 static bool test_ChangePasswordUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1098 const char *acct_name,
1099 struct policy_handle *handle, char **password)
1102 struct samr_ChangePasswordUser r;
1104 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1105 struct policy_handle user_handle;
1107 uint8_t old_nt_hash[16], new_nt_hash[16];
1108 uint8_t old_lm_hash[16], new_lm_hash[16];
1109 bool changed = true;
1112 struct samr_GetUserPwInfo pwp;
1113 int policy_min_pw_len = 0;
1115 status = test_OpenUser_byname(p, tctx, handle, acct_name, &user_handle);
1116 if (!NT_STATUS_IS_OK(status)) {
1119 pwp.in.user_handle = &user_handle;
1121 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1122 if (NT_STATUS_IS_OK(status)) {
1123 policy_min_pw_len = pwp.out.info.min_password_length;
1125 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1127 torture_comment(tctx, "Testing ChangePasswordUser\n");
1129 torture_assert(tctx, *password != NULL,
1130 "Failing ChangePasswordUser as old password was NULL. Previous test failed?");
1132 oldpass = *password;
1134 E_md4hash(oldpass, old_nt_hash);
1135 E_md4hash(newpass, new_nt_hash);
1136 E_deshash(oldpass, old_lm_hash);
1137 E_deshash(newpass, new_lm_hash);
1139 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1140 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1141 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1142 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1143 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1144 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1146 r.in.user_handle = &user_handle;
1147 r.in.lm_present = 1;
1148 /* Break the LM hash */
1150 r.in.old_lm_crypted = &hash1;
1151 r.in.new_lm_crypted = &hash2;
1152 r.in.nt_present = 1;
1153 r.in.old_nt_crypted = &hash3;
1154 r.in.new_nt_crypted = &hash4;
1155 r.in.cross1_present = 1;
1156 r.in.nt_cross = &hash5;
1157 r.in.cross2_present = 1;
1158 r.in.lm_cross = &hash6;
1160 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1161 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1162 "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash");
1164 /* Unbreak the LM hash */
1167 r.in.user_handle = &user_handle;
1168 r.in.lm_present = 1;
1169 r.in.old_lm_crypted = &hash1;
1170 r.in.new_lm_crypted = &hash2;
1171 /* Break the NT hash */
1173 r.in.nt_present = 1;
1174 r.in.old_nt_crypted = &hash3;
1175 r.in.new_nt_crypted = &hash4;
1176 r.in.cross1_present = 1;
1177 r.in.nt_cross = &hash5;
1178 r.in.cross2_present = 1;
1179 r.in.lm_cross = &hash6;
1181 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1182 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1183 "expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash");
1185 /* Unbreak the NT hash */
1188 r.in.user_handle = &user_handle;
1189 r.in.lm_present = 1;
1190 r.in.old_lm_crypted = &hash1;
1191 r.in.new_lm_crypted = &hash2;
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 /* Break the LM cross */
1200 r.in.lm_cross = &hash6;
1202 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1203 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1204 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status));
1208 /* Unbreak the LM cross */
1211 r.in.user_handle = &user_handle;
1212 r.in.lm_present = 1;
1213 r.in.old_lm_crypted = &hash1;
1214 r.in.new_lm_crypted = &hash2;
1215 r.in.nt_present = 1;
1216 r.in.old_nt_crypted = &hash3;
1217 r.in.new_nt_crypted = &hash4;
1218 r.in.cross1_present = 1;
1219 /* Break the NT cross */
1221 r.in.nt_cross = &hash5;
1222 r.in.cross2_present = 1;
1223 r.in.lm_cross = &hash6;
1225 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1226 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1227 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status));
1231 /* Unbreak the NT cross */
1235 /* Reset the hashes to not broken values */
1236 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1237 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1238 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1239 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1240 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1241 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1243 r.in.user_handle = &user_handle;
1244 r.in.lm_present = 1;
1245 r.in.old_lm_crypted = &hash1;
1246 r.in.new_lm_crypted = &hash2;
1247 r.in.nt_present = 1;
1248 r.in.old_nt_crypted = &hash3;
1249 r.in.new_nt_crypted = &hash4;
1250 r.in.cross1_present = 1;
1251 r.in.nt_cross = &hash5;
1252 r.in.cross2_present = 0;
1253 r.in.lm_cross = NULL;
1255 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1256 if (NT_STATUS_IS_OK(status)) {
1258 *password = newpass;
1259 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1260 printf("ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(status));
1265 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1267 E_md4hash(oldpass, old_nt_hash);
1268 E_md4hash(newpass, new_nt_hash);
1269 E_deshash(oldpass, old_lm_hash);
1270 E_deshash(newpass, new_lm_hash);
1273 /* Reset the hashes to not broken values */
1274 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1275 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1276 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1277 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1278 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1279 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1281 r.in.user_handle = &user_handle;
1282 r.in.lm_present = 1;
1283 r.in.old_lm_crypted = &hash1;
1284 r.in.new_lm_crypted = &hash2;
1285 r.in.nt_present = 1;
1286 r.in.old_nt_crypted = &hash3;
1287 r.in.new_nt_crypted = &hash4;
1288 r.in.cross1_present = 0;
1289 r.in.nt_cross = NULL;
1290 r.in.cross2_present = 1;
1291 r.in.lm_cross = &hash6;
1293 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1294 if (NT_STATUS_IS_OK(status)) {
1296 *password = newpass;
1297 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1298 printf("ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status));
1303 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1305 E_md4hash(oldpass, old_nt_hash);
1306 E_md4hash(newpass, new_nt_hash);
1307 E_deshash(oldpass, old_lm_hash);
1308 E_deshash(newpass, new_lm_hash);
1311 /* Reset the hashes to not broken values */
1312 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1313 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1314 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1315 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1316 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1317 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1319 r.in.user_handle = &user_handle;
1320 r.in.lm_present = 1;
1321 r.in.old_lm_crypted = &hash1;
1322 r.in.new_lm_crypted = &hash2;
1323 r.in.nt_present = 1;
1324 r.in.old_nt_crypted = &hash3;
1325 r.in.new_nt_crypted = &hash4;
1326 r.in.cross1_present = 1;
1327 r.in.nt_cross = &hash5;
1328 r.in.cross2_present = 1;
1329 r.in.lm_cross = &hash6;
1331 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1332 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1333 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1334 } else if (!NT_STATUS_IS_OK(status)) {
1335 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1339 *password = newpass;
1342 r.in.user_handle = &user_handle;
1343 r.in.lm_present = 1;
1344 r.in.old_lm_crypted = &hash1;
1345 r.in.new_lm_crypted = &hash2;
1346 r.in.nt_present = 1;
1347 r.in.old_nt_crypted = &hash3;
1348 r.in.new_nt_crypted = &hash4;
1349 r.in.cross1_present = 1;
1350 r.in.nt_cross = &hash5;
1351 r.in.cross2_present = 1;
1352 r.in.lm_cross = &hash6;
1355 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1356 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1357 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1358 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1359 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status));
1365 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
1373 static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
1374 const char *acct_name,
1375 struct policy_handle *handle, char **password)
1378 struct samr_OemChangePasswordUser2 r;
1380 struct samr_Password lm_verifier;
1381 struct samr_CryptPassword lm_pass;
1382 struct lsa_AsciiString server, account, account_bad;
1385 uint8_t old_lm_hash[16], new_lm_hash[16];
1387 struct samr_GetDomPwInfo dom_pw_info;
1388 int policy_min_pw_len = 0;
1390 struct lsa_String domain_name;
1392 domain_name.string = "";
1393 dom_pw_info.in.domain_name = &domain_name;
1395 torture_comment(tctx, "Testing OemChangePasswordUser2\n");
1397 torture_assert(tctx, *password != NULL,
1398 "Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?");
1400 oldpass = *password;
1402 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
1403 if (NT_STATUS_IS_OK(status)) {
1404 policy_min_pw_len = dom_pw_info.out.info.min_password_length;
1407 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1409 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1410 account.string = acct_name;
1412 E_deshash(oldpass, old_lm_hash);
1413 E_deshash(newpass, new_lm_hash);
1415 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1416 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1417 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1419 r.in.server = &server;
1420 r.in.account = &account;
1421 r.in.password = &lm_pass;
1422 r.in.hash = &lm_verifier;
1424 /* Break the verification */
1425 lm_verifier.hash[0]++;
1427 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1429 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1430 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1431 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1436 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1437 /* Break the old password */
1439 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1440 /* unbreak it for the next operation */
1442 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1444 r.in.server = &server;
1445 r.in.account = &account;
1446 r.in.password = &lm_pass;
1447 r.in.hash = &lm_verifier;
1449 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1451 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1452 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1453 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1458 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1459 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1461 r.in.server = &server;
1462 r.in.account = &account;
1463 r.in.password = &lm_pass;
1466 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1468 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1469 && !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1470 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
1475 /* This shouldn't be a valid name */
1476 account_bad.string = TEST_ACCOUNT_NAME "XX";
1477 r.in.account = &account_bad;
1479 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1481 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1482 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
1487 /* This shouldn't be a valid name */
1488 account_bad.string = TEST_ACCOUNT_NAME "XX";
1489 r.in.account = &account_bad;
1490 r.in.password = &lm_pass;
1491 r.in.hash = &lm_verifier;
1493 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1495 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1496 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1501 /* This shouldn't be a valid name */
1502 account_bad.string = TEST_ACCOUNT_NAME "XX";
1503 r.in.account = &account_bad;
1504 r.in.password = NULL;
1505 r.in.hash = &lm_verifier;
1507 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1509 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1510 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
1515 E_deshash(oldpass, old_lm_hash);
1516 E_deshash(newpass, new_lm_hash);
1518 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1519 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1520 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1522 r.in.server = &server;
1523 r.in.account = &account;
1524 r.in.password = &lm_pass;
1525 r.in.hash = &lm_verifier;
1527 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1528 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1529 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1530 } else if (!NT_STATUS_IS_OK(status)) {
1531 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
1534 *password = newpass;
1541 static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
1542 const char *acct_name,
1544 char *newpass, bool allow_password_restriction)
1547 struct samr_ChangePasswordUser2 r;
1549 struct lsa_String server, account;
1550 struct samr_CryptPassword nt_pass, lm_pass;
1551 struct samr_Password nt_verifier, lm_verifier;
1553 uint8_t old_nt_hash[16], new_nt_hash[16];
1554 uint8_t old_lm_hash[16], new_lm_hash[16];
1556 struct samr_GetDomPwInfo dom_pw_info;
1558 struct lsa_String domain_name;
1560 domain_name.string = "";
1561 dom_pw_info.in.domain_name = &domain_name;
1563 torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name);
1565 torture_assert(tctx, *password != NULL,
1566 "Failing ChangePasswordUser2 as old password was NULL. Previous test failed?");
1567 oldpass = *password;
1570 int policy_min_pw_len = 0;
1571 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
1572 if (NT_STATUS_IS_OK(status)) {
1573 policy_min_pw_len = dom_pw_info.out.info.min_password_length;
1576 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1579 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1580 init_lsa_String(&account, acct_name);
1582 E_md4hash(oldpass, old_nt_hash);
1583 E_md4hash(newpass, new_nt_hash);
1585 E_deshash(oldpass, old_lm_hash);
1586 E_deshash(newpass, new_lm_hash);
1588 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
1589 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1590 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1592 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1593 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1594 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1596 r.in.server = &server;
1597 r.in.account = &account;
1598 r.in.nt_password = &nt_pass;
1599 r.in.nt_verifier = &nt_verifier;
1601 r.in.lm_password = &lm_pass;
1602 r.in.lm_verifier = &lm_verifier;
1604 status = dcerpc_samr_ChangePasswordUser2(p, tctx, &r);
1605 if (allow_password_restriction && NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1606 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1607 } else if (!NT_STATUS_IS_OK(status)) {
1608 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
1611 *password = newpass;
1618 bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tctx,
1619 const char *account_string,
1620 int policy_min_pw_len,
1622 const char *newpass,
1623 NTTIME last_password_change,
1624 bool handle_reject_reason)
1627 struct samr_ChangePasswordUser3 r;
1629 struct lsa_String server, account, account_bad;
1630 struct samr_CryptPassword nt_pass, lm_pass;
1631 struct samr_Password nt_verifier, lm_verifier;
1633 uint8_t old_nt_hash[16], new_nt_hash[16];
1634 uint8_t old_lm_hash[16], new_lm_hash[16];
1636 struct samr_DomInfo1 *dominfo = NULL;
1637 struct samr_ChangeReject *reject = NULL;
1639 torture_comment(tctx, "Testing ChangePasswordUser3\n");
1641 if (newpass == NULL) {
1643 if (policy_min_pw_len == 0) {
1644 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1646 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len);
1648 } while (check_password_quality(newpass) == false);
1650 torture_comment(tctx, "Using password '%s'\n", newpass);
1653 torture_assert(tctx, *password != NULL,
1654 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
1656 oldpass = *password;
1657 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1658 init_lsa_String(&account, account_string);
1660 E_md4hash(oldpass, old_nt_hash);
1661 E_md4hash(newpass, new_nt_hash);
1663 E_deshash(oldpass, old_lm_hash);
1664 E_deshash(newpass, new_lm_hash);
1666 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1667 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1668 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1670 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1671 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1672 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1674 /* Break the verification */
1675 nt_verifier.hash[0]++;
1677 r.in.server = &server;
1678 r.in.account = &account;
1679 r.in.nt_password = &nt_pass;
1680 r.in.nt_verifier = &nt_verifier;
1682 r.in.lm_password = &lm_pass;
1683 r.in.lm_verifier = &lm_verifier;
1684 r.in.password3 = NULL;
1685 r.out.dominfo = &dominfo;
1686 r.out.reject = &reject;
1688 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1689 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1690 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1691 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1696 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1697 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1698 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1700 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1701 /* Break the NT hash */
1703 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1704 /* Unbreak it again */
1706 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1708 r.in.server = &server;
1709 r.in.account = &account;
1710 r.in.nt_password = &nt_pass;
1711 r.in.nt_verifier = &nt_verifier;
1713 r.in.lm_password = &lm_pass;
1714 r.in.lm_verifier = &lm_verifier;
1715 r.in.password3 = NULL;
1716 r.out.dominfo = &dominfo;
1717 r.out.reject = &reject;
1719 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1720 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1721 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1722 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1727 /* This shouldn't be a valid name */
1728 init_lsa_String(&account_bad, talloc_asprintf(tctx, "%sXX", account_string));
1730 r.in.account = &account_bad;
1731 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1732 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1733 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
1738 E_md4hash(oldpass, old_nt_hash);
1739 E_md4hash(newpass, new_nt_hash);
1741 E_deshash(oldpass, old_lm_hash);
1742 E_deshash(newpass, new_lm_hash);
1744 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1745 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1746 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1748 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1749 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1750 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1752 r.in.server = &server;
1753 r.in.account = &account;
1754 r.in.nt_password = &nt_pass;
1755 r.in.nt_verifier = &nt_verifier;
1757 r.in.lm_password = &lm_pass;
1758 r.in.lm_verifier = &lm_verifier;
1759 r.in.password3 = NULL;
1760 r.out.dominfo = &dominfo;
1761 r.out.reject = &reject;
1763 unix_to_nt_time(&t, time(NULL));
1765 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1767 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1770 && handle_reject_reason
1771 && (!null_nttime(last_password_change) || !dominfo->min_password_age)) {
1772 if (dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
1774 if (reject && (reject->reason != SAMR_REJECT_OTHER)) {
1775 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1776 SAMR_REJECT_OTHER, reject->reason);
1781 /* We tested the order of precendence which is as follows:
1790 if ((dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
1791 (last_password_change + dominfo->min_password_age > t)) {
1793 if (reject->reason != SAMR_REJECT_OTHER) {
1794 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1795 SAMR_REJECT_OTHER, reject->reason);
1799 } else if ((dominfo->min_password_length > 0) &&
1800 (strlen(newpass) < dominfo->min_password_length)) {
1802 if (reject->reason != SAMR_REJECT_TOO_SHORT) {
1803 printf("expected SAMR_REJECT_TOO_SHORT (%d), got %d\n",
1804 SAMR_REJECT_TOO_SHORT, reject->reason);
1808 } else if ((dominfo->password_history_length > 0) &&
1809 strequal(oldpass, newpass)) {
1811 if (reject->reason != SAMR_REJECT_IN_HISTORY) {
1812 printf("expected SAMR_REJECT_IN_HISTORY (%d), got %d\n",
1813 SAMR_REJECT_IN_HISTORY, reject->reason);
1816 } else if (dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
1818 if (reject->reason != SAMR_REJECT_COMPLEXITY) {
1819 printf("expected SAMR_REJECT_COMPLEXITY (%d), got %d\n",
1820 SAMR_REJECT_COMPLEXITY, reject->reason);
1826 if (reject->reason == SAMR_REJECT_TOO_SHORT) {
1827 /* retry with adjusted size */
1828 return test_ChangePasswordUser3(p, tctx, account_string,
1829 dominfo->min_password_length,
1830 password, NULL, 0, false);
1834 } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1835 if (reject && reject->reason != SAMR_REJECT_OTHER) {
1836 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1837 SAMR_REJECT_OTHER, reject->reason);
1840 /* Perhaps the server has a 'min password age' set? */
1843 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3");
1844 *password = talloc_strdup(tctx, newpass);
1850 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_context *tctx,
1851 const char *account_string,
1852 struct policy_handle *handle,
1856 struct samr_ChangePasswordUser3 r;
1857 struct samr_SetUserInfo s;
1858 union samr_UserInfo u;
1859 DATA_BLOB session_key;
1860 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
1861 uint8_t confounder[16];
1862 struct MD5Context ctx;
1865 struct lsa_String server, account;
1866 struct samr_CryptPassword nt_pass;
1867 struct samr_Password nt_verifier;
1868 DATA_BLOB new_random_pass;
1871 uint8_t old_nt_hash[16], new_nt_hash[16];
1873 struct samr_DomInfo1 *dominfo = NULL;
1874 struct samr_ChangeReject *reject = NULL;
1876 new_random_pass = samr_very_rand_pass(tctx, 128);
1878 torture_assert(tctx, *password != NULL,
1879 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
1881 oldpass = *password;
1882 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1883 init_lsa_String(&account, account_string);
1885 s.in.user_handle = handle;
1891 u.info25.info.fields_present = SAMR_FIELD_PASSWORD;
1893 set_pw_in_buffer(u.info25.password.data, &new_random_pass);
1895 status = dcerpc_fetch_session_key(p, &session_key);
1896 if (!NT_STATUS_IS_OK(status)) {
1897 printf("SetUserInfo level %u - no session key - %s\n",
1898 s.in.level, nt_errstr(status));
1902 generate_random_buffer((uint8_t *)confounder, 16);
1905 MD5Update(&ctx, confounder, 16);
1906 MD5Update(&ctx, session_key.data, session_key.length);
1907 MD5Final(confounded_session_key.data, &ctx);
1909 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
1910 memcpy(&u.info25.password.data[516], confounder, 16);
1912 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
1914 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1915 if (!NT_STATUS_IS_OK(status)) {
1916 printf("SetUserInfo level %u failed - %s\n",
1917 s.in.level, nt_errstr(status));
1921 torture_comment(tctx, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
1923 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
1925 new_random_pass = samr_very_rand_pass(tctx, 128);
1927 mdfour(new_nt_hash, new_random_pass.data, new_random_pass.length);
1929 set_pw_in_buffer(nt_pass.data, &new_random_pass);
1930 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1931 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1933 r.in.server = &server;
1934 r.in.account = &account;
1935 r.in.nt_password = &nt_pass;
1936 r.in.nt_verifier = &nt_verifier;
1938 r.in.lm_password = NULL;
1939 r.in.lm_verifier = NULL;
1940 r.in.password3 = NULL;
1941 r.out.dominfo = &dominfo;
1942 r.out.reject = &reject;
1944 unix_to_nt_time(&t, time(NULL));
1946 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1948 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1949 if (reject && reject->reason != SAMR_REJECT_OTHER) {
1950 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1951 SAMR_REJECT_OTHER, reject->reason);
1954 /* Perhaps the server has a 'min password age' set? */
1956 } else if (!NT_STATUS_IS_OK(status)) {
1957 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
1961 newpass = samr_rand_pass(tctx, 128);
1963 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
1965 E_md4hash(newpass, new_nt_hash);
1967 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1968 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1969 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1971 r.in.server = &server;
1972 r.in.account = &account;
1973 r.in.nt_password = &nt_pass;
1974 r.in.nt_verifier = &nt_verifier;
1976 r.in.lm_password = NULL;
1977 r.in.lm_verifier = NULL;
1978 r.in.password3 = NULL;
1979 r.out.dominfo = &dominfo;
1980 r.out.reject = &reject;
1982 unix_to_nt_time(&t, time(NULL));
1984 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1986 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1987 if (reject && reject->reason != SAMR_REJECT_OTHER) {
1988 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1989 SAMR_REJECT_OTHER, reject->reason);
1992 /* Perhaps the server has a 'min password age' set? */
1995 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3 (on second random password)");
1996 *password = talloc_strdup(tctx, newpass);
2003 static bool test_GetMembersInAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2004 struct policy_handle *alias_handle)
2006 struct samr_GetMembersInAlias r;
2007 struct lsa_SidArray sids;
2010 torture_comment(tctx, "Testing GetMembersInAlias\n");
2012 r.in.alias_handle = alias_handle;
2015 status = dcerpc_samr_GetMembersInAlias(p, tctx, &r);
2016 torture_assert_ntstatus_ok(tctx, status, "GetMembersInAlias");
2021 static bool test_AddMemberToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2022 struct policy_handle *alias_handle,
2023 const struct dom_sid *domain_sid)
2025 struct samr_AddAliasMember r;
2026 struct samr_DeleteAliasMember d;
2028 struct dom_sid *sid;
2030 sid = dom_sid_add_rid(tctx, domain_sid, 512);
2032 torture_comment(tctx, "testing AddAliasMember\n");
2033 r.in.alias_handle = alias_handle;
2036 status = dcerpc_samr_AddAliasMember(p, tctx, &r);
2037 torture_assert_ntstatus_ok(tctx, status, "AddAliasMember");
2039 d.in.alias_handle = alias_handle;
2042 status = dcerpc_samr_DeleteAliasMember(p, tctx, &d);
2043 torture_assert_ntstatus_ok(tctx, status, "DelAliasMember");
2048 static bool test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2049 struct policy_handle *alias_handle)
2051 struct samr_AddMultipleMembersToAlias a;
2052 struct samr_RemoveMultipleMembersFromAlias r;
2054 struct lsa_SidArray sids;
2056 torture_comment(tctx, "testing AddMultipleMembersToAlias\n");
2057 a.in.alias_handle = alias_handle;
2061 sids.sids = talloc_array(tctx, struct lsa_SidPtr, 3);
2063 sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2064 sids.sids[1].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-2");
2065 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-3");
2067 status = dcerpc_samr_AddMultipleMembersToAlias(p, tctx, &a);
2068 torture_assert_ntstatus_ok(tctx, status, "AddMultipleMembersToAlias");
2071 torture_comment(tctx, "testing RemoveMultipleMembersFromAlias\n");
2072 r.in.alias_handle = alias_handle;
2075 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2076 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2078 /* strange! removing twice doesn't give any error */
2079 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2080 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2082 /* but removing an alias that isn't there does */
2083 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-4");
2085 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2086 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, "RemoveMultipleMembersFromAlias");
2091 static bool test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2092 struct policy_handle *user_handle)
2094 struct samr_TestPrivateFunctionsUser r;
2097 torture_comment(tctx, "Testing TestPrivateFunctionsUser\n");
2099 r.in.user_handle = user_handle;
2101 status = dcerpc_samr_TestPrivateFunctionsUser(p, tctx, &r);
2102 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsUser");
2108 static bool test_user_ops(struct dcerpc_pipe *p,
2109 struct torture_context *tctx,
2110 struct policy_handle *user_handle,
2111 struct policy_handle *domain_handle,
2112 uint32_t base_acct_flags,
2113 const char *base_acct_name, enum torture_samr_choice which_ops)
2115 char *password = NULL;
2116 struct samr_QueryUserInfo q;
2122 const uint32_t password_fields[] = {
2123 SAMR_FIELD_PASSWORD,
2124 SAMR_FIELD_PASSWORD2,
2125 SAMR_FIELD_PASSWORD | SAMR_FIELD_PASSWORD2,
2129 status = test_LookupName(p, tctx, domain_handle, base_acct_name, &rid);
2130 if (!NT_STATUS_IS_OK(status)) {
2134 switch (which_ops) {
2135 case TORTURE_SAMR_USER_ATTRIBUTES:
2136 if (!test_QuerySecurity(p, tctx, user_handle)) {
2140 if (!test_QueryUserInfo(p, tctx, user_handle)) {
2144 if (!test_QueryUserInfo2(p, tctx, user_handle)) {
2148 if (!test_SetUserInfo(p, tctx, user_handle, base_acct_flags,
2153 if (!test_GetUserPwInfo(p, tctx, user_handle)) {
2157 if (!test_TestPrivateFunctionsUser(p, tctx, user_handle)) {
2161 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
2165 case TORTURE_SAMR_PASSWORDS:
2166 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
2167 char simple_pass[9];
2168 char *v = generate_random_str(tctx, 1);
2170 ZERO_STRUCT(simple_pass);
2171 memset(simple_pass, *v, sizeof(simple_pass) - 1);
2173 printf("Testing machine account password policy rules\n");
2175 /* Workstation trust accounts don't seem to need to honour password quality policy */
2176 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
2180 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
2184 /* reset again, to allow another 'user' password change */
2185 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
2189 /* Try a 'short' password */
2190 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
2194 /* Try a compleatly random password */
2195 if (!test_ChangePasswordRandomBytes(p, tctx, base_acct_name, user_handle, &password)) {
2200 for (i = 0; password_fields[i]; i++) {
2201 if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
2205 /* check it was set right */
2206 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
2211 for (i = 0; password_fields[i]; i++) {
2212 if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
2216 /* check it was set right */
2217 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
2222 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
2226 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
2230 q.in.user_handle = user_handle;
2233 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
2234 if (!NT_STATUS_IS_OK(status)) {
2235 printf("QueryUserInfo level %u failed - %s\n",
2236 q.in.level, nt_errstr(status));
2239 uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
2240 if ((q.out.info->info5.acct_flags) != expected_flags) {
2241 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2242 q.out.info->info5.acct_flags,
2246 if (q.out.info->info5.rid != rid) {
2247 printf("QuerUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
2248 q.out.info->info5.rid, rid);
2254 case TORTURE_SAMR_OTHER:
2255 /* We just need the account to exist */
2261 static bool test_alias_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
2262 struct policy_handle *alias_handle,
2263 const struct dom_sid *domain_sid)
2267 if (!test_QuerySecurity(p, tctx, alias_handle)) {
2271 if (!test_QueryAliasInfo(p, tctx, alias_handle)) {
2275 if (!test_SetAliasInfo(p, tctx, alias_handle)) {
2279 if (!test_AddMemberToAlias(p, tctx, alias_handle, domain_sid)) {
2283 if (torture_setting_bool(tctx, "samba4", false)) {
2284 printf("skipping MultipleMembers Alias tests against Samba4\n");
2288 if (!test_AddMultipleMembersToAlias(p, tctx, alias_handle)) {
2296 static bool test_DeleteUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2297 struct policy_handle *user_handle)
2299 struct samr_DeleteUser d;
2301 torture_comment(tctx, "Testing DeleteUser\n");
2303 d.in.user_handle = user_handle;
2304 d.out.user_handle = user_handle;
2306 status = dcerpc_samr_DeleteUser(p, tctx, &d);
2307 torture_assert_ntstatus_ok(tctx, status, "DeleteUser");
2312 bool test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2313 struct policy_handle *handle, const char *name)
2316 struct samr_DeleteUser d;
2317 struct policy_handle user_handle;
2320 status = test_LookupName(p, mem_ctx, handle, name, &rid);
2321 if (!NT_STATUS_IS_OK(status)) {
2325 status = test_OpenUser_byname(p, mem_ctx, handle, name, &user_handle);
2326 if (!NT_STATUS_IS_OK(status)) {
2330 d.in.user_handle = &user_handle;
2331 d.out.user_handle = &user_handle;
2332 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
2333 if (!NT_STATUS_IS_OK(status)) {
2340 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
2345 static bool test_DeleteGroup_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2346 struct policy_handle *handle, const char *name)
2349 struct samr_OpenGroup r;
2350 struct samr_DeleteDomainGroup d;
2351 struct policy_handle group_handle;
2354 status = test_LookupName(p, mem_ctx, handle, name, &rid);
2355 if (!NT_STATUS_IS_OK(status)) {
2359 r.in.domain_handle = handle;
2360 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2362 r.out.group_handle = &group_handle;
2363 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
2364 if (!NT_STATUS_IS_OK(status)) {
2368 d.in.group_handle = &group_handle;
2369 d.out.group_handle = &group_handle;
2370 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
2371 if (!NT_STATUS_IS_OK(status)) {
2378 printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
2383 static bool test_DeleteAlias_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2384 struct policy_handle *domain_handle, const char *name)
2387 struct samr_OpenAlias r;
2388 struct samr_DeleteDomAlias d;
2389 struct policy_handle alias_handle;
2392 printf("testing DeleteAlias_byname\n");
2394 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
2395 if (!NT_STATUS_IS_OK(status)) {
2399 r.in.domain_handle = domain_handle;
2400 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2402 r.out.alias_handle = &alias_handle;
2403 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
2404 if (!NT_STATUS_IS_OK(status)) {
2408 d.in.alias_handle = &alias_handle;
2409 d.out.alias_handle = &alias_handle;
2410 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
2411 if (!NT_STATUS_IS_OK(status)) {
2418 printf("DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
2422 static bool test_DeleteAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2423 struct policy_handle *alias_handle)
2425 struct samr_DeleteDomAlias d;
2428 printf("Testing DeleteAlias\n");
2430 d.in.alias_handle = alias_handle;
2431 d.out.alias_handle = alias_handle;
2433 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
2434 if (!NT_STATUS_IS_OK(status)) {
2435 printf("DeleteAlias failed - %s\n", nt_errstr(status));
2442 static bool test_CreateAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2443 struct policy_handle *domain_handle,
2444 struct policy_handle *alias_handle,
2445 const struct dom_sid *domain_sid)
2448 struct samr_CreateDomAlias r;
2449 struct lsa_String name;
2453 init_lsa_String(&name, TEST_ALIASNAME);
2454 r.in.domain_handle = domain_handle;
2455 r.in.alias_name = &name;
2456 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2457 r.out.alias_handle = alias_handle;
2460 printf("Testing CreateAlias (%s)\n", r.in.alias_name->string);
2462 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
2464 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
2465 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2466 printf("Server correctly refused create of '%s'\n", r.in.alias_name->string);
2469 printf("Server should have refused create of '%s', got %s instead\n", r.in.alias_name->string,
2475 if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
2476 if (!test_DeleteAlias_byname(p, tctx, domain_handle, r.in.alias_name->string)) {
2479 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
2482 if (!NT_STATUS_IS_OK(status)) {
2483 printf("CreateAlias failed - %s\n", nt_errstr(status));
2487 if (!test_alias_ops(p, tctx, alias_handle, domain_sid)) {
2494 static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2495 const char *acct_name,
2496 struct policy_handle *domain_handle, char **password)
2504 if (!test_ChangePasswordUser(p, mem_ctx, acct_name, domain_handle, password)) {
2508 if (!test_ChangePasswordUser2(p, mem_ctx, acct_name, password, 0, true)) {
2512 if (!test_OemChangePasswordUser2(p, mem_ctx, acct_name, domain_handle, password)) {
2516 /* test what happens when setting the old password again */
2517 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, *password, 0, true)) {
2522 char simple_pass[9];
2523 char *v = generate_random_str(mem_ctx, 1);
2525 ZERO_STRUCT(simple_pass);
2526 memset(simple_pass, *v, sizeof(simple_pass) - 1);
2528 /* test what happens when picking a simple password */
2529 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, simple_pass, 0, true)) {
2534 /* set samr_SetDomainInfo level 1 with min_length 5 */
2536 struct samr_QueryDomainInfo r;
2537 struct samr_SetDomainInfo s;
2538 uint16_t len_old, len;
2539 uint32_t pwd_prop_old;
2540 int64_t min_pwd_age_old;
2545 r.in.domain_handle = domain_handle;
2548 printf("testing samr_QueryDomainInfo level 1\n");
2549 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2550 if (!NT_STATUS_IS_OK(status)) {
2554 s.in.domain_handle = domain_handle;
2556 s.in.info = r.out.info;
2558 /* remember the old min length, so we can reset it */
2559 len_old = s.in.info->info1.min_password_length;
2560 s.in.info->info1.min_password_length = len;
2561 pwd_prop_old = s.in.info->info1.password_properties;
2562 /* turn off password complexity checks for this test */
2563 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
2565 min_pwd_age_old = s.in.info->info1.min_password_age;
2566 s.in.info->info1.min_password_age = 0;
2568 printf("testing samr_SetDomainInfo level 1\n");
2569 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2570 if (!NT_STATUS_IS_OK(status)) {
2574 printf("calling test_ChangePasswordUser3 with too short password\n");
2576 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, len - 1, password, NULL, 0, true)) {
2580 s.in.info->info1.min_password_length = len_old;
2581 s.in.info->info1.password_properties = pwd_prop_old;
2582 s.in.info->info1.min_password_age = min_pwd_age_old;
2584 printf("testing samr_SetDomainInfo level 1\n");
2585 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2586 if (!NT_STATUS_IS_OK(status)) {
2594 struct samr_OpenUser r;
2595 struct samr_QueryUserInfo q;
2596 struct samr_LookupNames n;
2597 struct policy_handle user_handle;
2599 n.in.domain_handle = domain_handle;
2601 n.in.names = talloc_array(mem_ctx, struct lsa_String, 1);
2602 n.in.names[0].string = acct_name;
2604 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
2605 if (!NT_STATUS_IS_OK(status)) {
2606 printf("LookupNames failed - %s\n", nt_errstr(status));
2610 r.in.domain_handle = domain_handle;
2611 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2612 r.in.rid = n.out.rids.ids[0];
2613 r.out.user_handle = &user_handle;
2615 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
2616 if (!NT_STATUS_IS_OK(status)) {
2617 printf("OpenUser(%u) failed - %s\n", n.out.rids.ids[0], nt_errstr(status));
2621 q.in.user_handle = &user_handle;
2624 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
2625 if (!NT_STATUS_IS_OK(status)) {
2626 printf("QueryUserInfo failed - %s\n", nt_errstr(status));
2630 printf("calling test_ChangePasswordUser3 with too early password change\n");
2632 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL,
2633 q.out.info->info5.last_password_change, true)) {
2638 /* we change passwords twice - this has the effect of verifying
2639 they were changed correctly for the final call */
2640 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, true)) {
2644 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, true)) {
2651 static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2652 struct policy_handle *domain_handle,
2653 struct policy_handle *user_handle_out,
2654 struct dom_sid *domain_sid,
2655 enum torture_samr_choice which_ops)
2658 TALLOC_CTX *user_ctx;
2661 struct samr_CreateUser r;
2662 struct samr_QueryUserInfo q;
2663 struct samr_DeleteUser d;
2666 /* This call creates a 'normal' account - check that it really does */
2667 const uint32_t acct_flags = ACB_NORMAL;
2668 struct lsa_String name;
2671 struct policy_handle user_handle;
2672 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
2673 init_lsa_String(&name, TEST_ACCOUNT_NAME);
2675 r.in.domain_handle = domain_handle;
2676 r.in.account_name = &name;
2677 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2678 r.out.user_handle = &user_handle;
2681 printf("Testing CreateUser(%s)\n", r.in.account_name->string);
2683 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
2685 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
2686 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
2687 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
2690 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
2696 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
2697 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
2698 talloc_free(user_ctx);
2701 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
2703 if (!NT_STATUS_IS_OK(status)) {
2704 talloc_free(user_ctx);
2705 printf("CreateUser failed - %s\n", nt_errstr(status));
2708 q.in.user_handle = &user_handle;
2711 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
2712 if (!NT_STATUS_IS_OK(status)) {
2713 printf("QueryUserInfo level %u failed - %s\n",
2714 q.in.level, nt_errstr(status));
2717 if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
2718 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2719 q.out.info->info16.acct_flags,
2725 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
2726 acct_flags, name.string, which_ops)) {
2730 if (user_handle_out) {
2731 *user_handle_out = user_handle;
2733 printf("Testing DeleteUser (createuser test)\n");
2735 d.in.user_handle = &user_handle;
2736 d.out.user_handle = &user_handle;
2738 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
2739 if (!NT_STATUS_IS_OK(status)) {
2740 printf("DeleteUser failed - %s\n", nt_errstr(status));
2747 talloc_free(user_ctx);
2753 static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
2754 struct policy_handle *domain_handle,
2755 struct dom_sid *domain_sid,
2756 enum torture_samr_choice which_ops)
2759 struct samr_CreateUser2 r;
2760 struct samr_QueryUserInfo q;
2761 struct samr_DeleteUser d;
2762 struct policy_handle user_handle;
2764 struct lsa_String name;
2769 uint32_t acct_flags;
2770 const char *account_name;
2772 } account_types[] = {
2773 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
2774 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2775 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2776 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
2777 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2778 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2779 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
2780 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2781 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2782 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
2783 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
2784 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
2785 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2786 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2787 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
2790 for (i = 0; account_types[i].account_name; i++) {
2791 TALLOC_CTX *user_ctx;
2792 uint32_t acct_flags = account_types[i].acct_flags;
2793 uint32_t access_granted;
2794 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
2795 init_lsa_String(&name, account_types[i].account_name);
2797 r.in.domain_handle = domain_handle;
2798 r.in.account_name = &name;
2799 r.in.acct_flags = acct_flags;
2800 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2801 r.out.user_handle = &user_handle;
2802 r.out.access_granted = &access_granted;
2805 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
2807 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
2809 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
2810 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
2811 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
2814 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
2821 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
2822 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
2823 talloc_free(user_ctx);
2827 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
2830 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
2831 printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
2832 nt_errstr(status), nt_errstr(account_types[i].nt_status));
2836 if (NT_STATUS_IS_OK(status)) {
2837 q.in.user_handle = &user_handle;
2840 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
2841 if (!NT_STATUS_IS_OK(status)) {
2842 printf("QueryUserInfo level %u failed - %s\n",
2843 q.in.level, nt_errstr(status));
2846 uint32_t expected_flags = (acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
2847 if (acct_flags == ACB_NORMAL) {
2848 expected_flags |= ACB_PW_EXPIRED;
2850 if ((q.out.info->info5.acct_flags) != expected_flags) {
2851 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2852 q.out.info->info5.acct_flags,
2856 switch (acct_flags) {
2858 if (q.out.info->info5.primary_gid != DOMAIN_RID_DCS) {
2859 printf("QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n",
2860 DOMAIN_RID_DCS, q.out.info->info5.primary_gid);
2865 if (q.out.info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
2866 printf("QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
2867 DOMAIN_RID_DOMAIN_MEMBERS, q.out.info->info5.primary_gid);
2872 if (q.out.info->info5.primary_gid != DOMAIN_RID_USERS) {
2873 printf("QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n",
2874 DOMAIN_RID_USERS, q.out.info->info5.primary_gid);
2881 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
2882 acct_flags, name.string, which_ops)) {
2886 printf("Testing DeleteUser (createuser2 test)\n");
2888 d.in.user_handle = &user_handle;
2889 d.out.user_handle = &user_handle;
2891 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
2892 if (!NT_STATUS_IS_OK(status)) {
2893 printf("DeleteUser failed - %s\n", nt_errstr(status));
2897 talloc_free(user_ctx);
2903 static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2904 struct policy_handle *handle)
2907 struct samr_QueryAliasInfo r;
2908 uint16_t levels[] = {1, 2, 3};
2912 for (i=0;i<ARRAY_SIZE(levels);i++) {
2913 printf("Testing QueryAliasInfo level %u\n", levels[i]);
2915 r.in.alias_handle = handle;
2916 r.in.level = levels[i];
2918 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
2919 if (!NT_STATUS_IS_OK(status)) {
2920 printf("QueryAliasInfo level %u failed - %s\n",
2921 levels[i], nt_errstr(status));
2929 static bool test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2930 struct policy_handle *handle)
2933 struct samr_QueryGroupInfo r;
2934 uint16_t levels[] = {1, 2, 3, 4, 5};
2938 for (i=0;i<ARRAY_SIZE(levels);i++) {
2939 printf("Testing QueryGroupInfo level %u\n", levels[i]);
2941 r.in.group_handle = handle;
2942 r.in.level = levels[i];
2944 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
2945 if (!NT_STATUS_IS_OK(status)) {
2946 printf("QueryGroupInfo level %u failed - %s\n",
2947 levels[i], nt_errstr(status));
2955 static bool test_QueryGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2956 struct policy_handle *handle)
2959 struct samr_QueryGroupMember r;
2962 printf("Testing QueryGroupMember\n");
2964 r.in.group_handle = handle;
2966 status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &r);
2967 if (!NT_STATUS_IS_OK(status)) {
2968 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
2976 static bool test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2977 struct policy_handle *handle)
2980 struct samr_QueryGroupInfo r;
2981 struct samr_SetGroupInfo s;
2982 uint16_t levels[] = {1, 2, 3, 4};
2983 uint16_t set_ok[] = {0, 1, 1, 1};
2987 for (i=0;i<ARRAY_SIZE(levels);i++) {
2988 printf("Testing QueryGroupInfo level %u\n", levels[i]);
2990 r.in.group_handle = handle;
2991 r.in.level = levels[i];
2993 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
2994 if (!NT_STATUS_IS_OK(status)) {
2995 printf("QueryGroupInfo level %u failed - %s\n",
2996 levels[i], nt_errstr(status));
3000 printf("Testing SetGroupInfo level %u\n", levels[i]);
3002 s.in.group_handle = handle;
3003 s.in.level = levels[i];
3004 s.in.info = r.out.info;
3007 /* disabled this, as it changes the name only from the point of view of samr,
3008 but leaves the name from the point of view of w2k3 internals (and ldap). This means
3009 the name is still reserved, so creating the old name fails, but deleting by the old name
3011 if (s.in.level == 2) {
3012 init_lsa_String(&s.in.info->string, "NewName");
3016 if (s.in.level == 4) {
3017 init_lsa_String(&s.in.info->description, "test description");
3020 status = dcerpc_samr_SetGroupInfo(p, mem_ctx, &s);
3022 if (!NT_STATUS_IS_OK(status)) {
3023 printf("SetGroupInfo level %u failed - %s\n",
3024 r.in.level, nt_errstr(status));
3029 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
3030 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
3031 r.in.level, nt_errstr(status));
3041 static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3042 struct policy_handle *handle)
3045 struct samr_QueryUserInfo r;
3046 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
3047 11, 12, 13, 14, 16, 17, 20, 21};
3051 for (i=0;i<ARRAY_SIZE(levels);i++) {
3052 printf("Testing QueryUserInfo level %u\n", levels[i]);
3054 r.in.user_handle = handle;
3055 r.in.level = levels[i];
3057 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
3058 if (!NT_STATUS_IS_OK(status)) {
3059 printf("QueryUserInfo level %u failed - %s\n",
3060 levels[i], nt_errstr(status));
3068 static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3069 struct policy_handle *handle)
3072 struct samr_QueryUserInfo2 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 QueryUserInfo2 level %u\n", levels[i]);
3081 r.in.user_handle = handle;
3082 r.in.level = levels[i];
3084 status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r);
3085 if (!NT_STATUS_IS_OK(status)) {
3086 printf("QueryUserInfo2 level %u failed - %s\n",
3087 levels[i], nt_errstr(status));
3095 static bool test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3096 struct policy_handle *handle, uint32_t rid)
3099 struct samr_OpenUser r;
3100 struct policy_handle user_handle;
3103 printf("Testing OpenUser(%u)\n", rid);
3105 r.in.domain_handle = handle;
3106 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3108 r.out.user_handle = &user_handle;
3110 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3111 if (!NT_STATUS_IS_OK(status)) {
3112 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
3116 if (!test_QuerySecurity(p, mem_ctx, &user_handle)) {
3120 if (!test_QueryUserInfo(p, mem_ctx, &user_handle)) {
3124 if (!test_QueryUserInfo2(p, mem_ctx, &user_handle)) {
3128 if (!test_GetUserPwInfo(p, mem_ctx, &user_handle)) {
3132 if (!test_GetGroupsForUser(p,mem_ctx, &user_handle)) {
3136 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
3143 static bool test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3144 struct policy_handle *handle, uint32_t rid)
3147 struct samr_OpenGroup r;
3148 struct policy_handle group_handle;
3151 printf("Testing OpenGroup(%u)\n", rid);
3153 r.in.domain_handle = handle;
3154 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3156 r.out.group_handle = &group_handle;
3158 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
3159 if (!NT_STATUS_IS_OK(status)) {
3160 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
3164 if (!test_QuerySecurity(p, mem_ctx, &group_handle)) {
3168 if (!test_QueryGroupInfo(p, mem_ctx, &group_handle)) {
3172 if (!test_QueryGroupMember(p, mem_ctx, &group_handle)) {
3176 if (!test_samr_handle_Close(p, mem_ctx, &group_handle)) {
3183 static bool test_OpenAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
3184 struct policy_handle *handle, uint32_t rid)
3187 struct samr_OpenAlias r;
3188 struct policy_handle alias_handle;
3191 torture_comment(tctx, "Testing OpenAlias(%u)\n", rid);
3193 r.in.domain_handle = handle;
3194 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3196 r.out.alias_handle = &alias_handle;
3198 status = dcerpc_samr_OpenAlias(p, tctx, &r);
3199 if (!NT_STATUS_IS_OK(status)) {
3200 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
3204 if (!test_QuerySecurity(p, tctx, &alias_handle)) {
3208 if (!test_QueryAliasInfo(p, tctx, &alias_handle)) {
3212 if (!test_GetMembersInAlias(p, tctx, &alias_handle)) {
3216 if (!test_samr_handle_Close(p, tctx, &alias_handle)) {
3223 static bool check_mask(struct dcerpc_pipe *p, struct torture_context *tctx,
3224 struct policy_handle *handle, uint32_t rid,
3225 uint32_t acct_flag_mask)
3228 struct samr_OpenUser r;
3229 struct samr_QueryUserInfo q;
3230 struct policy_handle user_handle;
3233 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
3235 r.in.domain_handle = handle;
3236 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3238 r.out.user_handle = &user_handle;
3240 status = dcerpc_samr_OpenUser(p, tctx, &r);
3241 if (!NT_STATUS_IS_OK(status)) {
3242 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
3246 q.in.user_handle = &user_handle;
3249 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
3250 if (!NT_STATUS_IS_OK(status)) {
3251 printf("QueryUserInfo level 16 failed - %s\n",
3255 if ((acct_flag_mask & q.out.info->info16.acct_flags) == 0) {
3256 printf("Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
3257 acct_flag_mask, q.out.info->info16.acct_flags, rid);
3262 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
3269 static bool test_EnumDomainUsers(struct dcerpc_pipe *p, struct torture_context *tctx,
3270 struct policy_handle *handle)
3272 NTSTATUS status = STATUS_MORE_ENTRIES;
3273 struct samr_EnumDomainUsers r;
3274 uint32_t mask, resume_handle=0;
3277 struct samr_LookupNames n;
3278 struct samr_LookupRids lr ;
3279 struct lsa_Strings names;
3280 struct samr_Ids types;
3282 uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
3283 ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
3284 ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
3287 printf("Testing EnumDomainUsers\n");
3289 for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
3290 r.in.domain_handle = handle;
3291 r.in.resume_handle = &resume_handle;
3292 r.in.acct_flags = mask = masks[mask_idx];
3293 r.in.max_size = (uint32_t)-1;
3294 r.out.resume_handle = &resume_handle;
3296 status = dcerpc_samr_EnumDomainUsers(p, tctx, &r);
3297 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
3298 !NT_STATUS_IS_OK(status)) {
3299 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
3303 torture_assert(tctx, r.out.sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
3305 if (r.out.sam->count == 0) {
3309 for (i=0;i<r.out.sam->count;i++) {
3311 if (!check_mask(p, tctx, handle, r.out.sam->entries[i].idx, mask)) {
3314 } else if (!test_OpenUser(p, tctx, handle, r.out.sam->entries[i].idx)) {
3320 printf("Testing LookupNames\n");
3321 n.in.domain_handle = handle;
3322 n.in.num_names = r.out.sam->count;
3323 n.in.names = talloc_array(tctx, struct lsa_String, r.out.sam->count);
3324 for (i=0;i<r.out.sam->count;i++) {
3325 n.in.names[i].string = r.out.sam->entries[i].name.string;
3327 status = dcerpc_samr_LookupNames(p, tctx, &n);
3328 if (!NT_STATUS_IS_OK(status)) {
3329 printf("LookupNames failed - %s\n", nt_errstr(status));
3334 printf("Testing LookupRids\n");
3335 lr.in.domain_handle = handle;
3336 lr.in.num_rids = r.out.sam->count;
3337 lr.in.rids = talloc_array(tctx, uint32_t, r.out.sam->count);
3338 lr.out.names = &names;
3339 lr.out.types = &types;
3340 for (i=0;i<r.out.sam->count;i++) {
3341 lr.in.rids[i] = r.out.sam->entries[i].idx;
3343 status = dcerpc_samr_LookupRids(p, tctx, &lr);
3344 torture_assert_ntstatus_ok(tctx, status, "LookupRids");
3350 try blasting the server with a bunch of sync requests
3352 static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, struct torture_context *tctx,
3353 struct policy_handle *handle)
3356 struct samr_EnumDomainUsers r;
3357 uint32_t resume_handle=0;
3359 #define ASYNC_COUNT 100
3360 struct rpc_request *req[ASYNC_COUNT];
3362 if (!torture_setting_bool(tctx, "dangerous", false)) {
3363 torture_skip(tctx, "samr async test disabled - enable dangerous tests to use\n");
3366 torture_comment(tctx, "Testing EnumDomainUsers_async\n");
3368 r.in.domain_handle = handle;
3369 r.in.resume_handle = &resume_handle;
3370 r.in.acct_flags = 0;
3371 r.in.max_size = (uint32_t)-1;
3372 r.out.resume_handle = &resume_handle;
3374 for (i=0;i<ASYNC_COUNT;i++) {
3375 req[i] = dcerpc_samr_EnumDomainUsers_send(p, tctx, &r);
3378 for (i=0;i<ASYNC_COUNT;i++) {
3379 status = dcerpc_ndr_request_recv(req[i]);
3380 if (!NT_STATUS_IS_OK(status)) {
3381 printf("EnumDomainUsers[%d] failed - %s\n",
3382 i, nt_errstr(status));
3387 torture_comment(tctx, "%d async requests OK\n", i);
3392 static bool test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3393 struct policy_handle *handle)
3396 struct samr_EnumDomainGroups r;
3397 uint32_t resume_handle=0;
3401 printf("Testing EnumDomainGroups\n");
3403 r.in.domain_handle = handle;
3404 r.in.resume_handle = &resume_handle;
3405 r.in.max_size = (uint32_t)-1;
3406 r.out.resume_handle = &resume_handle;
3408 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
3409 if (!NT_STATUS_IS_OK(status)) {
3410 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
3418 for (i=0;i<r.out.sam->count;i++) {
3419 if (!test_OpenGroup(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
3427 static bool test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3428 struct policy_handle *handle)
3431 struct samr_EnumDomainAliases r;
3432 uint32_t resume_handle=0;
3436 printf("Testing EnumDomainAliases\n");
3438 r.in.domain_handle = handle;
3439 r.in.resume_handle = &resume_handle;
3440 r.in.acct_flags = (uint32_t)-1;
3441 r.out.resume_handle = &resume_handle;
3443 status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
3444 if (!NT_STATUS_IS_OK(status)) {
3445 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
3453 for (i=0;i<r.out.sam->count;i++) {
3454 if (!test_OpenAlias(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
3462 static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3463 struct policy_handle *handle)
3466 struct samr_GetDisplayEnumerationIndex r;
3468 uint16_t levels[] = {1, 2, 3, 4, 5};
3469 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
3470 struct lsa_String name;
3474 for (i=0;i<ARRAY_SIZE(levels);i++) {
3475 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
3477 init_lsa_String(&name, TEST_ACCOUNT_NAME);
3479 r.in.domain_handle = handle;
3480 r.in.level = levels[i];
3484 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
3487 !NT_STATUS_IS_OK(status) &&
3488 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3489 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
3490 levels[i], nt_errstr(status));
3494 init_lsa_String(&name, "zzzzzzzz");
3496 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
3498 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3499 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
3500 levels[i], nt_errstr(status));
3508 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3509 struct policy_handle *handle)
3512 struct samr_GetDisplayEnumerationIndex2 r;
3514 uint16_t levels[] = {1, 2, 3, 4, 5};
3515 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
3516 struct lsa_String name;
3520 for (i=0;i<ARRAY_SIZE(levels);i++) {
3521 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
3523 init_lsa_String(&name, TEST_ACCOUNT_NAME);
3525 r.in.domain_handle = handle;
3526 r.in.level = levels[i];
3530 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
3532 !NT_STATUS_IS_OK(status) &&
3533 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3534 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
3535 levels[i], nt_errstr(status));
3539 init_lsa_String(&name, "zzzzzzzz");
3541 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
3542 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3543 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
3544 levels[i], nt_errstr(status));
3552 #define STRING_EQUAL_QUERY(s1, s2, user) \
3553 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
3554 /* odd, but valid */ \
3555 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
3556 printf("%s mismatch for %s: %s != %s (%s)\n", \
3557 #s1, user.string, s1.string, s2.string, __location__); \
3560 #define INT_EQUAL_QUERY(s1, s2, user) \
3562 printf("%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
3563 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
3567 static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3568 struct samr_QueryDisplayInfo *querydisplayinfo,
3569 bool *seen_testuser)
3571 struct samr_OpenUser r;
3572 struct samr_QueryUserInfo q;
3573 struct policy_handle user_handle;
3576 r.in.domain_handle = querydisplayinfo->in.domain_handle;
3577 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3578 for (i = 0; ; i++) {
3579 switch (querydisplayinfo->in.level) {
3581 if (i >= querydisplayinfo->out.info.info1.count) {
3584 r.in.rid = querydisplayinfo->out.info.info1.entries[i].rid;
3587 if (i >= querydisplayinfo->out.info.info2.count) {
3590 r.in.rid = querydisplayinfo->out.info.info2.entries[i].rid;
3596 /* Not interested in validating just the account name */
3600 r.out.user_handle = &user_handle;
3602 switch (querydisplayinfo->in.level) {
3605 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3606 if (!NT_STATUS_IS_OK(status)) {
3607 printf("OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(status));
3612 q.in.user_handle = &user_handle;
3614 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
3615 if (!NT_STATUS_IS_OK(status)) {
3616 printf("QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(status));
3620 switch (querydisplayinfo->in.level) {
3622 if (seen_testuser && strcmp(q.out.info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
3623 *seen_testuser = true;
3625 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].full_name,
3626 q.out.info->info21.full_name, q.out.info->info21.account_name);
3627 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].account_name,
3628 q.out.info->info21.account_name, q.out.info->info21.account_name);
3629 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].description,
3630 q.out.info->info21.description, q.out.info->info21.account_name);
3631 INT_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].rid,
3632 q.out.info->info21.rid, q.out.info->info21.account_name);
3633 INT_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].acct_flags,
3634 q.out.info->info21.acct_flags, q.out.info->info21.account_name);
3638 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].account_name,
3639 q.out.info->info21.account_name, q.out.info->info21.account_name);
3640 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].description,
3641 q.out.info->info21.description, q.out.info->info21.account_name);
3642 INT_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].rid,
3643 q.out.info->info21.rid, q.out.info->info21.account_name);
3644 INT_EQUAL_QUERY((querydisplayinfo->out.info.info2.entries[i].acct_flags & ~ACB_NORMAL),
3645 q.out.info->info21.acct_flags, q.out.info->info21.account_name);
3647 if (!(querydisplayinfo->out.info.info2.entries[i].acct_flags & ACB_NORMAL)) {
3648 printf("Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
3649 q.out.info->info21.account_name.string);
3652 if (!(q.out.info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
3653 printf("Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
3654 q.out.info->info21.account_name.string,
3655 querydisplayinfo->out.info.info2.entries[i].acct_flags,
3656 q.out.info->info21.acct_flags);
3663 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
3670 static bool test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3671 struct policy_handle *handle)
3674 struct samr_QueryDisplayInfo r;
3675 struct samr_QueryDomainInfo dom_info;
3677 uint16_t levels[] = {1, 2, 3, 4, 5};
3679 bool seen_testuser = false;
3681 for (i=0;i<ARRAY_SIZE(levels);i++) {
3682 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
3685 status = STATUS_MORE_ENTRIES;
3686 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
3687 r.in.domain_handle = handle;
3688 r.in.level = levels[i];
3689 r.in.max_entries = 2;
3690 r.in.buf_size = (uint32_t)-1;
3692 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
3693 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(status)) {
3694 printf("QueryDisplayInfo level %u failed - %s\n",
3695 levels[i], nt_errstr(status));
3698 switch (r.in.level) {
3700 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, &seen_testuser)) {
3703 r.in.start_idx += r.out.info.info1.count;
3706 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, NULL)) {
3709 r.in.start_idx += r.out.info.info2.count;
3712 r.in.start_idx += r.out.info.info3.count;
3715 r.in.start_idx += r.out.info.info4.count;
3718 r.in.start_idx += r.out.info.info5.count;
3722 dom_info.in.domain_handle = handle;
3723 dom_info.in.level = 2;
3724 /* Check number of users returned is correct */
3725 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &dom_info);
3726 if (!NT_STATUS_IS_OK(status)) {
3727 printf("QueryDomainInfo level %u failed - %s\n",
3728 r.in.level, nt_errstr(status));
3732 switch (r.in.level) {
3735 if (dom_info.out.info->general.num_users < r.in.start_idx) {
3736 printf("QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
3737 r.in.start_idx, dom_info.out.info->general.num_groups,
3738 dom_info.out.info->general.domain_name.string);
3741 if (!seen_testuser) {
3742 struct policy_handle user_handle;
3743 if (NT_STATUS_IS_OK(test_OpenUser_byname(p, mem_ctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
3744 printf("Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
3745 dom_info.out.info->general.domain_name.string);
3747 test_samr_handle_Close(p, mem_ctx, &user_handle);
3753 if (dom_info.out.info->general.num_groups != r.in.start_idx) {
3754 printf("QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
3755 r.in.start_idx, dom_info.out.info->general.num_groups,
3756 dom_info.out.info->general.domain_name.string);
3768 static bool test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3769 struct policy_handle *handle)
3772 struct samr_QueryDisplayInfo2 r;
3774 uint16_t levels[] = {1, 2, 3, 4, 5};
3777 for (i=0;i<ARRAY_SIZE(levels);i++) {
3778 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
3780 r.in.domain_handle = handle;
3781 r.in.level = levels[i];
3783 r.in.max_entries = 1000;
3784 r.in.buf_size = (uint32_t)-1;
3786 status = dcerpc_samr_QueryDisplayInfo2(p, mem_ctx, &r);
3787 if (!NT_STATUS_IS_OK(status)) {
3788 printf("QueryDisplayInfo2 level %u failed - %s\n",
3789 levels[i], nt_errstr(status));
3797 static bool test_QueryDisplayInfo3(struct dcerpc_pipe *p, struct torture_context *tctx,
3798 struct policy_handle *handle)
3801 struct samr_QueryDisplayInfo3 r;
3803 uint16_t levels[] = {1, 2, 3, 4, 5};
3806 for (i=0;i<ARRAY_SIZE(levels);i++) {
3807 torture_comment(tctx, "Testing QueryDisplayInfo3 level %u\n", levels[i]);
3809 r.in.domain_handle = handle;
3810 r.in.level = levels[i];
3812 r.in.max_entries = 1000;
3813 r.in.buf_size = (uint32_t)-1;
3815 status = dcerpc_samr_QueryDisplayInfo3(p, tctx, &r);
3816 if (!NT_STATUS_IS_OK(status)) {
3817 printf("QueryDisplayInfo3 level %u failed - %s\n",
3818 levels[i], nt_errstr(status));
3827 static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3828 struct policy_handle *handle)
3831 struct samr_QueryDisplayInfo r;
3834 printf("Testing QueryDisplayInfo continuation\n");
3836 r.in.domain_handle = handle;
3839 r.in.max_entries = 1;
3840 r.in.buf_size = (uint32_t)-1;
3843 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
3844 if (NT_STATUS_IS_OK(status) && r.out.returned_size != 0) {
3845 if (r.out.info.info1.entries[0].idx != r.in.start_idx + 1) {
3846 printf("expected idx %d but got %d\n",
3848 r.out.info.info1.entries[0].idx);
3852 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
3853 !NT_STATUS_IS_OK(status)) {
3854 printf("QueryDisplayInfo level %u failed - %s\n",
3855 r.in.level, nt_errstr(status));
3860 } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
3861 NT_STATUS_IS_OK(status)) &&
3862 r.out.returned_size != 0);
3867 static bool test_QueryDomainInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
3868 struct policy_handle *handle)
3871 struct samr_QueryDomainInfo r;
3872 struct samr_SetDomainInfo s;
3873 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
3874 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
3877 const char *domain_comment = talloc_asprintf(tctx,
3878 "Tortured by Samba4 RPC-SAMR: %s",
3879 timestring(tctx, time(NULL)));
3881 s.in.domain_handle = handle;
3883 s.in.info = talloc(tctx, union samr_DomainInfo);
3885 s.in.info->oem.oem_information.string = domain_comment;
3886 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
3887 if (!NT_STATUS_IS_OK(status)) {
3888 printf("SetDomainInfo level %u (set comment) failed - %s\n",
3889 r.in.level, nt_errstr(status));
3893 for (i=0;i<ARRAY_SIZE(levels);i++) {
3894 torture_comment(tctx, "Testing QueryDomainInfo level %u\n", levels[i]);
3896 r.in.domain_handle = handle;
3897 r.in.level = levels[i];
3899 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
3900 if (!NT_STATUS_IS_OK(status)) {
3901 printf("QueryDomainInfo level %u failed - %s\n",
3902 r.in.level, nt_errstr(status));
3907 switch (levels[i]) {
3909 if (strcmp(r.out.info->general.oem_information.string, domain_comment) != 0) {
3910 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
3911 levels[i], r.out.info->general.oem_information.string, domain_comment);
3914 if (!r.out.info->general.primary.string) {
3915 printf("QueryDomainInfo level %u returned no PDC name\n",
3918 } else if (r.out.info->general.role == SAMR_ROLE_DOMAIN_PDC) {
3919 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), r.out.info->general.primary.string) != 0) {
3920 printf("QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
3921 levels[i], r.out.info->general.primary.string, dcerpc_server_name(p));
3926 if (strcmp(r.out.info->oem.oem_information.string, domain_comment) != 0) {
3927 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
3928 levels[i], r.out.info->oem.oem_information.string, domain_comment);
3933 if (!r.out.info->info6.primary.string) {
3934 printf("QueryDomainInfo level %u returned no PDC name\n",
3940 if (strcmp(r.out.info->general2.general.oem_information.string, domain_comment) != 0) {
3941 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
3942 levels[i], r.out.info->general2.general.oem_information.string, domain_comment);
3948 torture_comment(tctx, "Testing SetDomainInfo level %u\n", levels[i]);
3950 s.in.domain_handle = handle;
3951 s.in.level = levels[i];
3952 s.in.info = r.out.info;
3954 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
3956 if (!NT_STATUS_IS_OK(status)) {
3957 printf("SetDomainInfo level %u failed - %s\n",
3958 r.in.level, nt_errstr(status));
3963 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
3964 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
3965 r.in.level, nt_errstr(status));
3971 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
3972 if (!NT_STATUS_IS_OK(status)) {
3973 printf("QueryDomainInfo level %u failed - %s\n",
3974 r.in.level, nt_errstr(status));
3984 static bool test_QueryDomainInfo2(struct dcerpc_pipe *p, struct torture_context *tctx,
3985 struct policy_handle *handle)
3988 struct samr_QueryDomainInfo2 r;
3989 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
3993 for (i=0;i<ARRAY_SIZE(levels);i++) {
3994 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
3996 r.in.domain_handle = handle;
3997 r.in.level = levels[i];
3999 status = dcerpc_samr_QueryDomainInfo2(p, tctx, &r);
4000 if (!NT_STATUS_IS_OK(status)) {
4001 printf("QueryDomainInfo2 level %u failed - %s\n",
4002 r.in.level, nt_errstr(status));
4011 /* Test whether querydispinfo level 5 and enumdomgroups return the same
4012 set of group names. */
4013 static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx,
4014 struct policy_handle *handle)
4016 struct samr_EnumDomainGroups q1;
4017 struct samr_QueryDisplayInfo q2;
4019 uint32_t resume_handle=0;
4024 const char **names = NULL;
4026 torture_comment(tctx, "Testing coherency of querydispinfo vs enumdomgroups\n");
4028 q1.in.domain_handle = handle;
4029 q1.in.resume_handle = &resume_handle;
4031 q1.out.resume_handle = &resume_handle;
4033 status = STATUS_MORE_ENTRIES;
4034 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
4035 status = dcerpc_samr_EnumDomainGroups(p, tctx, &q1);
4037 if (!NT_STATUS_IS_OK(status) &&
4038 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
4041 for (i=0; i<q1.out.num_entries; i++) {
4042 add_string_to_array(tctx,
4043 q1.out.sam->entries[i].name.string,
4044 &names, &num_names);
4048 torture_assert_ntstatus_ok(tctx, status, "EnumDomainGroups");
4050 torture_assert(tctx, q1.out.sam, "EnumDomainGroups failed to return q1.out.sam");
4052 q2.in.domain_handle = handle;
4054 q2.in.start_idx = 0;
4055 q2.in.max_entries = 5;
4056 q2.in.buf_size = (uint32_t)-1;
4058 status = STATUS_MORE_ENTRIES;
4059 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
4060 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &q2);
4062 if (!NT_STATUS_IS_OK(status) &&
4063 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
4066 for (i=0; i<q2.out.info.info5.count; i++) {
4068 const char *name = q2.out.info.info5.entries[i].account_name.string;
4070 for (j=0; j<num_names; j++) {
4071 if (names[j] == NULL)
4073 if (strequal(names[j], name)) {
4081 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
4086 q2.in.start_idx += q2.out.info.info5.count;
4089 if (!NT_STATUS_IS_OK(status)) {
4090 printf("QueryDisplayInfo level 5 failed - %s\n",
4095 for (i=0; i<num_names; i++) {
4096 if (names[i] != NULL) {
4097 printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
4106 static bool test_DeleteDomainGroup(struct dcerpc_pipe *p, struct torture_context *tctx,
4107 struct policy_handle *group_handle)
4109 struct samr_DeleteDomainGroup d;
4112 torture_comment(tctx, "Testing DeleteDomainGroup\n");
4114 d.in.group_handle = group_handle;
4115 d.out.group_handle = group_handle;
4117 status = dcerpc_samr_DeleteDomainGroup(p, tctx, &d);
4118 torture_assert_ntstatus_ok(tctx, status, "DeleteDomainGroup");
4123 static bool test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
4124 struct policy_handle *domain_handle)
4126 struct samr_TestPrivateFunctionsDomain r;
4130 torture_comment(tctx, "Testing TestPrivateFunctionsDomain\n");
4132 r.in.domain_handle = domain_handle;
4134 status = dcerpc_samr_TestPrivateFunctionsDomain(p, tctx, &r);
4135 torture_assert_ntstatus_equal(tctx, NT_STATUS_NOT_IMPLEMENTED, status, "TestPrivateFunctionsDomain");
4140 static bool test_RidToSid(struct dcerpc_pipe *p, struct torture_context *tctx,
4141 struct dom_sid *domain_sid,
4142 struct policy_handle *domain_handle)
4144 struct samr_RidToSid r;
4147 struct dom_sid *calc_sid;
4148 int rids[] = { 0, 42, 512, 10200 };
4151 for (i=0;i<ARRAY_SIZE(rids);i++) {
4152 torture_comment(tctx, "Testing RidToSid\n");
4154 calc_sid = dom_sid_dup(tctx, domain_sid);
4155 r.in.domain_handle = domain_handle;
4158 status = dcerpc_samr_RidToSid(p, tctx, &r);
4159 if (!NT_STATUS_IS_OK(status)) {
4160 printf("RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
4163 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
4165 if (!dom_sid_equal(calc_sid, r.out.sid)) {
4166 printf("RidToSid for %d failed - got %s, expected %s\n", rids[i],
4167 dom_sid_string(tctx, r.out.sid),
4168 dom_sid_string(tctx, calc_sid));
4177 static bool test_GetBootKeyInformation(struct dcerpc_pipe *p, struct torture_context *tctx,
4178 struct policy_handle *domain_handle)
4180 struct samr_GetBootKeyInformation r;
4184 torture_comment(tctx, "Testing GetBootKeyInformation\n");
4186 r.in.domain_handle = domain_handle;
4188 status = dcerpc_samr_GetBootKeyInformation(p, tctx, &r);
4189 if (!NT_STATUS_IS_OK(status)) {
4190 /* w2k3 seems to fail this sometimes and pass it sometimes */
4191 torture_comment(tctx, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
4197 static bool test_AddGroupMember(struct dcerpc_pipe *p, struct torture_context *tctx,
4198 struct policy_handle *domain_handle,
4199 struct policy_handle *group_handle)
4202 struct samr_AddGroupMember r;
4203 struct samr_DeleteGroupMember d;
4204 struct samr_QueryGroupMember q;
4205 struct samr_SetMemberAttributesOfGroup s;
4208 status = test_LookupName(p, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
4209 torture_assert_ntstatus_ok(tctx, status, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME);
4211 r.in.group_handle = group_handle;
4213 r.in.flags = 0; /* ??? */
4215 torture_comment(tctx, "Testing AddGroupMember and DeleteGroupMember\n");
4217 d.in.group_handle = group_handle;
4220 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
4221 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_NOT_IN_GROUP, status, "DeleteGroupMember");
4223 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4224 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
4226 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4227 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_IN_GROUP, status, "AddGroupMember");
4229 if (torture_setting_bool(tctx, "samba4", false)) {
4230 torture_comment(tctx, "skipping SetMemberAttributesOfGroup test against Samba4\n");
4232 /* this one is quite strange. I am using random inputs in the
4233 hope of triggering an error that might give us a clue */
4235 s.in.group_handle = group_handle;
4236 s.in.unknown1 = random();
4237 s.in.unknown2 = random();
4239 status = dcerpc_samr_SetMemberAttributesOfGroup(p, tctx, &s);
4240 torture_assert_ntstatus_ok(tctx, status, "SetMemberAttributesOfGroup");
4243 q.in.group_handle = group_handle;
4245 status = dcerpc_samr_QueryGroupMember(p, tctx, &q);
4246 torture_assert_ntstatus_ok(tctx, status, "QueryGroupMember");
4248 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
4249 torture_assert_ntstatus_ok(tctx, status, "DeleteGroupMember");
4251 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4252 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
4258 static bool test_CreateDomainGroup(struct dcerpc_pipe *p,
4259 struct torture_context *tctx,
4260 struct policy_handle *domain_handle,
4261 struct policy_handle *group_handle,
4262 struct dom_sid *domain_sid)
4265 struct samr_CreateDomainGroup r;
4267 struct lsa_String name;
4270 init_lsa_String(&name, TEST_GROUPNAME);
4272 r.in.domain_handle = domain_handle;
4274 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4275 r.out.group_handle = group_handle;
4278 printf("Testing CreateDomainGroup(%s)\n", r.in.name->string);
4280 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
4282 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
4283 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
4284 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.name->string);
4287 printf("Server should have refused create of '%s', got %s instead\n", r.in.name->string,
4293 if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS)) {
4294 if (!test_DeleteGroup_byname(p, tctx, domain_handle, r.in.name->string)) {
4295 printf("CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
4299 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
4301 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
4302 if (!test_DeleteUser_byname(p, tctx, domain_handle, r.in.name->string)) {
4304 printf("CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
4308 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
4310 torture_assert_ntstatus_ok(tctx, status, "CreateDomainGroup");
4312 if (!test_AddGroupMember(p, tctx, domain_handle, group_handle)) {
4313 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
4317 if (!test_SetGroupInfo(p, tctx, group_handle)) {
4326 its not totally clear what this does. It seems to accept any sid you like.
4328 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p,
4329 struct torture_context *tctx,
4330 struct policy_handle *domain_handle)
4333 struct samr_RemoveMemberFromForeignDomain r;
4335 r.in.domain_handle = domain_handle;
4336 r.in.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-12-34-56-78");
4338 status = dcerpc_samr_RemoveMemberFromForeignDomain(p, tctx, &r);
4339 torture_assert_ntstatus_ok(tctx, status, "RemoveMemberFromForeignDomain");
4346 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
4347 struct policy_handle *handle);
4349 static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
4350 struct policy_handle *handle, struct dom_sid *sid,
4351 enum torture_samr_choice which_ops)
4354 struct samr_OpenDomain r;
4355 struct policy_handle domain_handle;
4356 struct policy_handle alias_handle;
4357 struct policy_handle user_handle;
4358 struct policy_handle group_handle;
4361 ZERO_STRUCT(alias_handle);
4362 ZERO_STRUCT(user_handle);
4363 ZERO_STRUCT(group_handle);
4364 ZERO_STRUCT(domain_handle);
4366 torture_comment(tctx, "Testing OpenDomain of %s\n", dom_sid_string(tctx, sid));
4368 r.in.connect_handle = handle;
4369 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4371 r.out.domain_handle = &domain_handle;
4373 status = dcerpc_samr_OpenDomain(p, tctx, &r);
4374 torture_assert_ntstatus_ok(tctx, status, "OpenDomain");
4376 /* run the domain tests with the main handle closed - this tests
4377 the servers reference counting */
4378 ret &= test_samr_handle_Close(p, tctx, handle);
4380 switch (which_ops) {
4381 case TORTURE_SAMR_USER_ATTRIBUTES:
4382 case TORTURE_SAMR_PASSWORDS:
4383 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops);
4384 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops);
4385 /* This test needs 'complex' users to validate */
4386 ret &= test_QueryDisplayInfo(p, tctx, &domain_handle);
4388 printf("Testing PASSWORDS or ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
4391 case TORTURE_SAMR_OTHER:
4392 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops);
4394 printf("Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid));
4396 ret &= test_QuerySecurity(p, tctx, &domain_handle);
4397 ret &= test_RemoveMemberFromForeignDomain(p, tctx, &domain_handle);
4398 ret &= test_CreateAlias(p, tctx, &domain_handle, &alias_handle, sid);
4399 ret &= test_CreateDomainGroup(p, tctx, &domain_handle, &group_handle, sid);
4400 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
4401 ret &= test_QueryDomainInfo2(p, tctx, &domain_handle);
4402 ret &= test_EnumDomainUsers(p, tctx, &domain_handle);
4403 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
4404 ret &= test_EnumDomainGroups(p, tctx, &domain_handle);
4405 ret &= test_EnumDomainAliases(p, tctx, &domain_handle);
4406 ret &= test_QueryDisplayInfo2(p, tctx, &domain_handle);
4407 ret &= test_QueryDisplayInfo3(p, tctx, &domain_handle);
4408 ret &= test_QueryDisplayInfo_continue(p, tctx, &domain_handle);
4410 if (torture_setting_bool(tctx, "samba4", false)) {
4411 torture_comment(tctx, "skipping GetDisplayEnumerationIndex test against Samba4\n");
4413 ret &= test_GetDisplayEnumerationIndex(p, tctx, &domain_handle);
4414 ret &= test_GetDisplayEnumerationIndex2(p, tctx, &domain_handle);
4416 ret &= test_GroupList(p, tctx, &domain_handle);
4417 ret &= test_TestPrivateFunctionsDomain(p, tctx, &domain_handle);
4418 ret &= test_RidToSid(p, tctx, sid, &domain_handle);
4419 ret &= test_GetBootKeyInformation(p, tctx, &domain_handle);
4421 torture_comment(tctx, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx, sid));
4426 if (!policy_handle_empty(&user_handle) &&
4427 !test_DeleteUser(p, tctx, &user_handle)) {
4431 if (!policy_handle_empty(&alias_handle) &&
4432 !test_DeleteAlias(p, tctx, &alias_handle)) {
4436 if (!policy_handle_empty(&group_handle) &&
4437 !test_DeleteDomainGroup(p, tctx, &group_handle)) {
4441 ret &= test_samr_handle_Close(p, tctx, &domain_handle);
4443 /* reconnect the main handle */
4444 ret &= test_Connect(p, tctx, handle);
4447 printf("Testing domain %s failed!\n", dom_sid_string(tctx, sid));
4453 static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
4454 struct policy_handle *handle, const char *domain,
4455 enum torture_samr_choice which_ops)
4458 struct samr_LookupDomain r;
4459 struct lsa_String n1;
4460 struct lsa_String n2;
4463 torture_comment(tctx, "Testing LookupDomain(%s)\n", domain);
4465 /* check for correct error codes */
4466 r.in.connect_handle = handle;
4467 r.in.domain_name = &n2;
4470 status = dcerpc_samr_LookupDomain(p, tctx, &r);
4471 torture_assert_ntstatus_equal(tctx, NT_STATUS_INVALID_PARAMETER, status, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
4473 init_lsa_String(&n2, "xxNODOMAINxx");
4475 status = dcerpc_samr_LookupDomain(p, tctx, &r);
4476 torture_assert_ntstatus_equal(tctx, NT_STATUS_NO_SUCH_DOMAIN, status, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
4478 r.in.connect_handle = handle;
4480 init_lsa_String(&n1, domain);
4481 r.in.domain_name = &n1;
4483 status = dcerpc_samr_LookupDomain(p, tctx, &r);
4484 torture_assert_ntstatus_ok(tctx, status, "LookupDomain");
4486 if (!test_GetDomPwInfo(p, tctx, &n1)) {
4490 if (!test_OpenDomain(p, tctx, handle, r.out.sid, which_ops)) {
4498 static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
4499 struct policy_handle *handle, enum torture_samr_choice which_ops)
4502 struct samr_EnumDomains r;
4503 uint32_t resume_handle = 0;
4507 r.in.connect_handle = handle;
4508 r.in.resume_handle = &resume_handle;
4509 r.in.buf_size = (uint32_t)-1;
4510 r.out.resume_handle = &resume_handle;
4512 status = dcerpc_samr_EnumDomains(p, tctx, &r);
4513 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
4519 for (i=0;i<r.out.sam->count;i++) {
4520 if (!test_LookupDomain(p, tctx, handle,
4521 r.out.sam->entries[i].name.string, which_ops)) {
4526 status = dcerpc_samr_EnumDomains(p, tctx, &r);
4527 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
4533 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
4534 struct policy_handle *handle)
4537 struct samr_Connect r;
4538 struct samr_Connect2 r2;
4539 struct samr_Connect3 r3;
4540 struct samr_Connect4 r4;
4541 struct samr_Connect5 r5;
4542 union samr_ConnectInfo info;
4543 struct policy_handle h;
4544 bool ret = true, got_handle = false;
4546 torture_comment(tctx, "testing samr_Connect\n");
4548 r.in.system_name = 0;
4549 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4550 r.out.connect_handle = &h;
4552 status = dcerpc_samr_Connect(p, tctx, &r);
4553 if (!NT_STATUS_IS_OK(status)) {
4554 torture_comment(tctx, "Connect failed - %s\n", nt_errstr(status));
4561 torture_comment(tctx, "testing samr_Connect2\n");
4563 r2.in.system_name = NULL;
4564 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4565 r2.out.connect_handle = &h;
4567 status = dcerpc_samr_Connect2(p, tctx, &r2);
4568 if (!NT_STATUS_IS_OK(status)) {
4569 torture_comment(tctx, "Connect2 failed - %s\n", nt_errstr(status));
4573 test_samr_handle_Close(p, tctx, handle);
4579 torture_comment(tctx, "testing samr_Connect3\n");
4581 r3.in.system_name = NULL;
4583 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4584 r3.out.connect_handle = &h;
4586 status = dcerpc_samr_Connect3(p, tctx, &r3);
4587 if (!NT_STATUS_IS_OK(status)) {
4588 printf("Connect3 failed - %s\n", nt_errstr(status));
4592 test_samr_handle_Close(p, tctx, handle);
4598 torture_comment(tctx, "testing samr_Connect4\n");
4600 r4.in.system_name = "";
4601 r4.in.client_version = 0;
4602 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4603 r4.out.connect_handle = &h;
4605 status = dcerpc_samr_Connect4(p, tctx, &r4);
4606 if (!NT_STATUS_IS_OK(status)) {
4607 printf("Connect4 failed - %s\n", nt_errstr(status));
4611 test_samr_handle_Close(p, tctx, handle);
4617 torture_comment(tctx, "testing samr_Connect5\n");
4619 info.info1.client_version = 0;
4620 info.info1.unknown2 = 0;
4622 r5.in.system_name = "";
4623 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4626 r5.out.info = &info;
4627 r5.out.connect_handle = &h;
4629 status = dcerpc_samr_Connect5(p, tctx, &r5);
4630 if (!NT_STATUS_IS_OK(status)) {
4631 printf("Connect5 failed - %s\n", nt_errstr(status));
4635 test_samr_handle_Close(p, tctx, handle);
4645 bool torture_rpc_samr(struct torture_context *torture)
4648 struct dcerpc_pipe *p;
4650 struct policy_handle handle;
4652 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4653 if (!NT_STATUS_IS_OK(status)) {
4657 ret &= test_Connect(p, torture, &handle);
4659 ret &= test_QuerySecurity(p, torture, &handle);
4661 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_OTHER);
4663 ret &= test_SetDsrmPassword(p, torture, &handle);
4665 ret &= test_Shutdown(p, torture, &handle);
4667 ret &= test_samr_handle_Close(p, torture, &handle);
4673 bool torture_rpc_samr_users(struct torture_context *torture)
4676 struct dcerpc_pipe *p;
4678 struct policy_handle handle;
4680 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4681 if (!NT_STATUS_IS_OK(status)) {
4685 ret &= test_Connect(p, torture, &handle);
4687 ret &= test_QuerySecurity(p, torture, &handle);
4689 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_USER_ATTRIBUTES);
4691 ret &= test_SetDsrmPassword(p, torture, &handle);
4693 ret &= test_Shutdown(p, torture, &handle);
4695 ret &= test_samr_handle_Close(p, torture, &handle);
4701 bool torture_rpc_samr_passwords(struct torture_context *torture)
4704 struct dcerpc_pipe *p;
4706 struct policy_handle handle;
4708 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4709 if (!NT_STATUS_IS_OK(status)) {
4713 ret &= test_Connect(p, torture, &handle);
4715 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_PASSWORDS);
4717 ret &= test_samr_handle_Close(p, torture, &handle);