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 uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
3280 ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
3281 ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
3284 printf("Testing EnumDomainUsers\n");
3286 for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
3287 r.in.domain_handle = handle;
3288 r.in.resume_handle = &resume_handle;
3289 r.in.acct_flags = mask = masks[mask_idx];
3290 r.in.max_size = (uint32_t)-1;
3291 r.out.resume_handle = &resume_handle;
3293 status = dcerpc_samr_EnumDomainUsers(p, tctx, &r);
3294 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
3295 !NT_STATUS_IS_OK(status)) {
3296 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
3300 torture_assert(tctx, r.out.sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
3302 if (r.out.sam->count == 0) {
3306 for (i=0;i<r.out.sam->count;i++) {
3308 if (!check_mask(p, tctx, handle, r.out.sam->entries[i].idx, mask)) {
3311 } else if (!test_OpenUser(p, tctx, handle, r.out.sam->entries[i].idx)) {
3317 printf("Testing LookupNames\n");
3318 n.in.domain_handle = handle;
3319 n.in.num_names = r.out.sam->count;
3320 n.in.names = talloc_array(tctx, struct lsa_String, r.out.sam->count);
3321 for (i=0;i<r.out.sam->count;i++) {
3322 n.in.names[i].string = r.out.sam->entries[i].name.string;
3324 status = dcerpc_samr_LookupNames(p, tctx, &n);
3325 if (!NT_STATUS_IS_OK(status)) {
3326 printf("LookupNames failed - %s\n", nt_errstr(status));
3331 printf("Testing LookupRids\n");
3332 lr.in.domain_handle = handle;
3333 lr.in.num_rids = r.out.sam->count;
3334 lr.in.rids = talloc_array(tctx, uint32_t, r.out.sam->count);
3335 for (i=0;i<r.out.sam->count;i++) {
3336 lr.in.rids[i] = r.out.sam->entries[i].idx;
3338 status = dcerpc_samr_LookupRids(p, tctx, &lr);
3339 torture_assert_ntstatus_ok(tctx, status, "LookupRids");
3345 try blasting the server with a bunch of sync requests
3347 static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, struct torture_context *tctx,
3348 struct policy_handle *handle)
3351 struct samr_EnumDomainUsers r;
3352 uint32_t resume_handle=0;
3354 #define ASYNC_COUNT 100
3355 struct rpc_request *req[ASYNC_COUNT];
3357 if (!torture_setting_bool(tctx, "dangerous", false)) {
3358 torture_skip(tctx, "samr async test disabled - enable dangerous tests to use\n");
3361 torture_comment(tctx, "Testing EnumDomainUsers_async\n");
3363 r.in.domain_handle = handle;
3364 r.in.resume_handle = &resume_handle;
3365 r.in.acct_flags = 0;
3366 r.in.max_size = (uint32_t)-1;
3367 r.out.resume_handle = &resume_handle;
3369 for (i=0;i<ASYNC_COUNT;i++) {
3370 req[i] = dcerpc_samr_EnumDomainUsers_send(p, tctx, &r);
3373 for (i=0;i<ASYNC_COUNT;i++) {
3374 status = dcerpc_ndr_request_recv(req[i]);
3375 if (!NT_STATUS_IS_OK(status)) {
3376 printf("EnumDomainUsers[%d] failed - %s\n",
3377 i, nt_errstr(status));
3382 torture_comment(tctx, "%d async requests OK\n", i);
3387 static bool test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3388 struct policy_handle *handle)
3391 struct samr_EnumDomainGroups r;
3392 uint32_t resume_handle=0;
3396 printf("Testing EnumDomainGroups\n");
3398 r.in.domain_handle = handle;
3399 r.in.resume_handle = &resume_handle;
3400 r.in.max_size = (uint32_t)-1;
3401 r.out.resume_handle = &resume_handle;
3403 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
3404 if (!NT_STATUS_IS_OK(status)) {
3405 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
3413 for (i=0;i<r.out.sam->count;i++) {
3414 if (!test_OpenGroup(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
3422 static bool test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3423 struct policy_handle *handle)
3426 struct samr_EnumDomainAliases r;
3427 uint32_t resume_handle=0;
3431 printf("Testing EnumDomainAliases\n");
3433 r.in.domain_handle = handle;
3434 r.in.resume_handle = &resume_handle;
3435 r.in.acct_flags = (uint32_t)-1;
3436 r.out.resume_handle = &resume_handle;
3438 status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
3439 if (!NT_STATUS_IS_OK(status)) {
3440 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
3448 for (i=0;i<r.out.sam->count;i++) {
3449 if (!test_OpenAlias(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
3457 static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3458 struct policy_handle *handle)
3461 struct samr_GetDisplayEnumerationIndex r;
3463 uint16_t levels[] = {1, 2, 3, 4, 5};
3464 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
3465 struct lsa_String name;
3469 for (i=0;i<ARRAY_SIZE(levels);i++) {
3470 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
3472 init_lsa_String(&name, TEST_ACCOUNT_NAME);
3474 r.in.domain_handle = handle;
3475 r.in.level = levels[i];
3479 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
3482 !NT_STATUS_IS_OK(status) &&
3483 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3484 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
3485 levels[i], nt_errstr(status));
3489 init_lsa_String(&name, "zzzzzzzz");
3491 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
3493 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3494 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
3495 levels[i], nt_errstr(status));
3503 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3504 struct policy_handle *handle)
3507 struct samr_GetDisplayEnumerationIndex2 r;
3509 uint16_t levels[] = {1, 2, 3, 4, 5};
3510 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
3513 for (i=0;i<ARRAY_SIZE(levels);i++) {
3514 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
3516 r.in.domain_handle = handle;
3517 r.in.level = levels[i];
3518 init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
3520 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
3522 !NT_STATUS_IS_OK(status) &&
3523 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3524 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
3525 levels[i], nt_errstr(status));
3529 init_lsa_String(&r.in.name, "zzzzzzzz");
3531 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
3532 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3533 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
3534 levels[i], nt_errstr(status));
3542 #define STRING_EQUAL_QUERY(s1, s2, user) \
3543 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
3544 /* odd, but valid */ \
3545 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
3546 printf("%s mismatch for %s: %s != %s (%s)\n", \
3547 #s1, user.string, s1.string, s2.string, __location__); \
3550 #define INT_EQUAL_QUERY(s1, s2, user) \
3552 printf("%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
3553 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
3557 static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3558 struct samr_QueryDisplayInfo *querydisplayinfo,
3559 bool *seen_testuser)
3561 struct samr_OpenUser r;
3562 struct samr_QueryUserInfo q;
3563 struct policy_handle user_handle;
3566 r.in.domain_handle = querydisplayinfo->in.domain_handle;
3567 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3568 for (i = 0; ; i++) {
3569 switch (querydisplayinfo->in.level) {
3571 if (i >= querydisplayinfo->out.info.info1.count) {
3574 r.in.rid = querydisplayinfo->out.info.info1.entries[i].rid;
3577 if (i >= querydisplayinfo->out.info.info2.count) {
3580 r.in.rid = querydisplayinfo->out.info.info2.entries[i].rid;
3586 /* Not interested in validating just the account name */
3590 r.out.user_handle = &user_handle;
3592 switch (querydisplayinfo->in.level) {
3595 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3596 if (!NT_STATUS_IS_OK(status)) {
3597 printf("OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(status));
3602 q.in.user_handle = &user_handle;
3604 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
3605 if (!NT_STATUS_IS_OK(status)) {
3606 printf("QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(status));
3610 switch (querydisplayinfo->in.level) {
3612 if (seen_testuser && strcmp(q.out.info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
3613 *seen_testuser = true;
3615 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].full_name,
3616 q.out.info->info21.full_name, q.out.info->info21.account_name);
3617 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].account_name,
3618 q.out.info->info21.account_name, q.out.info->info21.account_name);
3619 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].description,
3620 q.out.info->info21.description, q.out.info->info21.account_name);
3621 INT_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].rid,
3622 q.out.info->info21.rid, q.out.info->info21.account_name);
3623 INT_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].acct_flags,
3624 q.out.info->info21.acct_flags, q.out.info->info21.account_name);
3628 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].account_name,
3629 q.out.info->info21.account_name, q.out.info->info21.account_name);
3630 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].description,
3631 q.out.info->info21.description, q.out.info->info21.account_name);
3632 INT_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].rid,
3633 q.out.info->info21.rid, q.out.info->info21.account_name);
3634 INT_EQUAL_QUERY((querydisplayinfo->out.info.info2.entries[i].acct_flags & ~ACB_NORMAL),
3635 q.out.info->info21.acct_flags, q.out.info->info21.account_name);
3637 if (!(querydisplayinfo->out.info.info2.entries[i].acct_flags & ACB_NORMAL)) {
3638 printf("Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
3639 q.out.info->info21.account_name.string);
3642 if (!(q.out.info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
3643 printf("Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
3644 q.out.info->info21.account_name.string,
3645 querydisplayinfo->out.info.info2.entries[i].acct_flags,
3646 q.out.info->info21.acct_flags);
3653 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
3660 static bool test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3661 struct policy_handle *handle)
3664 struct samr_QueryDisplayInfo r;
3665 struct samr_QueryDomainInfo dom_info;
3667 uint16_t levels[] = {1, 2, 3, 4, 5};
3669 bool seen_testuser = false;
3671 for (i=0;i<ARRAY_SIZE(levels);i++) {
3672 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
3675 status = STATUS_MORE_ENTRIES;
3676 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
3677 r.in.domain_handle = handle;
3678 r.in.level = levels[i];
3679 r.in.max_entries = 2;
3680 r.in.buf_size = (uint32_t)-1;
3682 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
3683 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(status)) {
3684 printf("QueryDisplayInfo level %u failed - %s\n",
3685 levels[i], nt_errstr(status));
3688 switch (r.in.level) {
3690 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, &seen_testuser)) {
3693 r.in.start_idx += r.out.info.info1.count;
3696 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, NULL)) {
3699 r.in.start_idx += r.out.info.info2.count;
3702 r.in.start_idx += r.out.info.info3.count;
3705 r.in.start_idx += r.out.info.info4.count;
3708 r.in.start_idx += r.out.info.info5.count;
3712 dom_info.in.domain_handle = handle;
3713 dom_info.in.level = 2;
3714 /* Check number of users returned is correct */
3715 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &dom_info);
3716 if (!NT_STATUS_IS_OK(status)) {
3717 printf("QueryDomainInfo level %u failed - %s\n",
3718 r.in.level, nt_errstr(status));
3722 switch (r.in.level) {
3725 if (dom_info.out.info->general.num_users < r.in.start_idx) {
3726 printf("QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
3727 r.in.start_idx, dom_info.out.info->general.num_groups,
3728 dom_info.out.info->general.domain_name.string);
3731 if (!seen_testuser) {
3732 struct policy_handle user_handle;
3733 if (NT_STATUS_IS_OK(test_OpenUser_byname(p, mem_ctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
3734 printf("Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
3735 dom_info.out.info->general.domain_name.string);
3737 test_samr_handle_Close(p, mem_ctx, &user_handle);
3743 if (dom_info.out.info->general.num_groups != r.in.start_idx) {
3744 printf("QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
3745 r.in.start_idx, dom_info.out.info->general.num_groups,
3746 dom_info.out.info->general.domain_name.string);
3758 static bool test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3759 struct policy_handle *handle)
3762 struct samr_QueryDisplayInfo2 r;
3764 uint16_t levels[] = {1, 2, 3, 4, 5};
3767 for (i=0;i<ARRAY_SIZE(levels);i++) {
3768 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
3770 r.in.domain_handle = handle;
3771 r.in.level = levels[i];
3773 r.in.max_entries = 1000;
3774 r.in.buf_size = (uint32_t)-1;
3776 status = dcerpc_samr_QueryDisplayInfo2(p, mem_ctx, &r);
3777 if (!NT_STATUS_IS_OK(status)) {
3778 printf("QueryDisplayInfo2 level %u failed - %s\n",
3779 levels[i], nt_errstr(status));
3787 static bool test_QueryDisplayInfo3(struct dcerpc_pipe *p, struct torture_context *tctx,
3788 struct policy_handle *handle)
3791 struct samr_QueryDisplayInfo3 r;
3793 uint16_t levels[] = {1, 2, 3, 4, 5};
3796 for (i=0;i<ARRAY_SIZE(levels);i++) {
3797 torture_comment(tctx, "Testing QueryDisplayInfo3 level %u\n", levels[i]);
3799 r.in.domain_handle = handle;
3800 r.in.level = levels[i];
3802 r.in.max_entries = 1000;
3803 r.in.buf_size = (uint32_t)-1;
3805 status = dcerpc_samr_QueryDisplayInfo3(p, tctx, &r);
3806 if (!NT_STATUS_IS_OK(status)) {
3807 printf("QueryDisplayInfo3 level %u failed - %s\n",
3808 levels[i], nt_errstr(status));
3817 static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3818 struct policy_handle *handle)
3821 struct samr_QueryDisplayInfo r;
3824 printf("Testing QueryDisplayInfo continuation\n");
3826 r.in.domain_handle = handle;
3829 r.in.max_entries = 1;
3830 r.in.buf_size = (uint32_t)-1;
3833 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
3834 if (NT_STATUS_IS_OK(status) && r.out.returned_size != 0) {
3835 if (r.out.info.info1.entries[0].idx != r.in.start_idx + 1) {
3836 printf("expected idx %d but got %d\n",
3838 r.out.info.info1.entries[0].idx);
3842 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
3843 !NT_STATUS_IS_OK(status)) {
3844 printf("QueryDisplayInfo level %u failed - %s\n",
3845 r.in.level, nt_errstr(status));
3850 } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
3851 NT_STATUS_IS_OK(status)) &&
3852 r.out.returned_size != 0);
3857 static bool test_QueryDomainInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
3858 struct policy_handle *handle)
3861 struct samr_QueryDomainInfo r;
3862 struct samr_SetDomainInfo s;
3863 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
3864 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
3867 const char *domain_comment = talloc_asprintf(tctx,
3868 "Tortured by Samba4 RPC-SAMR: %s",
3869 timestring(tctx, time(NULL)));
3871 s.in.domain_handle = handle;
3873 s.in.info = talloc(tctx, union samr_DomainInfo);
3875 s.in.info->oem.oem_information.string = domain_comment;
3876 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
3877 if (!NT_STATUS_IS_OK(status)) {
3878 printf("SetDomainInfo level %u (set comment) failed - %s\n",
3879 r.in.level, nt_errstr(status));
3883 for (i=0;i<ARRAY_SIZE(levels);i++) {
3884 torture_comment(tctx, "Testing QueryDomainInfo level %u\n", levels[i]);
3886 r.in.domain_handle = handle;
3887 r.in.level = levels[i];
3889 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
3890 if (!NT_STATUS_IS_OK(status)) {
3891 printf("QueryDomainInfo level %u failed - %s\n",
3892 r.in.level, nt_errstr(status));
3897 switch (levels[i]) {
3899 if (strcmp(r.out.info->general.oem_information.string, domain_comment) != 0) {
3900 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
3901 levels[i], r.out.info->general.oem_information.string, domain_comment);
3904 if (!r.out.info->general.primary.string) {
3905 printf("QueryDomainInfo level %u returned no PDC name\n",
3908 } else if (r.out.info->general.role == SAMR_ROLE_DOMAIN_PDC) {
3909 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), r.out.info->general.primary.string) != 0) {
3910 printf("QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
3911 levels[i], r.out.info->general.primary.string, dcerpc_server_name(p));
3916 if (strcmp(r.out.info->oem.oem_information.string, domain_comment) != 0) {
3917 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
3918 levels[i], r.out.info->oem.oem_information.string, domain_comment);
3923 if (!r.out.info->info6.primary.string) {
3924 printf("QueryDomainInfo level %u returned no PDC name\n",
3930 if (strcmp(r.out.info->general2.general.oem_information.string, domain_comment) != 0) {
3931 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
3932 levels[i], r.out.info->general2.general.oem_information.string, domain_comment);
3938 torture_comment(tctx, "Testing SetDomainInfo level %u\n", levels[i]);
3940 s.in.domain_handle = handle;
3941 s.in.level = levels[i];
3942 s.in.info = r.out.info;
3944 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
3946 if (!NT_STATUS_IS_OK(status)) {
3947 printf("SetDomainInfo level %u failed - %s\n",
3948 r.in.level, nt_errstr(status));
3953 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
3954 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
3955 r.in.level, nt_errstr(status));
3961 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
3962 if (!NT_STATUS_IS_OK(status)) {
3963 printf("QueryDomainInfo level %u failed - %s\n",
3964 r.in.level, nt_errstr(status));
3974 static bool test_QueryDomainInfo2(struct dcerpc_pipe *p, struct torture_context *tctx,
3975 struct policy_handle *handle)
3978 struct samr_QueryDomainInfo2 r;
3979 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
3983 for (i=0;i<ARRAY_SIZE(levels);i++) {
3984 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
3986 r.in.domain_handle = handle;
3987 r.in.level = levels[i];
3989 status = dcerpc_samr_QueryDomainInfo2(p, tctx, &r);
3990 if (!NT_STATUS_IS_OK(status)) {
3991 printf("QueryDomainInfo2 level %u failed - %s\n",
3992 r.in.level, nt_errstr(status));
4001 /* Test whether querydispinfo level 5 and enumdomgroups return the same
4002 set of group names. */
4003 static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx,
4004 struct policy_handle *handle)
4006 struct samr_EnumDomainGroups q1;
4007 struct samr_QueryDisplayInfo q2;
4009 uint32_t resume_handle=0;
4014 const char **names = NULL;
4016 torture_comment(tctx, "Testing coherency of querydispinfo vs enumdomgroups\n");
4018 q1.in.domain_handle = handle;
4019 q1.in.resume_handle = &resume_handle;
4021 q1.out.resume_handle = &resume_handle;
4023 status = STATUS_MORE_ENTRIES;
4024 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
4025 status = dcerpc_samr_EnumDomainGroups(p, tctx, &q1);
4027 if (!NT_STATUS_IS_OK(status) &&
4028 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
4031 for (i=0; i<q1.out.num_entries; i++) {
4032 add_string_to_array(tctx,
4033 q1.out.sam->entries[i].name.string,
4034 &names, &num_names);
4038 torture_assert_ntstatus_ok(tctx, status, "EnumDomainGroups");
4040 torture_assert(tctx, q1.out.sam, "EnumDomainGroups failed to return q1.out.sam");
4042 q2.in.domain_handle = handle;
4044 q2.in.start_idx = 0;
4045 q2.in.max_entries = 5;
4046 q2.in.buf_size = (uint32_t)-1;
4048 status = STATUS_MORE_ENTRIES;
4049 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
4050 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &q2);
4052 if (!NT_STATUS_IS_OK(status) &&
4053 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
4056 for (i=0; i<q2.out.info.info5.count; i++) {
4058 const char *name = q2.out.info.info5.entries[i].account_name.string;
4060 for (j=0; j<num_names; j++) {
4061 if (names[j] == NULL)
4063 if (strequal(names[j], name)) {
4071 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
4076 q2.in.start_idx += q2.out.info.info5.count;
4079 if (!NT_STATUS_IS_OK(status)) {
4080 printf("QueryDisplayInfo level 5 failed - %s\n",
4085 for (i=0; i<num_names; i++) {
4086 if (names[i] != NULL) {
4087 printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
4096 static bool test_DeleteDomainGroup(struct dcerpc_pipe *p, struct torture_context *tctx,
4097 struct policy_handle *group_handle)
4099 struct samr_DeleteDomainGroup d;
4102 torture_comment(tctx, "Testing DeleteDomainGroup\n");
4104 d.in.group_handle = group_handle;
4105 d.out.group_handle = group_handle;
4107 status = dcerpc_samr_DeleteDomainGroup(p, tctx, &d);
4108 torture_assert_ntstatus_ok(tctx, status, "DeleteDomainGroup");
4113 static bool test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
4114 struct policy_handle *domain_handle)
4116 struct samr_TestPrivateFunctionsDomain r;
4120 torture_comment(tctx, "Testing TestPrivateFunctionsDomain\n");
4122 r.in.domain_handle = domain_handle;
4124 status = dcerpc_samr_TestPrivateFunctionsDomain(p, tctx, &r);
4125 torture_assert_ntstatus_equal(tctx, NT_STATUS_NOT_IMPLEMENTED, status, "TestPrivateFunctionsDomain");
4130 static bool test_RidToSid(struct dcerpc_pipe *p, struct torture_context *tctx,
4131 struct dom_sid *domain_sid,
4132 struct policy_handle *domain_handle)
4134 struct samr_RidToSid r;
4137 struct dom_sid *calc_sid;
4138 int rids[] = { 0, 42, 512, 10200 };
4141 for (i=0;i<ARRAY_SIZE(rids);i++) {
4142 torture_comment(tctx, "Testing RidToSid\n");
4144 calc_sid = dom_sid_dup(tctx, domain_sid);
4145 r.in.domain_handle = domain_handle;
4148 status = dcerpc_samr_RidToSid(p, tctx, &r);
4149 if (!NT_STATUS_IS_OK(status)) {
4150 printf("RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
4153 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
4155 if (!dom_sid_equal(calc_sid, r.out.sid)) {
4156 printf("RidToSid for %d failed - got %s, expected %s\n", rids[i],
4157 dom_sid_string(tctx, r.out.sid),
4158 dom_sid_string(tctx, calc_sid));
4167 static bool test_GetBootKeyInformation(struct dcerpc_pipe *p, struct torture_context *tctx,
4168 struct policy_handle *domain_handle)
4170 struct samr_GetBootKeyInformation r;
4174 torture_comment(tctx, "Testing GetBootKeyInformation\n");
4176 r.in.domain_handle = domain_handle;
4178 status = dcerpc_samr_GetBootKeyInformation(p, tctx, &r);
4179 if (!NT_STATUS_IS_OK(status)) {
4180 /* w2k3 seems to fail this sometimes and pass it sometimes */
4181 torture_comment(tctx, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
4187 static bool test_AddGroupMember(struct dcerpc_pipe *p, struct torture_context *tctx,
4188 struct policy_handle *domain_handle,
4189 struct policy_handle *group_handle)
4192 struct samr_AddGroupMember r;
4193 struct samr_DeleteGroupMember d;
4194 struct samr_QueryGroupMember q;
4195 struct samr_SetMemberAttributesOfGroup s;
4198 status = test_LookupName(p, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
4199 torture_assert_ntstatus_ok(tctx, status, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME);
4201 r.in.group_handle = group_handle;
4203 r.in.flags = 0; /* ??? */
4205 torture_comment(tctx, "Testing AddGroupMember and DeleteGroupMember\n");
4207 d.in.group_handle = group_handle;
4210 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
4211 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_NOT_IN_GROUP, status, "DeleteGroupMember");
4213 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4214 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
4216 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4217 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_IN_GROUP, status, "AddGroupMember");
4219 if (torture_setting_bool(tctx, "samba4", false)) {
4220 torture_comment(tctx, "skipping SetMemberAttributesOfGroup test against Samba4\n");
4222 /* this one is quite strange. I am using random inputs in the
4223 hope of triggering an error that might give us a clue */
4225 s.in.group_handle = group_handle;
4226 s.in.unknown1 = random();
4227 s.in.unknown2 = random();
4229 status = dcerpc_samr_SetMemberAttributesOfGroup(p, tctx, &s);
4230 torture_assert_ntstatus_ok(tctx, status, "SetMemberAttributesOfGroup");
4233 q.in.group_handle = group_handle;
4235 status = dcerpc_samr_QueryGroupMember(p, tctx, &q);
4236 torture_assert_ntstatus_ok(tctx, status, "QueryGroupMember");
4238 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
4239 torture_assert_ntstatus_ok(tctx, status, "DeleteGroupMember");
4241 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4242 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
4248 static bool test_CreateDomainGroup(struct dcerpc_pipe *p,
4249 struct torture_context *tctx,
4250 struct policy_handle *domain_handle,
4251 struct policy_handle *group_handle,
4252 struct dom_sid *domain_sid)
4255 struct samr_CreateDomainGroup r;
4257 struct lsa_String name;
4260 init_lsa_String(&name, TEST_GROUPNAME);
4262 r.in.domain_handle = domain_handle;
4264 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4265 r.out.group_handle = group_handle;
4268 printf("Testing CreateDomainGroup(%s)\n", r.in.name->string);
4270 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
4272 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
4273 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
4274 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.name->string);
4277 printf("Server should have refused create of '%s', got %s instead\n", r.in.name->string,
4283 if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS)) {
4284 if (!test_DeleteGroup_byname(p, tctx, domain_handle, r.in.name->string)) {
4285 printf("CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
4289 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
4291 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
4292 if (!test_DeleteUser_byname(p, tctx, domain_handle, r.in.name->string)) {
4294 printf("CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
4298 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
4300 torture_assert_ntstatus_ok(tctx, status, "CreateDomainGroup");
4302 if (!test_AddGroupMember(p, tctx, domain_handle, group_handle)) {
4303 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
4307 if (!test_SetGroupInfo(p, tctx, group_handle)) {
4316 its not totally clear what this does. It seems to accept any sid you like.
4318 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p,
4319 struct torture_context *tctx,
4320 struct policy_handle *domain_handle)
4323 struct samr_RemoveMemberFromForeignDomain r;
4325 r.in.domain_handle = domain_handle;
4326 r.in.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-12-34-56-78");
4328 status = dcerpc_samr_RemoveMemberFromForeignDomain(p, tctx, &r);
4329 torture_assert_ntstatus_ok(tctx, status, "RemoveMemberFromForeignDomain");
4336 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
4337 struct policy_handle *handle);
4339 static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
4340 struct policy_handle *handle, struct dom_sid *sid,
4341 enum torture_samr_choice which_ops)
4344 struct samr_OpenDomain r;
4345 struct policy_handle domain_handle;
4346 struct policy_handle alias_handle;
4347 struct policy_handle user_handle;
4348 struct policy_handle group_handle;
4351 ZERO_STRUCT(alias_handle);
4352 ZERO_STRUCT(user_handle);
4353 ZERO_STRUCT(group_handle);
4354 ZERO_STRUCT(domain_handle);
4356 torture_comment(tctx, "Testing OpenDomain of %s\n", dom_sid_string(tctx, sid));
4358 r.in.connect_handle = handle;
4359 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4361 r.out.domain_handle = &domain_handle;
4363 status = dcerpc_samr_OpenDomain(p, tctx, &r);
4364 torture_assert_ntstatus_ok(tctx, status, "OpenDomain");
4366 /* run the domain tests with the main handle closed - this tests
4367 the servers reference counting */
4368 ret &= test_samr_handle_Close(p, tctx, handle);
4370 switch (which_ops) {
4371 case TORTURE_SAMR_USER_ATTRIBUTES:
4372 case TORTURE_SAMR_PASSWORDS:
4373 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops);
4374 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops);
4375 /* This test needs 'complex' users to validate */
4376 ret &= test_QueryDisplayInfo(p, tctx, &domain_handle);
4378 printf("Testing PASSWORDS or ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
4381 case TORTURE_SAMR_OTHER:
4382 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops);
4384 printf("Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid));
4386 ret &= test_QuerySecurity(p, tctx, &domain_handle);
4387 ret &= test_RemoveMemberFromForeignDomain(p, tctx, &domain_handle);
4388 ret &= test_CreateAlias(p, tctx, &domain_handle, &alias_handle, sid);
4389 ret &= test_CreateDomainGroup(p, tctx, &domain_handle, &group_handle, sid);
4390 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
4391 ret &= test_QueryDomainInfo2(p, tctx, &domain_handle);
4392 ret &= test_EnumDomainUsers(p, tctx, &domain_handle);
4393 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
4394 ret &= test_EnumDomainGroups(p, tctx, &domain_handle);
4395 ret &= test_EnumDomainAliases(p, tctx, &domain_handle);
4396 ret &= test_QueryDisplayInfo2(p, tctx, &domain_handle);
4397 ret &= test_QueryDisplayInfo3(p, tctx, &domain_handle);
4398 ret &= test_QueryDisplayInfo_continue(p, tctx, &domain_handle);
4400 if (torture_setting_bool(tctx, "samba4", false)) {
4401 torture_comment(tctx, "skipping GetDisplayEnumerationIndex test against Samba4\n");
4403 ret &= test_GetDisplayEnumerationIndex(p, tctx, &domain_handle);
4404 ret &= test_GetDisplayEnumerationIndex2(p, tctx, &domain_handle);
4406 ret &= test_GroupList(p, tctx, &domain_handle);
4407 ret &= test_TestPrivateFunctionsDomain(p, tctx, &domain_handle);
4408 ret &= test_RidToSid(p, tctx, sid, &domain_handle);
4409 ret &= test_GetBootKeyInformation(p, tctx, &domain_handle);
4411 torture_comment(tctx, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx, sid));
4416 if (!policy_handle_empty(&user_handle) &&
4417 !test_DeleteUser(p, tctx, &user_handle)) {
4421 if (!policy_handle_empty(&alias_handle) &&
4422 !test_DeleteAlias(p, tctx, &alias_handle)) {
4426 if (!policy_handle_empty(&group_handle) &&
4427 !test_DeleteDomainGroup(p, tctx, &group_handle)) {
4431 ret &= test_samr_handle_Close(p, tctx, &domain_handle);
4433 /* reconnect the main handle */
4434 ret &= test_Connect(p, tctx, handle);
4437 printf("Testing domain %s failed!\n", dom_sid_string(tctx, sid));
4443 static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
4444 struct policy_handle *handle, const char *domain,
4445 enum torture_samr_choice which_ops)
4448 struct samr_LookupDomain r;
4449 struct lsa_String n1;
4450 struct lsa_String n2;
4453 torture_comment(tctx, "Testing LookupDomain(%s)\n", domain);
4455 /* check for correct error codes */
4456 r.in.connect_handle = handle;
4457 r.in.domain_name = &n2;
4460 status = dcerpc_samr_LookupDomain(p, tctx, &r);
4461 torture_assert_ntstatus_equal(tctx, NT_STATUS_INVALID_PARAMETER, status, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
4463 init_lsa_String(&n2, "xxNODOMAINxx");
4465 status = dcerpc_samr_LookupDomain(p, tctx, &r);
4466 torture_assert_ntstatus_equal(tctx, NT_STATUS_NO_SUCH_DOMAIN, status, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
4468 r.in.connect_handle = handle;
4470 init_lsa_String(&n1, domain);
4471 r.in.domain_name = &n1;
4473 status = dcerpc_samr_LookupDomain(p, tctx, &r);
4474 torture_assert_ntstatus_ok(tctx, status, "LookupDomain");
4476 if (!test_GetDomPwInfo(p, tctx, &n1)) {
4480 if (!test_OpenDomain(p, tctx, handle, r.out.sid, which_ops)) {
4488 static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
4489 struct policy_handle *handle, enum torture_samr_choice which_ops)
4492 struct samr_EnumDomains r;
4493 uint32_t resume_handle = 0;
4497 r.in.connect_handle = handle;
4498 r.in.resume_handle = &resume_handle;
4499 r.in.buf_size = (uint32_t)-1;
4500 r.out.resume_handle = &resume_handle;
4502 status = dcerpc_samr_EnumDomains(p, tctx, &r);
4503 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
4509 for (i=0;i<r.out.sam->count;i++) {
4510 if (!test_LookupDomain(p, tctx, handle,
4511 r.out.sam->entries[i].name.string, which_ops)) {
4516 status = dcerpc_samr_EnumDomains(p, tctx, &r);
4517 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
4523 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
4524 struct policy_handle *handle)
4527 struct samr_Connect r;
4528 struct samr_Connect2 r2;
4529 struct samr_Connect3 r3;
4530 struct samr_Connect4 r4;
4531 struct samr_Connect5 r5;
4532 union samr_ConnectInfo info;
4533 struct policy_handle h;
4534 bool ret = true, got_handle = false;
4536 torture_comment(tctx, "testing samr_Connect\n");
4538 r.in.system_name = 0;
4539 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4540 r.out.connect_handle = &h;
4542 status = dcerpc_samr_Connect(p, tctx, &r);
4543 if (!NT_STATUS_IS_OK(status)) {
4544 torture_comment(tctx, "Connect failed - %s\n", nt_errstr(status));
4551 torture_comment(tctx, "testing samr_Connect2\n");
4553 r2.in.system_name = NULL;
4554 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4555 r2.out.connect_handle = &h;
4557 status = dcerpc_samr_Connect2(p, tctx, &r2);
4558 if (!NT_STATUS_IS_OK(status)) {
4559 torture_comment(tctx, "Connect2 failed - %s\n", nt_errstr(status));
4563 test_samr_handle_Close(p, tctx, handle);
4569 torture_comment(tctx, "testing samr_Connect3\n");
4571 r3.in.system_name = NULL;
4573 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4574 r3.out.connect_handle = &h;
4576 status = dcerpc_samr_Connect3(p, tctx, &r3);
4577 if (!NT_STATUS_IS_OK(status)) {
4578 printf("Connect3 failed - %s\n", nt_errstr(status));
4582 test_samr_handle_Close(p, tctx, handle);
4588 torture_comment(tctx, "testing samr_Connect4\n");
4590 r4.in.system_name = "";
4591 r4.in.client_version = 0;
4592 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4593 r4.out.connect_handle = &h;
4595 status = dcerpc_samr_Connect4(p, tctx, &r4);
4596 if (!NT_STATUS_IS_OK(status)) {
4597 printf("Connect4 failed - %s\n", nt_errstr(status));
4601 test_samr_handle_Close(p, tctx, handle);
4607 torture_comment(tctx, "testing samr_Connect5\n");
4609 info.info1.client_version = 0;
4610 info.info1.unknown2 = 0;
4612 r5.in.system_name = "";
4613 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4616 r5.out.info = &info;
4617 r5.out.connect_handle = &h;
4619 status = dcerpc_samr_Connect5(p, tctx, &r5);
4620 if (!NT_STATUS_IS_OK(status)) {
4621 printf("Connect5 failed - %s\n", nt_errstr(status));
4625 test_samr_handle_Close(p, tctx, handle);
4635 bool torture_rpc_samr(struct torture_context *torture)
4638 struct dcerpc_pipe *p;
4640 struct policy_handle handle;
4642 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4643 if (!NT_STATUS_IS_OK(status)) {
4647 ret &= test_Connect(p, torture, &handle);
4649 ret &= test_QuerySecurity(p, torture, &handle);
4651 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_OTHER);
4653 ret &= test_SetDsrmPassword(p, torture, &handle);
4655 ret &= test_Shutdown(p, torture, &handle);
4657 ret &= test_samr_handle_Close(p, torture, &handle);
4663 bool torture_rpc_samr_users(struct torture_context *torture)
4666 struct dcerpc_pipe *p;
4668 struct policy_handle handle;
4670 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4671 if (!NT_STATUS_IS_OK(status)) {
4675 ret &= test_Connect(p, torture, &handle);
4677 ret &= test_QuerySecurity(p, torture, &handle);
4679 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_USER_ATTRIBUTES);
4681 ret &= test_SetDsrmPassword(p, torture, &handle);
4683 ret &= test_Shutdown(p, torture, &handle);
4685 ret &= test_samr_handle_Close(p, torture, &handle);
4691 bool torture_rpc_samr_passwords(struct torture_context *torture)
4694 struct dcerpc_pipe *p;
4696 struct policy_handle handle;
4698 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4699 if (!NT_STATUS_IS_OK(status)) {
4703 ret &= test_Connect(p, torture, &handle);
4705 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_PASSWORDS);
4707 ret &= test_samr_handle_Close(p, torture, &handle);