2 Unix SMB/CIFS implementation.
3 test suite for samr rpc operations
5 Copyright (C) Andrew Tridgell 2003
6 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "torture/torture.h"
24 #include "system/time.h"
25 #include "librpc/gen_ndr/lsa.h"
26 #include "librpc/gen_ndr/ndr_samr_c.h"
27 #include "../lib/crypto/crypto.h"
28 #include "libcli/auth/libcli_auth.h"
29 #include "libcli/security/security.h"
30 #include "torture/rpc/rpc.h"
32 #define TEST_ACCOUNT_NAME "samrtorturetest"
33 #define TEST_ALIASNAME "samrtorturetestalias"
34 #define TEST_GROUPNAME "samrtorturetestgroup"
35 #define TEST_MACHINENAME "samrtestmach$"
36 #define TEST_DOMAINNAME "samrtestdom$"
38 enum torture_samr_choice {
39 TORTURE_SAMR_PASSWORDS,
40 TORTURE_SAMR_USER_ATTRIBUTES,
44 static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
45 struct policy_handle *handle);
47 static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
48 struct policy_handle *handle);
50 static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
51 struct policy_handle *handle);
53 static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
54 const char *acct_name,
55 struct policy_handle *domain_handle, char **password);
57 static void init_lsa_String(struct lsa_String *string, const char *s)
62 static void init_lsa_BinaryString(struct lsa_BinaryString *string, const char *s, uint32_t length)
64 string->length = length;
65 string->size = length;
66 string->array = (uint16_t *)discard_const(s);
69 bool test_samr_handle_Close(struct dcerpc_pipe *p, struct torture_context *tctx,
70 struct policy_handle *handle)
76 r.out.handle = handle;
78 status = dcerpc_samr_Close(p, tctx, &r);
79 torture_assert_ntstatus_ok(tctx, status, "Close");
84 static bool test_Shutdown(struct dcerpc_pipe *p, struct torture_context *tctx,
85 struct policy_handle *handle)
88 struct samr_Shutdown r;
90 if (!torture_setting_bool(tctx, "dangerous", false)) {
91 torture_skip(tctx, "samr_Shutdown disabled - enable dangerous tests to use\n");
95 r.in.connect_handle = handle;
97 torture_comment(tctx, "testing samr_Shutdown\n");
99 status = dcerpc_samr_Shutdown(p, tctx, &r);
100 torture_assert_ntstatus_ok(tctx, status, "samr_Shutdown");
105 static bool test_SetDsrmPassword(struct dcerpc_pipe *p, struct torture_context *tctx,
106 struct policy_handle *handle)
109 struct samr_SetDsrmPassword r;
110 struct lsa_String string;
111 struct samr_Password hash;
113 if (!torture_setting_bool(tctx, "dangerous", false)) {
114 torture_skip(tctx, "samr_SetDsrmPassword disabled - enable dangerous tests to use");
117 E_md4hash("TeSTDSRM123", hash.hash);
119 init_lsa_String(&string, "Administrator");
125 torture_comment(tctx, "testing samr_SetDsrmPassword\n");
127 status = dcerpc_samr_SetDsrmPassword(p, tctx, &r);
128 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_SUPPORTED, "samr_SetDsrmPassword");
134 static bool test_QuerySecurity(struct dcerpc_pipe *p,
135 struct torture_context *tctx,
136 struct policy_handle *handle)
139 struct samr_QuerySecurity r;
140 struct samr_SetSecurity s;
141 struct sec_desc_buf *sdbuf = NULL;
143 r.in.handle = handle;
145 r.out.sdbuf = &sdbuf;
147 status = dcerpc_samr_QuerySecurity(p, tctx, &r);
148 torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
150 torture_assert(tctx, sdbuf != NULL, "sdbuf is NULL");
152 s.in.handle = handle;
156 if (torture_setting_bool(tctx, "samba4", false)) {
157 torture_skip(tctx, "skipping SetSecurity test against Samba4\n");
160 status = dcerpc_samr_SetSecurity(p, tctx, &s);
161 torture_assert_ntstatus_ok(tctx, status, "SetSecurity");
163 status = dcerpc_samr_QuerySecurity(p, tctx, &r);
164 torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
170 static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
171 struct policy_handle *handle, uint32_t base_acct_flags,
172 const char *base_account_name)
175 struct samr_SetUserInfo s;
176 struct samr_SetUserInfo2 s2;
177 struct samr_QueryUserInfo q;
178 struct samr_QueryUserInfo q0;
179 union samr_UserInfo u;
180 union samr_UserInfo *info;
182 const char *test_account_name;
184 uint32_t user_extra_flags = 0;
185 if (base_acct_flags == ACB_NORMAL) {
186 /* When created, accounts are expired by default */
187 user_extra_flags = ACB_PW_EXPIRED;
190 s.in.user_handle = handle;
193 s2.in.user_handle = handle;
196 q.in.user_handle = handle;
200 #define TESTCALL(call, r) \
201 status = dcerpc_samr_ ##call(p, tctx, &r); \
202 if (!NT_STATUS_IS_OK(status)) { \
203 torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
204 r.in.level, nt_errstr(status), __location__); \
209 #define STRING_EQUAL(s1, s2, field) \
210 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
211 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
212 #field, s2, __location__); \
217 #define MEM_EQUAL(s1, s2, length, field) \
218 if ((s1 && !s2) || (s2 && !s1) || memcmp(s1, s2, length)) { \
219 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
220 #field, (const char *)s2, __location__); \
225 #define INT_EQUAL(i1, i2, field) \
227 torture_comment(tctx, "Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \
228 #field, (unsigned long long)i2, (unsigned long long)i1, __location__); \
233 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
234 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
236 TESTCALL(QueryUserInfo, q) \
238 s2.in.level = lvl1; \
241 ZERO_STRUCT(u.info21); \
242 u.info21.fields_present = fpval; \
244 init_lsa_String(&u.info ## lvl1.field1, value); \
245 TESTCALL(SetUserInfo, s) \
246 TESTCALL(SetUserInfo2, s2) \
247 init_lsa_String(&u.info ## lvl1.field1, ""); \
248 TESTCALL(QueryUserInfo, q); \
250 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
252 TESTCALL(QueryUserInfo, q) \
254 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
257 #define TEST_USERINFO_BINARYSTRING(lvl1, field1, lvl2, field2, value, fpval) do { \
258 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
260 TESTCALL(QueryUserInfo, q) \
262 s2.in.level = lvl1; \
265 ZERO_STRUCT(u.info21); \
266 u.info21.fields_present = fpval; \
268 init_lsa_BinaryString(&u.info ## lvl1.field1, value, strlen(value)); \
269 TESTCALL(SetUserInfo, s) \
270 TESTCALL(SetUserInfo2, s2) \
271 init_lsa_BinaryString(&u.info ## lvl1.field1, "", 1); \
272 TESTCALL(QueryUserInfo, q); \
274 MEM_EQUAL(u.info ## lvl1.field1.array, value, strlen(value), field1); \
276 TESTCALL(QueryUserInfo, q) \
278 MEM_EQUAL(u.info ## lvl2.field2.array, value, strlen(value), field2); \
281 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
282 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
284 TESTCALL(QueryUserInfo, q) \
286 s2.in.level = lvl1; \
289 uint8_t *bits = u.info21.logon_hours.bits; \
290 ZERO_STRUCT(u.info21); \
291 if (fpval == SAMR_FIELD_LOGON_HOURS) { \
292 u.info21.logon_hours.units_per_week = 168; \
293 u.info21.logon_hours.bits = bits; \
295 u.info21.fields_present = fpval; \
297 u.info ## lvl1.field1 = value; \
298 TESTCALL(SetUserInfo, s) \
299 TESTCALL(SetUserInfo2, s2) \
300 u.info ## lvl1.field1 = 0; \
301 TESTCALL(QueryUserInfo, q); \
303 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
305 TESTCALL(QueryUserInfo, q) \
307 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
310 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
311 TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
315 do { TESTCALL(QueryUserInfo, q0) } while (0);
317 TEST_USERINFO_STRING(2, comment, 1, comment, "xx2-1 comment", 0);
318 TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
319 TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment",
322 test_account_name = talloc_asprintf(tctx, "%sxx7-1", base_account_name);
323 TEST_USERINFO_STRING(7, account_name, 1, account_name, base_account_name, 0);
324 test_account_name = talloc_asprintf(tctx, "%sxx7-3", base_account_name);
325 TEST_USERINFO_STRING(7, account_name, 3, account_name, base_account_name, 0);
326 test_account_name = talloc_asprintf(tctx, "%sxx7-5", base_account_name);
327 TEST_USERINFO_STRING(7, account_name, 5, account_name, base_account_name, 0);
328 test_account_name = talloc_asprintf(tctx, "%sxx7-6", base_account_name);
329 TEST_USERINFO_STRING(7, account_name, 6, account_name, base_account_name, 0);
330 test_account_name = talloc_asprintf(tctx, "%sxx7-7", base_account_name);
331 TEST_USERINFO_STRING(7, account_name, 7, account_name, base_account_name, 0);
332 test_account_name = talloc_asprintf(tctx, "%sxx7-21", base_account_name);
333 TEST_USERINFO_STRING(7, account_name, 21, account_name, base_account_name, 0);
334 test_account_name = base_account_name;
335 TEST_USERINFO_STRING(21, account_name, 21, account_name, base_account_name,
336 SAMR_FIELD_ACCOUNT_NAME);
338 TEST_USERINFO_STRING(6, full_name, 1, full_name, "xx6-1 full_name", 0);
339 TEST_USERINFO_STRING(6, full_name, 3, full_name, "xx6-3 full_name", 0);
340 TEST_USERINFO_STRING(6, full_name, 5, full_name, "xx6-5 full_name", 0);
341 TEST_USERINFO_STRING(6, full_name, 6, full_name, "xx6-6 full_name", 0);
342 TEST_USERINFO_STRING(6, full_name, 8, full_name, "xx6-8 full_name", 0);
343 TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
344 TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
345 TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name",
346 SAMR_FIELD_FULL_NAME);
348 TEST_USERINFO_STRING(6, full_name, 1, full_name, "", 0);
349 TEST_USERINFO_STRING(6, full_name, 3, full_name, "", 0);
350 TEST_USERINFO_STRING(6, full_name, 5, full_name, "", 0);
351 TEST_USERINFO_STRING(6, full_name, 6, full_name, "", 0);
352 TEST_USERINFO_STRING(6, full_name, 8, full_name, "", 0);
353 TEST_USERINFO_STRING(6, full_name, 21, full_name, "", 0);
354 TEST_USERINFO_STRING(8, full_name, 21, full_name, "", 0);
355 TEST_USERINFO_STRING(21, full_name, 21, full_name, "",
356 SAMR_FIELD_FULL_NAME);
358 TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
359 TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
360 TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
361 TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script",
362 SAMR_FIELD_LOGON_SCRIPT);
364 TEST_USERINFO_STRING(12, profile_path, 3, profile_path, "xx12-3 profile_path", 0);
365 TEST_USERINFO_STRING(12, profile_path, 5, profile_path, "xx12-5 profile_path", 0);
366 TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
367 TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path",
368 SAMR_FIELD_PROFILE_PATH);
370 TEST_USERINFO_STRING(10, home_directory, 3, home_directory, "xx10-3 home_directory", 0);
371 TEST_USERINFO_STRING(10, home_directory, 5, home_directory, "xx10-5 home_directory", 0);
372 TEST_USERINFO_STRING(10, home_directory, 21, home_directory, "xx10-21 home_directory", 0);
373 TEST_USERINFO_STRING(21, home_directory, 21, home_directory, "xx21-21 home_directory",
374 SAMR_FIELD_HOME_DIRECTORY);
375 TEST_USERINFO_STRING(21, home_directory, 10, home_directory, "xx21-10 home_directory",
376 SAMR_FIELD_HOME_DIRECTORY);
378 TEST_USERINFO_STRING(10, home_drive, 3, home_drive, "xx10-3 home_drive", 0);
379 TEST_USERINFO_STRING(10, home_drive, 5, home_drive, "xx10-5 home_drive", 0);
380 TEST_USERINFO_STRING(10, home_drive, 21, home_drive, "xx10-21 home_drive", 0);
381 TEST_USERINFO_STRING(21, home_drive, 21, home_drive, "xx21-21 home_drive",
382 SAMR_FIELD_HOME_DRIVE);
383 TEST_USERINFO_STRING(21, home_drive, 10, home_drive, "xx21-10 home_drive",
384 SAMR_FIELD_HOME_DRIVE);
386 TEST_USERINFO_STRING(13, description, 1, description, "xx13-1 description", 0);
387 TEST_USERINFO_STRING(13, description, 5, description, "xx13-5 description", 0);
388 TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
389 TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description",
390 SAMR_FIELD_DESCRIPTION);
392 TEST_USERINFO_STRING(14, workstations, 3, workstations, "14workstation3", 0);
393 TEST_USERINFO_STRING(14, workstations, 5, workstations, "14workstation4", 0);
394 TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
395 TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21",
396 SAMR_FIELD_WORKSTATIONS);
397 TEST_USERINFO_STRING(21, workstations, 3, workstations, "21workstation3",
398 SAMR_FIELD_WORKSTATIONS);
399 TEST_USERINFO_STRING(21, workstations, 5, workstations, "21workstation5",
400 SAMR_FIELD_WORKSTATIONS);
401 TEST_USERINFO_STRING(21, workstations, 14, workstations, "21workstation14",
402 SAMR_FIELD_WORKSTATIONS);
404 TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
405 TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "xx21-21 parameters",
406 SAMR_FIELD_PARAMETERS);
407 TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "xx21-20 parameters",
408 SAMR_FIELD_PARAMETERS);
410 TEST_USERINFO_INT(2, country_code, 2, country_code, __LINE__, 0);
411 TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
412 TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__,
413 SAMR_FIELD_COUNTRY_CODE);
414 TEST_USERINFO_INT(21, country_code, 2, country_code, __LINE__,
415 SAMR_FIELD_COUNTRY_CODE);
417 TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
418 TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__,
419 SAMR_FIELD_CODE_PAGE);
420 TEST_USERINFO_INT(21, code_page, 2, code_page, __LINE__,
421 SAMR_FIELD_CODE_PAGE);
423 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, __LINE__, 0);
424 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, __LINE__, 0);
425 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, __LINE__,
426 SAMR_FIELD_ACCT_EXPIRY);
427 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, __LINE__,
428 SAMR_FIELD_ACCT_EXPIRY);
429 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, __LINE__,
430 SAMR_FIELD_ACCT_EXPIRY);
432 TEST_USERINFO_INT(4, logon_hours.bits[3], 3, logon_hours.bits[3], 1, 0);
433 TEST_USERINFO_INT(4, logon_hours.bits[3], 5, logon_hours.bits[3], 2, 0);
434 TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
435 TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4,
436 SAMR_FIELD_LOGON_HOURS);
438 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
439 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
440 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
442 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
443 (base_acct_flags | ACB_DISABLED),
444 (base_acct_flags | ACB_DISABLED | user_extra_flags),
447 /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
448 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
449 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
450 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
452 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
453 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
454 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
458 /* The 'autolock' flag doesn't stick - check this */
459 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
460 (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK),
461 (base_acct_flags | ACB_DISABLED | user_extra_flags),
464 /* Removing the 'disabled' flag doesn't stick - check this */
465 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
467 (base_acct_flags | ACB_DISABLED | user_extra_flags),
470 /* The 'store plaintext' flag does stick */
471 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
472 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED),
473 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags),
475 /* The 'use DES' flag does stick */
476 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
477 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY),
478 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags),
480 /* The 'don't require kerberos pre-authentication flag does stick */
481 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
482 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH),
483 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags),
485 /* The 'no kerberos PAC required' flag sticks */
486 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
487 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD),
488 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags),
491 TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags,
492 (base_acct_flags | ACB_DISABLED),
493 (base_acct_flags | ACB_DISABLED | user_extra_flags),
494 SAMR_FIELD_ACCT_FLAGS);
497 /* these fail with win2003 - it appears you can't set the primary gid?
498 the set succeeds, but the gid isn't changed. Very weird! */
499 TEST_USERINFO_INT(9, primary_gid, 1, primary_gid, 513);
500 TEST_USERINFO_INT(9, primary_gid, 3, primary_gid, 513);
501 TEST_USERINFO_INT(9, primary_gid, 5, primary_gid, 513);
502 TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
509 generate a random password for password change tests
511 static char *samr_rand_pass_silent(TALLOC_CTX *mem_ctx, int min_len)
513 size_t len = MAX(8, min_len) + (random() % 6);
514 char *s = generate_random_str(mem_ctx, len);
518 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
520 char *s = samr_rand_pass_silent(mem_ctx, min_len);
521 printf("Generated password '%s'\n", s);
527 generate a random password for password change tests
529 static DATA_BLOB samr_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
532 DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
533 generate_random_buffer(password.data, password.length);
535 for (i=0; i < len; i++) {
536 if (((uint16_t *)password.data)[i] == 0) {
537 ((uint16_t *)password.data)[i] = 1;
545 generate a random password for password change tests (fixed length)
547 static char *samr_rand_pass_fixed_len(TALLOC_CTX *mem_ctx, int len)
549 char *s = generate_random_str(mem_ctx, len);
550 printf("Generated password '%s'\n", s);
554 static bool test_SetUserPass(struct dcerpc_pipe *p, struct torture_context *tctx,
555 struct policy_handle *handle, char **password)
558 struct samr_SetUserInfo s;
559 union samr_UserInfo u;
561 DATA_BLOB session_key;
563 struct samr_GetUserPwInfo pwp;
564 struct samr_PwInfo info;
565 int policy_min_pw_len = 0;
566 pwp.in.user_handle = handle;
567 pwp.out.info = &info;
569 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
570 if (NT_STATUS_IS_OK(status)) {
571 policy_min_pw_len = pwp.out.info->min_password_length;
573 newpass = samr_rand_pass(tctx, policy_min_pw_len);
575 s.in.user_handle = handle;
579 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
580 u.info24.password_expired = 0;
582 status = dcerpc_fetch_session_key(p, &session_key);
583 if (!NT_STATUS_IS_OK(status)) {
584 printf("SetUserInfo level %u - no session key - %s\n",
585 s.in.level, nt_errstr(status));
589 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
591 torture_comment(tctx, "Testing SetUserInfo level 24 (set password)\n");
593 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
594 if (!NT_STATUS_IS_OK(status)) {
595 printf("SetUserInfo level %u failed - %s\n",
596 s.in.level, nt_errstr(status));
606 static bool test_SetUserPass_23(struct dcerpc_pipe *p, struct torture_context *tctx,
607 struct policy_handle *handle, uint32_t fields_present,
611 struct samr_SetUserInfo s;
612 union samr_UserInfo u;
614 DATA_BLOB session_key;
616 struct samr_GetUserPwInfo pwp;
617 struct samr_PwInfo info;
618 int policy_min_pw_len = 0;
619 pwp.in.user_handle = handle;
620 pwp.out.info = &info;
622 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
623 if (NT_STATUS_IS_OK(status)) {
624 policy_min_pw_len = pwp.out.info->min_password_length;
626 newpass = samr_rand_pass(tctx, policy_min_pw_len);
628 s.in.user_handle = handle;
634 u.info23.info.fields_present = fields_present;
636 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
638 status = dcerpc_fetch_session_key(p, &session_key);
639 if (!NT_STATUS_IS_OK(status)) {
640 printf("SetUserInfo level %u - no session key - %s\n",
641 s.in.level, nt_errstr(status));
645 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
647 torture_comment(tctx, "Testing SetUserInfo level 23 (set password)\n");
649 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
650 if (!NT_STATUS_IS_OK(status)) {
651 printf("SetUserInfo level %u failed - %s\n",
652 s.in.level, nt_errstr(status));
658 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
660 status = dcerpc_fetch_session_key(p, &session_key);
661 if (!NT_STATUS_IS_OK(status)) {
662 printf("SetUserInfo level %u - no session key - %s\n",
663 s.in.level, nt_errstr(status));
667 /* This should break the key nicely */
668 session_key.length--;
669 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
671 torture_comment(tctx, "Testing SetUserInfo level 23 (set password) with wrong password\n");
673 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
674 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
675 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
676 s.in.level, nt_errstr(status));
684 static bool test_SetUserPassEx(struct dcerpc_pipe *p, struct torture_context *tctx,
685 struct policy_handle *handle, bool makeshort,
689 struct samr_SetUserInfo s;
690 union samr_UserInfo u;
692 DATA_BLOB session_key;
693 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
694 uint8_t confounder[16];
696 struct MD5Context ctx;
697 struct samr_GetUserPwInfo pwp;
698 struct samr_PwInfo info;
699 int policy_min_pw_len = 0;
700 pwp.in.user_handle = handle;
701 pwp.out.info = &info;
703 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
704 if (NT_STATUS_IS_OK(status)) {
705 policy_min_pw_len = pwp.out.info->min_password_length;
707 if (makeshort && policy_min_pw_len) {
708 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len - 1);
710 newpass = samr_rand_pass(tctx, policy_min_pw_len);
713 s.in.user_handle = handle;
717 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
718 u.info26.password_expired = 0;
720 status = dcerpc_fetch_session_key(p, &session_key);
721 if (!NT_STATUS_IS_OK(status)) {
722 printf("SetUserInfo level %u - no session key - %s\n",
723 s.in.level, nt_errstr(status));
727 generate_random_buffer((uint8_t *)confounder, 16);
730 MD5Update(&ctx, confounder, 16);
731 MD5Update(&ctx, session_key.data, session_key.length);
732 MD5Final(confounded_session_key.data, &ctx);
734 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
735 memcpy(&u.info26.password.data[516], confounder, 16);
737 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex)\n");
739 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
740 if (!NT_STATUS_IS_OK(status)) {
741 printf("SetUserInfo level %u failed - %s\n",
742 s.in.level, nt_errstr(status));
748 /* This should break the key nicely */
749 confounded_session_key.data[0]++;
751 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
752 memcpy(&u.info26.password.data[516], confounder, 16);
754 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
756 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
757 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
758 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
759 s.in.level, nt_errstr(status));
768 static bool test_SetUserPass_25(struct dcerpc_pipe *p, struct torture_context *tctx,
769 struct policy_handle *handle, uint32_t fields_present,
773 struct samr_SetUserInfo s;
774 union samr_UserInfo u;
776 DATA_BLOB session_key;
777 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
778 struct MD5Context ctx;
779 uint8_t confounder[16];
781 struct samr_GetUserPwInfo pwp;
782 struct samr_PwInfo info;
783 int policy_min_pw_len = 0;
784 pwp.in.user_handle = handle;
785 pwp.out.info = &info;
787 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
788 if (NT_STATUS_IS_OK(status)) {
789 policy_min_pw_len = pwp.out.info->min_password_length;
791 newpass = samr_rand_pass(tctx, policy_min_pw_len);
793 s.in.user_handle = handle;
799 u.info25.info.fields_present = fields_present;
801 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
803 status = dcerpc_fetch_session_key(p, &session_key);
804 if (!NT_STATUS_IS_OK(status)) {
805 printf("SetUserInfo level %u - no session key - %s\n",
806 s.in.level, nt_errstr(status));
810 generate_random_buffer((uint8_t *)confounder, 16);
813 MD5Update(&ctx, confounder, 16);
814 MD5Update(&ctx, session_key.data, session_key.length);
815 MD5Final(confounded_session_key.data, &ctx);
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)\n");
822 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
823 if (!NT_STATUS_IS_OK(status)) {
824 printf("SetUserInfo level %u failed - %s\n",
825 s.in.level, nt_errstr(status));
831 /* This should break the key nicely */
832 confounded_session_key.data[0]++;
834 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
835 memcpy(&u.info25.password.data[516], confounder, 16);
837 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
839 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
840 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
841 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
842 s.in.level, nt_errstr(status));
849 static bool test_SetAliasInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
850 struct policy_handle *handle)
853 struct samr_SetAliasInfo r;
854 struct samr_QueryAliasInfo q;
855 union samr_AliasInfo *info;
856 uint16_t levels[] = {2, 3};
860 /* Ignoring switch level 1, as that includes the number of members for the alias
861 * and setting this to a wrong value might have negative consequences
864 for (i=0;i<ARRAY_SIZE(levels);i++) {
865 torture_comment(tctx, "Testing SetAliasInfo level %u\n", levels[i]);
867 r.in.alias_handle = handle;
868 r.in.level = levels[i];
869 r.in.info = talloc(tctx, union samr_AliasInfo);
870 switch (r.in.level) {
871 case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
872 case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
873 "Test Description, should test I18N as well"); break;
874 case ALIASINFOALL: printf("ALIASINFOALL ignored\n"); break;
877 status = dcerpc_samr_SetAliasInfo(p, tctx, &r);
878 if (!NT_STATUS_IS_OK(status)) {
879 printf("SetAliasInfo level %u failed - %s\n",
880 levels[i], nt_errstr(status));
884 q.in.alias_handle = handle;
885 q.in.level = levels[i];
888 status = dcerpc_samr_QueryAliasInfo(p, tctx, &q);
889 if (!NT_STATUS_IS_OK(status)) {
890 printf("QueryAliasInfo level %u failed - %s\n",
891 levels[i], nt_errstr(status));
899 static bool test_GetGroupsForUser(struct dcerpc_pipe *p, struct torture_context *tctx,
900 struct policy_handle *user_handle)
902 struct samr_GetGroupsForUser r;
903 struct samr_RidWithAttributeArray *rids = NULL;
906 torture_comment(tctx, "testing GetGroupsForUser\n");
908 r.in.user_handle = user_handle;
911 status = dcerpc_samr_GetGroupsForUser(p, tctx, &r);
912 torture_assert_ntstatus_ok(tctx, status, "GetGroupsForUser");
918 static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
919 struct lsa_String *domain_name)
922 struct samr_GetDomPwInfo r;
923 struct samr_PwInfo info;
925 r.in.domain_name = domain_name;
928 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
930 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
931 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
933 r.in.domain_name->string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
934 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
936 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
937 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
939 r.in.domain_name->string = "\\\\__NONAME__";
940 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
942 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
943 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
945 r.in.domain_name->string = "\\\\Builtin";
946 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
948 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
949 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
954 static bool test_GetUserPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
955 struct policy_handle *handle)
958 struct samr_GetUserPwInfo r;
959 struct samr_PwInfo info;
961 torture_comment(tctx, "Testing GetUserPwInfo\n");
963 r.in.user_handle = handle;
966 status = dcerpc_samr_GetUserPwInfo(p, tctx, &r);
967 torture_assert_ntstatus_ok(tctx, status, "GetUserPwInfo");
972 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, struct torture_context *tctx,
973 struct policy_handle *domain_handle, const char *name,
977 struct samr_LookupNames n;
978 struct lsa_String sname[2];
979 struct samr_Ids rids, types;
981 init_lsa_String(&sname[0], name);
983 n.in.domain_handle = domain_handle;
987 n.out.types = &types;
988 status = dcerpc_samr_LookupNames(p, tctx, &n);
989 if (NT_STATUS_IS_OK(status)) {
990 *rid = n.out.rids->ids[0];
995 init_lsa_String(&sname[1], "xxNONAMExx");
997 status = dcerpc_samr_LookupNames(p, tctx, &n);
998 if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
999 printf("LookupNames[2] failed - %s\n", nt_errstr(status));
1000 if (NT_STATUS_IS_OK(status)) {
1001 return NT_STATUS_UNSUCCESSFUL;
1007 status = dcerpc_samr_LookupNames(p, tctx, &n);
1008 if (!NT_STATUS_IS_OK(status)) {
1009 printf("LookupNames[0] failed - %s\n", nt_errstr(status));
1013 init_lsa_String(&sname[0], "xxNONAMExx");
1015 status = dcerpc_samr_LookupNames(p, tctx, &n);
1016 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1017 printf("LookupNames[1 bad name] failed - %s\n", nt_errstr(status));
1018 if (NT_STATUS_IS_OK(status)) {
1019 return NT_STATUS_UNSUCCESSFUL;
1024 init_lsa_String(&sname[0], "xxNONAMExx");
1025 init_lsa_String(&sname[1], "xxNONAME2xx");
1027 status = dcerpc_samr_LookupNames(p, tctx, &n);
1028 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1029 printf("LookupNames[2 bad names] failed - %s\n", nt_errstr(status));
1030 if (NT_STATUS_IS_OK(status)) {
1031 return NT_STATUS_UNSUCCESSFUL;
1036 return NT_STATUS_OK;
1039 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1040 struct policy_handle *domain_handle,
1041 const char *name, struct policy_handle *user_handle)
1044 struct samr_OpenUser r;
1047 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
1048 if (!NT_STATUS_IS_OK(status)) {
1052 r.in.domain_handle = domain_handle;
1053 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1055 r.out.user_handle = user_handle;
1056 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
1057 if (!NT_STATUS_IS_OK(status)) {
1058 printf("OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(status));
1065 static bool test_ChangePasswordNT3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1066 struct policy_handle *handle)
1069 struct samr_ChangePasswordUser r;
1071 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1072 struct policy_handle user_handle;
1073 char *oldpass = "test";
1074 char *newpass = "test2";
1075 uint8_t old_nt_hash[16], new_nt_hash[16];
1076 uint8_t old_lm_hash[16], new_lm_hash[16];
1078 status = test_OpenUser_byname(p, mem_ctx, handle, "testuser", &user_handle);
1079 if (!NT_STATUS_IS_OK(status)) {
1083 printf("Testing ChangePasswordUser for user 'testuser'\n");
1085 printf("old password: %s\n", oldpass);
1086 printf("new password: %s\n", newpass);
1088 E_md4hash(oldpass, old_nt_hash);
1089 E_md4hash(newpass, new_nt_hash);
1090 E_deshash(oldpass, old_lm_hash);
1091 E_deshash(newpass, new_lm_hash);
1093 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1094 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1095 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1096 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1097 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1098 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1100 r.in.handle = &user_handle;
1101 r.in.lm_present = 1;
1102 r.in.old_lm_crypted = &hash1;
1103 r.in.new_lm_crypted = &hash2;
1104 r.in.nt_present = 1;
1105 r.in.old_nt_crypted = &hash3;
1106 r.in.new_nt_crypted = &hash4;
1107 r.in.cross1_present = 1;
1108 r.in.nt_cross = &hash5;
1109 r.in.cross2_present = 1;
1110 r.in.lm_cross = &hash6;
1112 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1113 if (!NT_STATUS_IS_OK(status)) {
1114 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1118 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1126 static bool test_ChangePasswordUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1127 const char *acct_name,
1128 struct policy_handle *handle, char **password)
1131 struct samr_ChangePasswordUser r;
1133 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1134 struct policy_handle user_handle;
1136 uint8_t old_nt_hash[16], new_nt_hash[16];
1137 uint8_t old_lm_hash[16], new_lm_hash[16];
1138 bool changed = true;
1141 struct samr_GetUserPwInfo pwp;
1142 struct samr_PwInfo info;
1143 int policy_min_pw_len = 0;
1145 status = test_OpenUser_byname(p, tctx, handle, acct_name, &user_handle);
1146 if (!NT_STATUS_IS_OK(status)) {
1149 pwp.in.user_handle = &user_handle;
1150 pwp.out.info = &info;
1152 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1153 if (NT_STATUS_IS_OK(status)) {
1154 policy_min_pw_len = pwp.out.info->min_password_length;
1156 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1158 torture_comment(tctx, "Testing ChangePasswordUser\n");
1160 torture_assert(tctx, *password != NULL,
1161 "Failing ChangePasswordUser as old password was NULL. Previous test failed?");
1163 oldpass = *password;
1165 E_md4hash(oldpass, old_nt_hash);
1166 E_md4hash(newpass, new_nt_hash);
1167 E_deshash(oldpass, old_lm_hash);
1168 E_deshash(newpass, new_lm_hash);
1170 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1171 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1172 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1173 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1174 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1175 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1177 r.in.user_handle = &user_handle;
1178 r.in.lm_present = 1;
1179 /* Break the LM hash */
1181 r.in.old_lm_crypted = &hash1;
1182 r.in.new_lm_crypted = &hash2;
1183 r.in.nt_present = 1;
1184 r.in.old_nt_crypted = &hash3;
1185 r.in.new_nt_crypted = &hash4;
1186 r.in.cross1_present = 1;
1187 r.in.nt_cross = &hash5;
1188 r.in.cross2_present = 1;
1189 r.in.lm_cross = &hash6;
1191 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1192 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1193 "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash");
1195 /* Unbreak the LM hash */
1198 r.in.user_handle = &user_handle;
1199 r.in.lm_present = 1;
1200 r.in.old_lm_crypted = &hash1;
1201 r.in.new_lm_crypted = &hash2;
1202 /* Break the NT hash */
1204 r.in.nt_present = 1;
1205 r.in.old_nt_crypted = &hash3;
1206 r.in.new_nt_crypted = &hash4;
1207 r.in.cross1_present = 1;
1208 r.in.nt_cross = &hash5;
1209 r.in.cross2_present = 1;
1210 r.in.lm_cross = &hash6;
1212 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1213 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1214 "expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash");
1216 /* Unbreak the NT hash */
1219 r.in.user_handle = &user_handle;
1220 r.in.lm_present = 1;
1221 r.in.old_lm_crypted = &hash1;
1222 r.in.new_lm_crypted = &hash2;
1223 r.in.nt_present = 1;
1224 r.in.old_nt_crypted = &hash3;
1225 r.in.new_nt_crypted = &hash4;
1226 r.in.cross1_present = 1;
1227 r.in.nt_cross = &hash5;
1228 r.in.cross2_present = 1;
1229 /* Break the LM cross */
1231 r.in.lm_cross = &hash6;
1233 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1234 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1235 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status));
1239 /* Unbreak the LM cross */
1242 r.in.user_handle = &user_handle;
1243 r.in.lm_present = 1;
1244 r.in.old_lm_crypted = &hash1;
1245 r.in.new_lm_crypted = &hash2;
1246 r.in.nt_present = 1;
1247 r.in.old_nt_crypted = &hash3;
1248 r.in.new_nt_crypted = &hash4;
1249 r.in.cross1_present = 1;
1250 /* Break the NT cross */
1252 r.in.nt_cross = &hash5;
1253 r.in.cross2_present = 1;
1254 r.in.lm_cross = &hash6;
1256 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1257 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1258 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status));
1262 /* Unbreak the NT cross */
1266 /* Reset the hashes to not broken values */
1267 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1268 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1269 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1270 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1271 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1272 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1274 r.in.user_handle = &user_handle;
1275 r.in.lm_present = 1;
1276 r.in.old_lm_crypted = &hash1;
1277 r.in.new_lm_crypted = &hash2;
1278 r.in.nt_present = 1;
1279 r.in.old_nt_crypted = &hash3;
1280 r.in.new_nt_crypted = &hash4;
1281 r.in.cross1_present = 1;
1282 r.in.nt_cross = &hash5;
1283 r.in.cross2_present = 0;
1284 r.in.lm_cross = NULL;
1286 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1287 if (NT_STATUS_IS_OK(status)) {
1289 *password = newpass;
1290 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1291 printf("ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(status));
1296 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1298 E_md4hash(oldpass, old_nt_hash);
1299 E_md4hash(newpass, new_nt_hash);
1300 E_deshash(oldpass, old_lm_hash);
1301 E_deshash(newpass, new_lm_hash);
1304 /* Reset the hashes to not broken values */
1305 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1306 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1307 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1308 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1309 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1310 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1312 r.in.user_handle = &user_handle;
1313 r.in.lm_present = 1;
1314 r.in.old_lm_crypted = &hash1;
1315 r.in.new_lm_crypted = &hash2;
1316 r.in.nt_present = 1;
1317 r.in.old_nt_crypted = &hash3;
1318 r.in.new_nt_crypted = &hash4;
1319 r.in.cross1_present = 0;
1320 r.in.nt_cross = NULL;
1321 r.in.cross2_present = 1;
1322 r.in.lm_cross = &hash6;
1324 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1325 if (NT_STATUS_IS_OK(status)) {
1327 *password = newpass;
1328 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1329 printf("ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status));
1334 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1336 E_md4hash(oldpass, old_nt_hash);
1337 E_md4hash(newpass, new_nt_hash);
1338 E_deshash(oldpass, old_lm_hash);
1339 E_deshash(newpass, new_lm_hash);
1342 /* Reset the hashes to not broken values */
1343 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1344 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1345 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1346 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1347 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1348 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1350 r.in.user_handle = &user_handle;
1351 r.in.lm_present = 1;
1352 r.in.old_lm_crypted = &hash1;
1353 r.in.new_lm_crypted = &hash2;
1354 r.in.nt_present = 1;
1355 r.in.old_nt_crypted = &hash3;
1356 r.in.new_nt_crypted = &hash4;
1357 r.in.cross1_present = 1;
1358 r.in.nt_cross = &hash5;
1359 r.in.cross2_present = 1;
1360 r.in.lm_cross = &hash6;
1362 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1363 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1364 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1365 } else if (!NT_STATUS_IS_OK(status)) {
1366 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1370 *password = newpass;
1373 r.in.user_handle = &user_handle;
1374 r.in.lm_present = 1;
1375 r.in.old_lm_crypted = &hash1;
1376 r.in.new_lm_crypted = &hash2;
1377 r.in.nt_present = 1;
1378 r.in.old_nt_crypted = &hash3;
1379 r.in.new_nt_crypted = &hash4;
1380 r.in.cross1_present = 1;
1381 r.in.nt_cross = &hash5;
1382 r.in.cross2_present = 1;
1383 r.in.lm_cross = &hash6;
1386 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1387 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1388 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1389 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1390 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status));
1396 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
1404 static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
1405 const char *acct_name,
1406 struct policy_handle *handle, char **password)
1409 struct samr_OemChangePasswordUser2 r;
1411 struct samr_Password lm_verifier;
1412 struct samr_CryptPassword lm_pass;
1413 struct lsa_AsciiString server, account, account_bad;
1416 uint8_t old_lm_hash[16], new_lm_hash[16];
1418 struct samr_GetDomPwInfo dom_pw_info;
1419 struct samr_PwInfo info;
1420 int policy_min_pw_len = 0;
1422 struct lsa_String domain_name;
1424 domain_name.string = "";
1425 dom_pw_info.in.domain_name = &domain_name;
1426 dom_pw_info.out.info = &info;
1428 torture_comment(tctx, "Testing OemChangePasswordUser2\n");
1430 torture_assert(tctx, *password != NULL,
1431 "Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?");
1433 oldpass = *password;
1435 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
1436 if (NT_STATUS_IS_OK(status)) {
1437 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
1440 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1442 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1443 account.string = acct_name;
1445 E_deshash(oldpass, old_lm_hash);
1446 E_deshash(newpass, new_lm_hash);
1448 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1449 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1450 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1452 r.in.server = &server;
1453 r.in.account = &account;
1454 r.in.password = &lm_pass;
1455 r.in.hash = &lm_verifier;
1457 /* Break the verification */
1458 lm_verifier.hash[0]++;
1460 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1462 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1463 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1464 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1469 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1470 /* Break the old password */
1472 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1473 /* unbreak it for the next operation */
1475 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1477 r.in.server = &server;
1478 r.in.account = &account;
1479 r.in.password = &lm_pass;
1480 r.in.hash = &lm_verifier;
1482 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1484 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1485 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1486 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1491 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1492 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1494 r.in.server = &server;
1495 r.in.account = &account;
1496 r.in.password = &lm_pass;
1499 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1501 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1502 && !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1503 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
1508 /* This shouldn't be a valid name */
1509 account_bad.string = TEST_ACCOUNT_NAME "XX";
1510 r.in.account = &account_bad;
1512 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1514 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1515 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
1520 /* This shouldn't be a valid name */
1521 account_bad.string = TEST_ACCOUNT_NAME "XX";
1522 r.in.account = &account_bad;
1523 r.in.password = &lm_pass;
1524 r.in.hash = &lm_verifier;
1526 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1528 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1529 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1534 /* This shouldn't be a valid name */
1535 account_bad.string = TEST_ACCOUNT_NAME "XX";
1536 r.in.account = &account_bad;
1537 r.in.password = NULL;
1538 r.in.hash = &lm_verifier;
1540 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1542 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1543 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
1548 E_deshash(oldpass, old_lm_hash);
1549 E_deshash(newpass, new_lm_hash);
1551 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1552 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1553 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1555 r.in.server = &server;
1556 r.in.account = &account;
1557 r.in.password = &lm_pass;
1558 r.in.hash = &lm_verifier;
1560 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1561 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1562 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1563 } else if (!NT_STATUS_IS_OK(status)) {
1564 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
1567 *password = newpass;
1574 static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
1575 const char *acct_name,
1577 char *newpass, bool allow_password_restriction)
1580 struct samr_ChangePasswordUser2 r;
1582 struct lsa_String server, account;
1583 struct samr_CryptPassword nt_pass, lm_pass;
1584 struct samr_Password nt_verifier, lm_verifier;
1586 uint8_t old_nt_hash[16], new_nt_hash[16];
1587 uint8_t old_lm_hash[16], new_lm_hash[16];
1589 struct samr_GetDomPwInfo dom_pw_info;
1590 struct samr_PwInfo info;
1592 struct lsa_String domain_name;
1594 domain_name.string = "";
1595 dom_pw_info.in.domain_name = &domain_name;
1596 dom_pw_info.out.info = &info;
1598 torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name);
1600 torture_assert(tctx, *password != NULL,
1601 "Failing ChangePasswordUser2 as old password was NULL. Previous test failed?");
1602 oldpass = *password;
1605 int policy_min_pw_len = 0;
1606 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
1607 if (NT_STATUS_IS_OK(status)) {
1608 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
1611 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1614 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1615 init_lsa_String(&account, acct_name);
1617 E_md4hash(oldpass, old_nt_hash);
1618 E_md4hash(newpass, new_nt_hash);
1620 E_deshash(oldpass, old_lm_hash);
1621 E_deshash(newpass, new_lm_hash);
1623 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
1624 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1625 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1627 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1628 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1629 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1631 r.in.server = &server;
1632 r.in.account = &account;
1633 r.in.nt_password = &nt_pass;
1634 r.in.nt_verifier = &nt_verifier;
1636 r.in.lm_password = &lm_pass;
1637 r.in.lm_verifier = &lm_verifier;
1639 status = dcerpc_samr_ChangePasswordUser2(p, tctx, &r);
1640 if (allow_password_restriction && NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1641 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1642 } else if (!NT_STATUS_IS_OK(status)) {
1643 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
1646 *password = newpass;
1653 bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tctx,
1654 const char *account_string,
1655 int policy_min_pw_len,
1657 const char *newpass,
1658 NTTIME last_password_change,
1659 bool handle_reject_reason)
1662 struct samr_ChangePasswordUser3 r;
1664 struct lsa_String server, account, account_bad;
1665 struct samr_CryptPassword nt_pass, lm_pass;
1666 struct samr_Password nt_verifier, lm_verifier;
1668 uint8_t old_nt_hash[16], new_nt_hash[16];
1669 uint8_t old_lm_hash[16], new_lm_hash[16];
1671 struct samr_DomInfo1 *dominfo = NULL;
1672 struct samr_ChangeReject *reject = NULL;
1674 torture_comment(tctx, "Testing ChangePasswordUser3\n");
1676 if (newpass == NULL) {
1678 if (policy_min_pw_len == 0) {
1679 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1681 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len);
1683 } while (check_password_quality(newpass) == false);
1685 torture_comment(tctx, "Using password '%s'\n", newpass);
1688 torture_assert(tctx, *password != NULL,
1689 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
1691 oldpass = *password;
1692 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1693 init_lsa_String(&account, account_string);
1695 E_md4hash(oldpass, old_nt_hash);
1696 E_md4hash(newpass, new_nt_hash);
1698 E_deshash(oldpass, old_lm_hash);
1699 E_deshash(newpass, new_lm_hash);
1701 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1702 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1703 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1705 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1706 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1707 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1709 /* Break the verification */
1710 nt_verifier.hash[0]++;
1712 r.in.server = &server;
1713 r.in.account = &account;
1714 r.in.nt_password = &nt_pass;
1715 r.in.nt_verifier = &nt_verifier;
1717 r.in.lm_password = &lm_pass;
1718 r.in.lm_verifier = &lm_verifier;
1719 r.in.password3 = NULL;
1720 r.out.dominfo = &dominfo;
1721 r.out.reject = &reject;
1723 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1724 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1725 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1726 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1731 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1732 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1733 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1735 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1736 /* Break the NT hash */
1738 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1739 /* Unbreak it again */
1741 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1743 r.in.server = &server;
1744 r.in.account = &account;
1745 r.in.nt_password = &nt_pass;
1746 r.in.nt_verifier = &nt_verifier;
1748 r.in.lm_password = &lm_pass;
1749 r.in.lm_verifier = &lm_verifier;
1750 r.in.password3 = NULL;
1751 r.out.dominfo = &dominfo;
1752 r.out.reject = &reject;
1754 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1755 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1756 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1757 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1762 /* This shouldn't be a valid name */
1763 init_lsa_String(&account_bad, talloc_asprintf(tctx, "%sXX", account_string));
1765 r.in.account = &account_bad;
1766 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1767 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1768 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
1773 E_md4hash(oldpass, old_nt_hash);
1774 E_md4hash(newpass, new_nt_hash);
1776 E_deshash(oldpass, old_lm_hash);
1777 E_deshash(newpass, new_lm_hash);
1779 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1780 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1781 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1783 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1784 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1785 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1787 r.in.server = &server;
1788 r.in.account = &account;
1789 r.in.nt_password = &nt_pass;
1790 r.in.nt_verifier = &nt_verifier;
1792 r.in.lm_password = &lm_pass;
1793 r.in.lm_verifier = &lm_verifier;
1794 r.in.password3 = NULL;
1795 r.out.dominfo = &dominfo;
1796 r.out.reject = &reject;
1798 unix_to_nt_time(&t, time(NULL));
1800 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1802 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1805 && handle_reject_reason
1806 && (!null_nttime(last_password_change) || !dominfo->min_password_age)) {
1807 if (dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
1809 if (reject && (reject->reason != SAMR_REJECT_OTHER)) {
1810 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1811 SAMR_REJECT_OTHER, reject->reason);
1816 /* We tested the order of precendence which is as follows:
1825 if ((dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
1826 (last_password_change + dominfo->min_password_age > t)) {
1828 if (reject->reason != SAMR_REJECT_OTHER) {
1829 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1830 SAMR_REJECT_OTHER, reject->reason);
1834 } else if ((dominfo->min_password_length > 0) &&
1835 (strlen(newpass) < dominfo->min_password_length)) {
1837 if (reject->reason != SAMR_REJECT_TOO_SHORT) {
1838 printf("expected SAMR_REJECT_TOO_SHORT (%d), got %d\n",
1839 SAMR_REJECT_TOO_SHORT, reject->reason);
1843 } else if ((dominfo->password_history_length > 0) &&
1844 strequal(oldpass, newpass)) {
1846 if (reject->reason != SAMR_REJECT_IN_HISTORY) {
1847 printf("expected SAMR_REJECT_IN_HISTORY (%d), got %d\n",
1848 SAMR_REJECT_IN_HISTORY, reject->reason);
1851 } else if (dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
1853 if (reject->reason != SAMR_REJECT_COMPLEXITY) {
1854 printf("expected SAMR_REJECT_COMPLEXITY (%d), got %d\n",
1855 SAMR_REJECT_COMPLEXITY, reject->reason);
1861 if (reject->reason == SAMR_REJECT_TOO_SHORT) {
1862 /* retry with adjusted size */
1863 return test_ChangePasswordUser3(p, tctx, account_string,
1864 dominfo->min_password_length,
1865 password, NULL, 0, false);
1869 } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1870 if (reject && reject->reason != SAMR_REJECT_OTHER) {
1871 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1872 SAMR_REJECT_OTHER, reject->reason);
1875 /* Perhaps the server has a 'min password age' set? */
1878 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3");
1879 *password = talloc_strdup(tctx, newpass);
1885 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_context *tctx,
1886 const char *account_string,
1887 struct policy_handle *handle,
1891 struct samr_ChangePasswordUser3 r;
1892 struct samr_SetUserInfo s;
1893 union samr_UserInfo u;
1894 DATA_BLOB session_key;
1895 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
1896 uint8_t confounder[16];
1897 struct MD5Context ctx;
1900 struct lsa_String server, account;
1901 struct samr_CryptPassword nt_pass;
1902 struct samr_Password nt_verifier;
1903 DATA_BLOB new_random_pass;
1906 uint8_t old_nt_hash[16], new_nt_hash[16];
1908 struct samr_DomInfo1 *dominfo = NULL;
1909 struct samr_ChangeReject *reject = NULL;
1911 new_random_pass = samr_very_rand_pass(tctx, 128);
1913 torture_assert(tctx, *password != NULL,
1914 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
1916 oldpass = *password;
1917 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1918 init_lsa_String(&account, account_string);
1920 s.in.user_handle = handle;
1926 u.info25.info.fields_present = SAMR_FIELD_PASSWORD;
1928 set_pw_in_buffer(u.info25.password.data, &new_random_pass);
1930 status = dcerpc_fetch_session_key(p, &session_key);
1931 if (!NT_STATUS_IS_OK(status)) {
1932 printf("SetUserInfo level %u - no session key - %s\n",
1933 s.in.level, nt_errstr(status));
1937 generate_random_buffer((uint8_t *)confounder, 16);
1940 MD5Update(&ctx, confounder, 16);
1941 MD5Update(&ctx, session_key.data, session_key.length);
1942 MD5Final(confounded_session_key.data, &ctx);
1944 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
1945 memcpy(&u.info25.password.data[516], confounder, 16);
1947 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
1949 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1950 if (!NT_STATUS_IS_OK(status)) {
1951 printf("SetUserInfo level %u failed - %s\n",
1952 s.in.level, nt_errstr(status));
1956 torture_comment(tctx, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
1958 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
1960 new_random_pass = samr_very_rand_pass(tctx, 128);
1962 mdfour(new_nt_hash, new_random_pass.data, new_random_pass.length);
1964 set_pw_in_buffer(nt_pass.data, &new_random_pass);
1965 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1966 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1968 r.in.server = &server;
1969 r.in.account = &account;
1970 r.in.nt_password = &nt_pass;
1971 r.in.nt_verifier = &nt_verifier;
1973 r.in.lm_password = NULL;
1974 r.in.lm_verifier = NULL;
1975 r.in.password3 = NULL;
1976 r.out.dominfo = &dominfo;
1977 r.out.reject = &reject;
1979 unix_to_nt_time(&t, time(NULL));
1981 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1983 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1984 if (reject && reject->reason != SAMR_REJECT_OTHER) {
1985 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1986 SAMR_REJECT_OTHER, reject->reason);
1989 /* Perhaps the server has a 'min password age' set? */
1991 } else if (!NT_STATUS_IS_OK(status)) {
1992 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
1996 newpass = samr_rand_pass(tctx, 128);
1998 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2000 E_md4hash(newpass, new_nt_hash);
2002 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2003 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2004 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2006 r.in.server = &server;
2007 r.in.account = &account;
2008 r.in.nt_password = &nt_pass;
2009 r.in.nt_verifier = &nt_verifier;
2011 r.in.lm_password = NULL;
2012 r.in.lm_verifier = NULL;
2013 r.in.password3 = NULL;
2014 r.out.dominfo = &dominfo;
2015 r.out.reject = &reject;
2017 unix_to_nt_time(&t, time(NULL));
2019 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2021 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2022 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2023 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2024 SAMR_REJECT_OTHER, reject->reason);
2027 /* Perhaps the server has a 'min password age' set? */
2030 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3 (on second random password)");
2031 *password = talloc_strdup(tctx, newpass);
2038 static bool test_GetMembersInAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2039 struct policy_handle *alias_handle)
2041 struct samr_GetMembersInAlias r;
2042 struct lsa_SidArray sids;
2045 torture_comment(tctx, "Testing GetMembersInAlias\n");
2047 r.in.alias_handle = alias_handle;
2050 status = dcerpc_samr_GetMembersInAlias(p, tctx, &r);
2051 torture_assert_ntstatus_ok(tctx, status, "GetMembersInAlias");
2056 static bool test_AddMemberToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2057 struct policy_handle *alias_handle,
2058 const struct dom_sid *domain_sid)
2060 struct samr_AddAliasMember r;
2061 struct samr_DeleteAliasMember d;
2063 struct dom_sid *sid;
2065 sid = dom_sid_add_rid(tctx, domain_sid, 512);
2067 torture_comment(tctx, "testing AddAliasMember\n");
2068 r.in.alias_handle = alias_handle;
2071 status = dcerpc_samr_AddAliasMember(p, tctx, &r);
2072 torture_assert_ntstatus_ok(tctx, status, "AddAliasMember");
2074 d.in.alias_handle = alias_handle;
2077 status = dcerpc_samr_DeleteAliasMember(p, tctx, &d);
2078 torture_assert_ntstatus_ok(tctx, status, "DelAliasMember");
2083 static bool test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2084 struct policy_handle *alias_handle)
2086 struct samr_AddMultipleMembersToAlias a;
2087 struct samr_RemoveMultipleMembersFromAlias r;
2089 struct lsa_SidArray sids;
2091 torture_comment(tctx, "testing AddMultipleMembersToAlias\n");
2092 a.in.alias_handle = alias_handle;
2096 sids.sids = talloc_array(tctx, struct lsa_SidPtr, 3);
2098 sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2099 sids.sids[1].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-2");
2100 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-3");
2102 status = dcerpc_samr_AddMultipleMembersToAlias(p, tctx, &a);
2103 torture_assert_ntstatus_ok(tctx, status, "AddMultipleMembersToAlias");
2106 torture_comment(tctx, "testing RemoveMultipleMembersFromAlias\n");
2107 r.in.alias_handle = alias_handle;
2110 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2111 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2113 /* strange! removing twice doesn't give any error */
2114 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2115 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2117 /* but removing an alias that isn't there does */
2118 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-4");
2120 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2121 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, "RemoveMultipleMembersFromAlias");
2126 static bool test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2127 struct policy_handle *user_handle)
2129 struct samr_TestPrivateFunctionsUser r;
2132 torture_comment(tctx, "Testing TestPrivateFunctionsUser\n");
2134 r.in.user_handle = user_handle;
2136 status = dcerpc_samr_TestPrivateFunctionsUser(p, tctx, &r);
2137 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsUser");
2143 static bool test_user_ops(struct dcerpc_pipe *p,
2144 struct torture_context *tctx,
2145 struct policy_handle *user_handle,
2146 struct policy_handle *domain_handle,
2147 uint32_t base_acct_flags,
2148 const char *base_acct_name, enum torture_samr_choice which_ops)
2150 char *password = NULL;
2151 struct samr_QueryUserInfo q;
2152 union samr_UserInfo *info;
2158 const uint32_t password_fields[] = {
2159 SAMR_FIELD_PASSWORD,
2160 SAMR_FIELD_PASSWORD2,
2161 SAMR_FIELD_PASSWORD | SAMR_FIELD_PASSWORD2,
2165 status = test_LookupName(p, tctx, domain_handle, base_acct_name, &rid);
2166 if (!NT_STATUS_IS_OK(status)) {
2170 switch (which_ops) {
2171 case TORTURE_SAMR_USER_ATTRIBUTES:
2172 if (!test_QuerySecurity(p, tctx, user_handle)) {
2176 if (!test_QueryUserInfo(p, tctx, user_handle)) {
2180 if (!test_QueryUserInfo2(p, tctx, user_handle)) {
2184 if (!test_SetUserInfo(p, tctx, user_handle, base_acct_flags,
2189 if (!test_GetUserPwInfo(p, tctx, user_handle)) {
2193 if (!test_TestPrivateFunctionsUser(p, tctx, user_handle)) {
2197 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
2201 case TORTURE_SAMR_PASSWORDS:
2202 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
2203 char simple_pass[9];
2204 char *v = generate_random_str(tctx, 1);
2206 ZERO_STRUCT(simple_pass);
2207 memset(simple_pass, *v, sizeof(simple_pass) - 1);
2209 printf("Testing machine account password policy rules\n");
2211 /* Workstation trust accounts don't seem to need to honour password quality policy */
2212 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
2216 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
2220 /* reset again, to allow another 'user' password change */
2221 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
2225 /* Try a 'short' password */
2226 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
2230 /* Try a compleatly random password */
2231 if (!test_ChangePasswordRandomBytes(p, tctx, base_acct_name, user_handle, &password)) {
2236 for (i = 0; password_fields[i]; i++) {
2237 if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
2241 /* check it was set right */
2242 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
2247 for (i = 0; password_fields[i]; i++) {
2248 if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
2252 /* check it was set right */
2253 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
2258 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
2262 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
2266 q.in.user_handle = user_handle;
2270 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
2271 if (!NT_STATUS_IS_OK(status)) {
2272 printf("QueryUserInfo level %u failed - %s\n",
2273 q.in.level, nt_errstr(status));
2276 uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
2277 if ((info->info5.acct_flags) != expected_flags) {
2278 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2279 info->info5.acct_flags,
2283 if (info->info5.rid != rid) {
2284 printf("QuerUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
2285 info->info5.rid, rid);
2291 case TORTURE_SAMR_OTHER:
2292 /* We just need the account to exist */
2298 static bool test_alias_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
2299 struct policy_handle *alias_handle,
2300 const struct dom_sid *domain_sid)
2304 if (!test_QuerySecurity(p, tctx, alias_handle)) {
2308 if (!test_QueryAliasInfo(p, tctx, alias_handle)) {
2312 if (!test_SetAliasInfo(p, tctx, alias_handle)) {
2316 if (!test_AddMemberToAlias(p, tctx, alias_handle, domain_sid)) {
2320 if (torture_setting_bool(tctx, "samba4", false)) {
2321 printf("skipping MultipleMembers Alias tests against Samba4\n");
2325 if (!test_AddMultipleMembersToAlias(p, tctx, alias_handle)) {
2333 static bool test_DeleteUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2334 struct policy_handle *user_handle)
2336 struct samr_DeleteUser d;
2338 torture_comment(tctx, "Testing DeleteUser\n");
2340 d.in.user_handle = user_handle;
2341 d.out.user_handle = user_handle;
2343 status = dcerpc_samr_DeleteUser(p, tctx, &d);
2344 torture_assert_ntstatus_ok(tctx, status, "DeleteUser");
2349 bool test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2350 struct policy_handle *handle, const char *name)
2353 struct samr_DeleteUser d;
2354 struct policy_handle user_handle;
2357 status = test_LookupName(p, mem_ctx, handle, name, &rid);
2358 if (!NT_STATUS_IS_OK(status)) {
2362 status = test_OpenUser_byname(p, mem_ctx, handle, name, &user_handle);
2363 if (!NT_STATUS_IS_OK(status)) {
2367 d.in.user_handle = &user_handle;
2368 d.out.user_handle = &user_handle;
2369 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
2370 if (!NT_STATUS_IS_OK(status)) {
2377 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
2382 static bool test_DeleteGroup_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2383 struct policy_handle *handle, const char *name)
2386 struct samr_OpenGroup r;
2387 struct samr_DeleteDomainGroup d;
2388 struct policy_handle group_handle;
2391 status = test_LookupName(p, mem_ctx, handle, name, &rid);
2392 if (!NT_STATUS_IS_OK(status)) {
2396 r.in.domain_handle = handle;
2397 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2399 r.out.group_handle = &group_handle;
2400 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
2401 if (!NT_STATUS_IS_OK(status)) {
2405 d.in.group_handle = &group_handle;
2406 d.out.group_handle = &group_handle;
2407 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
2408 if (!NT_STATUS_IS_OK(status)) {
2415 printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
2420 static bool test_DeleteAlias_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2421 struct policy_handle *domain_handle, const char *name)
2424 struct samr_OpenAlias r;
2425 struct samr_DeleteDomAlias d;
2426 struct policy_handle alias_handle;
2429 printf("testing DeleteAlias_byname\n");
2431 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
2432 if (!NT_STATUS_IS_OK(status)) {
2436 r.in.domain_handle = domain_handle;
2437 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2439 r.out.alias_handle = &alias_handle;
2440 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
2441 if (!NT_STATUS_IS_OK(status)) {
2445 d.in.alias_handle = &alias_handle;
2446 d.out.alias_handle = &alias_handle;
2447 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
2448 if (!NT_STATUS_IS_OK(status)) {
2455 printf("DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
2459 static bool test_DeleteAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2460 struct policy_handle *alias_handle)
2462 struct samr_DeleteDomAlias d;
2465 printf("Testing DeleteAlias\n");
2467 d.in.alias_handle = alias_handle;
2468 d.out.alias_handle = alias_handle;
2470 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
2471 if (!NT_STATUS_IS_OK(status)) {
2472 printf("DeleteAlias failed - %s\n", nt_errstr(status));
2479 static bool test_CreateAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2480 struct policy_handle *domain_handle,
2481 struct policy_handle *alias_handle,
2482 const struct dom_sid *domain_sid)
2485 struct samr_CreateDomAlias r;
2486 struct lsa_String name;
2490 init_lsa_String(&name, TEST_ALIASNAME);
2491 r.in.domain_handle = domain_handle;
2492 r.in.alias_name = &name;
2493 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2494 r.out.alias_handle = alias_handle;
2497 printf("Testing CreateAlias (%s)\n", r.in.alias_name->string);
2499 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
2501 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
2502 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2503 printf("Server correctly refused create of '%s'\n", r.in.alias_name->string);
2506 printf("Server should have refused create of '%s', got %s instead\n", r.in.alias_name->string,
2512 if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
2513 if (!test_DeleteAlias_byname(p, tctx, domain_handle, r.in.alias_name->string)) {
2516 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
2519 if (!NT_STATUS_IS_OK(status)) {
2520 printf("CreateAlias failed - %s\n", nt_errstr(status));
2524 if (!test_alias_ops(p, tctx, alias_handle, domain_sid)) {
2531 static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2532 const char *acct_name,
2533 struct policy_handle *domain_handle, char **password)
2541 if (!test_ChangePasswordUser(p, mem_ctx, acct_name, domain_handle, password)) {
2545 if (!test_ChangePasswordUser2(p, mem_ctx, acct_name, password, 0, true)) {
2549 if (!test_OemChangePasswordUser2(p, mem_ctx, acct_name, domain_handle, password)) {
2553 /* test what happens when setting the old password again */
2554 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, *password, 0, true)) {
2559 char simple_pass[9];
2560 char *v = generate_random_str(mem_ctx, 1);
2562 ZERO_STRUCT(simple_pass);
2563 memset(simple_pass, *v, sizeof(simple_pass) - 1);
2565 /* test what happens when picking a simple password */
2566 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, simple_pass, 0, true)) {
2571 /* set samr_SetDomainInfo level 1 with min_length 5 */
2573 struct samr_QueryDomainInfo r;
2574 union samr_DomainInfo *info = NULL;
2575 struct samr_SetDomainInfo s;
2576 uint16_t len_old, len;
2577 uint32_t pwd_prop_old;
2578 int64_t min_pwd_age_old;
2583 r.in.domain_handle = domain_handle;
2587 printf("testing samr_QueryDomainInfo level 1\n");
2588 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2589 if (!NT_STATUS_IS_OK(status)) {
2593 s.in.domain_handle = domain_handle;
2597 /* remember the old min length, so we can reset it */
2598 len_old = s.in.info->info1.min_password_length;
2599 s.in.info->info1.min_password_length = len;
2600 pwd_prop_old = s.in.info->info1.password_properties;
2601 /* turn off password complexity checks for this test */
2602 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
2604 min_pwd_age_old = s.in.info->info1.min_password_age;
2605 s.in.info->info1.min_password_age = 0;
2607 printf("testing samr_SetDomainInfo level 1\n");
2608 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2609 if (!NT_STATUS_IS_OK(status)) {
2613 printf("calling test_ChangePasswordUser3 with too short password\n");
2615 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, len - 1, password, NULL, 0, true)) {
2619 s.in.info->info1.min_password_length = len_old;
2620 s.in.info->info1.password_properties = pwd_prop_old;
2621 s.in.info->info1.min_password_age = min_pwd_age_old;
2623 printf("testing samr_SetDomainInfo level 1\n");
2624 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2625 if (!NT_STATUS_IS_OK(status)) {
2633 struct samr_OpenUser r;
2634 struct samr_QueryUserInfo q;
2635 union samr_UserInfo *info;
2636 struct samr_LookupNames n;
2637 struct policy_handle user_handle;
2638 struct samr_Ids rids, types;
2640 n.in.domain_handle = domain_handle;
2642 n.in.names = talloc_array(mem_ctx, struct lsa_String, 1);
2643 n.in.names[0].string = acct_name;
2645 n.out.types = &types;
2647 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
2648 if (!NT_STATUS_IS_OK(status)) {
2649 printf("LookupNames failed - %s\n", nt_errstr(status));
2653 r.in.domain_handle = domain_handle;
2654 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2655 r.in.rid = n.out.rids->ids[0];
2656 r.out.user_handle = &user_handle;
2658 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
2659 if (!NT_STATUS_IS_OK(status)) {
2660 printf("OpenUser(%u) failed - %s\n", n.out.rids->ids[0], nt_errstr(status));
2664 q.in.user_handle = &user_handle;
2668 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
2669 if (!NT_STATUS_IS_OK(status)) {
2670 printf("QueryUserInfo failed - %s\n", nt_errstr(status));
2674 printf("calling test_ChangePasswordUser3 with too early password change\n");
2676 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL,
2677 info->info5.last_password_change, true)) {
2682 /* we change passwords twice - this has the effect of verifying
2683 they were changed correctly for the final call */
2684 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, true)) {
2688 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, true)) {
2695 static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2696 struct policy_handle *domain_handle,
2697 struct policy_handle *user_handle_out,
2698 struct dom_sid *domain_sid,
2699 enum torture_samr_choice which_ops)
2702 TALLOC_CTX *user_ctx;
2705 struct samr_CreateUser r;
2706 struct samr_QueryUserInfo q;
2707 union samr_UserInfo *info;
2708 struct samr_DeleteUser d;
2711 /* This call creates a 'normal' account - check that it really does */
2712 const uint32_t acct_flags = ACB_NORMAL;
2713 struct lsa_String name;
2716 struct policy_handle user_handle;
2717 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
2718 init_lsa_String(&name, TEST_ACCOUNT_NAME);
2720 r.in.domain_handle = domain_handle;
2721 r.in.account_name = &name;
2722 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2723 r.out.user_handle = &user_handle;
2726 printf("Testing CreateUser(%s)\n", r.in.account_name->string);
2728 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
2730 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
2731 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
2732 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
2735 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
2741 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
2742 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
2743 talloc_free(user_ctx);
2746 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
2748 if (!NT_STATUS_IS_OK(status)) {
2749 talloc_free(user_ctx);
2750 printf("CreateUser failed - %s\n", nt_errstr(status));
2753 q.in.user_handle = &user_handle;
2757 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
2758 if (!NT_STATUS_IS_OK(status)) {
2759 printf("QueryUserInfo level %u failed - %s\n",
2760 q.in.level, nt_errstr(status));
2763 if ((info->info16.acct_flags & acct_flags) != acct_flags) {
2764 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2765 info->info16.acct_flags,
2771 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
2772 acct_flags, name.string, which_ops)) {
2776 if (user_handle_out) {
2777 *user_handle_out = user_handle;
2779 printf("Testing DeleteUser (createuser test)\n");
2781 d.in.user_handle = &user_handle;
2782 d.out.user_handle = &user_handle;
2784 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
2785 if (!NT_STATUS_IS_OK(status)) {
2786 printf("DeleteUser failed - %s\n", nt_errstr(status));
2793 talloc_free(user_ctx);
2799 static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
2800 struct policy_handle *domain_handle,
2801 struct dom_sid *domain_sid,
2802 enum torture_samr_choice which_ops)
2805 struct samr_CreateUser2 r;
2806 struct samr_QueryUserInfo q;
2807 union samr_UserInfo *info;
2808 struct samr_DeleteUser d;
2809 struct policy_handle user_handle;
2811 struct lsa_String name;
2816 uint32_t acct_flags;
2817 const char *account_name;
2819 } account_types[] = {
2820 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
2821 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2822 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2823 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
2824 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2825 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2826 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
2827 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2828 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2829 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
2830 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
2831 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
2832 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2833 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2834 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
2837 for (i = 0; account_types[i].account_name; i++) {
2838 TALLOC_CTX *user_ctx;
2839 uint32_t acct_flags = account_types[i].acct_flags;
2840 uint32_t access_granted;
2841 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
2842 init_lsa_String(&name, account_types[i].account_name);
2844 r.in.domain_handle = domain_handle;
2845 r.in.account_name = &name;
2846 r.in.acct_flags = acct_flags;
2847 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2848 r.out.user_handle = &user_handle;
2849 r.out.access_granted = &access_granted;
2852 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
2854 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
2856 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
2857 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
2858 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
2861 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
2868 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
2869 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
2870 talloc_free(user_ctx);
2874 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
2877 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
2878 printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
2879 nt_errstr(status), nt_errstr(account_types[i].nt_status));
2883 if (NT_STATUS_IS_OK(status)) {
2884 q.in.user_handle = &user_handle;
2888 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
2889 if (!NT_STATUS_IS_OK(status)) {
2890 printf("QueryUserInfo level %u failed - %s\n",
2891 q.in.level, nt_errstr(status));
2894 uint32_t expected_flags = (acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
2895 if (acct_flags == ACB_NORMAL) {
2896 expected_flags |= ACB_PW_EXPIRED;
2898 if ((info->info5.acct_flags) != expected_flags) {
2899 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2900 info->info5.acct_flags,
2904 switch (acct_flags) {
2906 if (info->info5.primary_gid != DOMAIN_RID_DCS) {
2907 printf("QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n",
2908 DOMAIN_RID_DCS, info->info5.primary_gid);
2913 if (info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
2914 printf("QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
2915 DOMAIN_RID_DOMAIN_MEMBERS, info->info5.primary_gid);
2920 if (info->info5.primary_gid != DOMAIN_RID_USERS) {
2921 printf("QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n",
2922 DOMAIN_RID_USERS, info->info5.primary_gid);
2929 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
2930 acct_flags, name.string, which_ops)) {
2934 printf("Testing DeleteUser (createuser2 test)\n");
2936 d.in.user_handle = &user_handle;
2937 d.out.user_handle = &user_handle;
2939 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
2940 if (!NT_STATUS_IS_OK(status)) {
2941 printf("DeleteUser failed - %s\n", nt_errstr(status));
2945 talloc_free(user_ctx);
2951 static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2952 struct policy_handle *handle)
2955 struct samr_QueryAliasInfo r;
2956 union samr_AliasInfo *info;
2957 uint16_t levels[] = {1, 2, 3};
2961 for (i=0;i<ARRAY_SIZE(levels);i++) {
2962 printf("Testing QueryAliasInfo level %u\n", levels[i]);
2964 r.in.alias_handle = handle;
2965 r.in.level = levels[i];
2968 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
2969 if (!NT_STATUS_IS_OK(status)) {
2970 printf("QueryAliasInfo level %u failed - %s\n",
2971 levels[i], nt_errstr(status));
2979 static bool test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2980 struct policy_handle *handle)
2983 struct samr_QueryGroupInfo r;
2984 union samr_GroupInfo *info;
2985 uint16_t levels[] = {1, 2, 3, 4, 5};
2989 for (i=0;i<ARRAY_SIZE(levels);i++) {
2990 printf("Testing QueryGroupInfo level %u\n", levels[i]);
2992 r.in.group_handle = handle;
2993 r.in.level = levels[i];
2996 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
2997 if (!NT_STATUS_IS_OK(status)) {
2998 printf("QueryGroupInfo level %u failed - %s\n",
2999 levels[i], nt_errstr(status));
3007 static bool test_QueryGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3008 struct policy_handle *handle)
3011 struct samr_QueryGroupMember r;
3012 struct samr_RidTypeArray *rids = NULL;
3015 printf("Testing QueryGroupMember\n");
3017 r.in.group_handle = handle;
3020 status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &r);
3021 if (!NT_STATUS_IS_OK(status)) {
3022 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
3030 static bool test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3031 struct policy_handle *handle)
3034 struct samr_QueryGroupInfo r;
3035 union samr_GroupInfo *info;
3036 struct samr_SetGroupInfo s;
3037 uint16_t levels[] = {1, 2, 3, 4};
3038 uint16_t set_ok[] = {0, 1, 1, 1};
3042 for (i=0;i<ARRAY_SIZE(levels);i++) {
3043 printf("Testing QueryGroupInfo level %u\n", levels[i]);
3045 r.in.group_handle = handle;
3046 r.in.level = levels[i];
3049 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
3050 if (!NT_STATUS_IS_OK(status)) {
3051 printf("QueryGroupInfo level %u failed - %s\n",
3052 levels[i], nt_errstr(status));
3056 printf("Testing SetGroupInfo level %u\n", levels[i]);
3058 s.in.group_handle = handle;
3059 s.in.level = levels[i];
3060 s.in.info = *r.out.info;
3063 /* disabled this, as it changes the name only from the point of view of samr,
3064 but leaves the name from the point of view of w2k3 internals (and ldap). This means
3065 the name is still reserved, so creating the old name fails, but deleting by the old name
3067 if (s.in.level == 2) {
3068 init_lsa_String(&s.in.info->string, "NewName");
3072 if (s.in.level == 4) {
3073 init_lsa_String(&s.in.info->description, "test description");
3076 status = dcerpc_samr_SetGroupInfo(p, mem_ctx, &s);
3078 if (!NT_STATUS_IS_OK(status)) {
3079 printf("SetGroupInfo level %u failed - %s\n",
3080 r.in.level, nt_errstr(status));
3085 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
3086 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
3087 r.in.level, nt_errstr(status));
3097 static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3098 struct policy_handle *handle)
3101 struct samr_QueryUserInfo r;
3102 union samr_UserInfo *info;
3103 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
3104 11, 12, 13, 14, 16, 17, 20, 21};
3108 for (i=0;i<ARRAY_SIZE(levels);i++) {
3109 printf("Testing QueryUserInfo level %u\n", levels[i]);
3111 r.in.user_handle = handle;
3112 r.in.level = levels[i];
3115 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
3116 if (!NT_STATUS_IS_OK(status)) {
3117 printf("QueryUserInfo level %u failed - %s\n",
3118 levels[i], nt_errstr(status));
3126 static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3127 struct policy_handle *handle)
3130 struct samr_QueryUserInfo2 r;
3131 union samr_UserInfo *info;
3132 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
3133 11, 12, 13, 14, 16, 17, 20, 21};
3137 for (i=0;i<ARRAY_SIZE(levels);i++) {
3138 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
3140 r.in.user_handle = handle;
3141 r.in.level = levels[i];
3144 status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r);
3145 if (!NT_STATUS_IS_OK(status)) {
3146 printf("QueryUserInfo2 level %u failed - %s\n",
3147 levels[i], nt_errstr(status));
3155 static bool test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3156 struct policy_handle *handle, uint32_t rid)
3159 struct samr_OpenUser r;
3160 struct policy_handle user_handle;
3163 printf("Testing OpenUser(%u)\n", rid);
3165 r.in.domain_handle = handle;
3166 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3168 r.out.user_handle = &user_handle;
3170 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3171 if (!NT_STATUS_IS_OK(status)) {
3172 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
3176 if (!test_QuerySecurity(p, mem_ctx, &user_handle)) {
3180 if (!test_QueryUserInfo(p, mem_ctx, &user_handle)) {
3184 if (!test_QueryUserInfo2(p, mem_ctx, &user_handle)) {
3188 if (!test_GetUserPwInfo(p, mem_ctx, &user_handle)) {
3192 if (!test_GetGroupsForUser(p,mem_ctx, &user_handle)) {
3196 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
3203 static bool test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3204 struct policy_handle *handle, uint32_t rid)
3207 struct samr_OpenGroup r;
3208 struct policy_handle group_handle;
3211 printf("Testing OpenGroup(%u)\n", rid);
3213 r.in.domain_handle = handle;
3214 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3216 r.out.group_handle = &group_handle;
3218 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
3219 if (!NT_STATUS_IS_OK(status)) {
3220 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
3224 if (!test_QuerySecurity(p, mem_ctx, &group_handle)) {
3228 if (!test_QueryGroupInfo(p, mem_ctx, &group_handle)) {
3232 if (!test_QueryGroupMember(p, mem_ctx, &group_handle)) {
3236 if (!test_samr_handle_Close(p, mem_ctx, &group_handle)) {
3243 static bool test_OpenAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
3244 struct policy_handle *handle, uint32_t rid)
3247 struct samr_OpenAlias r;
3248 struct policy_handle alias_handle;
3251 torture_comment(tctx, "Testing OpenAlias(%u)\n", rid);
3253 r.in.domain_handle = handle;
3254 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3256 r.out.alias_handle = &alias_handle;
3258 status = dcerpc_samr_OpenAlias(p, tctx, &r);
3259 if (!NT_STATUS_IS_OK(status)) {
3260 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
3264 if (!test_QuerySecurity(p, tctx, &alias_handle)) {
3268 if (!test_QueryAliasInfo(p, tctx, &alias_handle)) {
3272 if (!test_GetMembersInAlias(p, tctx, &alias_handle)) {
3276 if (!test_samr_handle_Close(p, tctx, &alias_handle)) {
3283 static bool check_mask(struct dcerpc_pipe *p, struct torture_context *tctx,
3284 struct policy_handle *handle, uint32_t rid,
3285 uint32_t acct_flag_mask)
3288 struct samr_OpenUser r;
3289 struct samr_QueryUserInfo q;
3290 union samr_UserInfo *info;
3291 struct policy_handle user_handle;
3294 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
3296 r.in.domain_handle = handle;
3297 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3299 r.out.user_handle = &user_handle;
3301 status = dcerpc_samr_OpenUser(p, tctx, &r);
3302 if (!NT_STATUS_IS_OK(status)) {
3303 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
3307 q.in.user_handle = &user_handle;
3311 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
3312 if (!NT_STATUS_IS_OK(status)) {
3313 printf("QueryUserInfo level 16 failed - %s\n",
3317 if ((acct_flag_mask & info->info16.acct_flags) == 0) {
3318 printf("Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
3319 acct_flag_mask, info->info16.acct_flags, rid);
3324 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
3331 static bool test_EnumDomainUsers(struct dcerpc_pipe *p, struct torture_context *tctx,
3332 struct policy_handle *handle)
3334 NTSTATUS status = STATUS_MORE_ENTRIES;
3335 struct samr_EnumDomainUsers r;
3336 uint32_t mask, resume_handle=0;
3339 struct samr_LookupNames n;
3340 struct samr_LookupRids lr ;
3341 struct lsa_Strings names;
3342 struct samr_Ids rids, types;
3343 struct samr_SamArray *sam = NULL;
3344 uint32_t num_entries = 0;
3346 uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
3347 ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
3348 ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
3351 printf("Testing EnumDomainUsers\n");
3353 for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
3354 r.in.domain_handle = handle;
3355 r.in.resume_handle = &resume_handle;
3356 r.in.acct_flags = mask = masks[mask_idx];
3357 r.in.max_size = (uint32_t)-1;
3358 r.out.resume_handle = &resume_handle;
3359 r.out.num_entries = &num_entries;
3362 status = dcerpc_samr_EnumDomainUsers(p, tctx, &r);
3363 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
3364 !NT_STATUS_IS_OK(status)) {
3365 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
3369 torture_assert(tctx, sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
3371 if (sam->count == 0) {
3375 for (i=0;i<sam->count;i++) {
3377 if (!check_mask(p, tctx, handle, sam->entries[i].idx, mask)) {
3380 } else if (!test_OpenUser(p, tctx, handle, sam->entries[i].idx)) {
3386 printf("Testing LookupNames\n");
3387 n.in.domain_handle = handle;
3388 n.in.num_names = sam->count;
3389 n.in.names = talloc_array(tctx, struct lsa_String, sam->count);
3391 n.out.types = &types;
3392 for (i=0;i<sam->count;i++) {
3393 n.in.names[i].string = sam->entries[i].name.string;
3395 status = dcerpc_samr_LookupNames(p, tctx, &n);
3396 if (!NT_STATUS_IS_OK(status)) {
3397 printf("LookupNames failed - %s\n", nt_errstr(status));
3402 printf("Testing LookupRids\n");
3403 lr.in.domain_handle = handle;
3404 lr.in.num_rids = sam->count;
3405 lr.in.rids = talloc_array(tctx, uint32_t, sam->count);
3406 lr.out.names = &names;
3407 lr.out.types = &types;
3408 for (i=0;i<sam->count;i++) {
3409 lr.in.rids[i] = sam->entries[i].idx;
3411 status = dcerpc_samr_LookupRids(p, tctx, &lr);
3412 torture_assert_ntstatus_ok(tctx, status, "LookupRids");
3418 try blasting the server with a bunch of sync requests
3420 static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, struct torture_context *tctx,
3421 struct policy_handle *handle)
3424 struct samr_EnumDomainUsers r;
3425 uint32_t resume_handle=0;
3427 #define ASYNC_COUNT 100
3428 struct rpc_request *req[ASYNC_COUNT];
3430 if (!torture_setting_bool(tctx, "dangerous", false)) {
3431 torture_skip(tctx, "samr async test disabled - enable dangerous tests to use\n");
3434 torture_comment(tctx, "Testing EnumDomainUsers_async\n");
3436 r.in.domain_handle = handle;
3437 r.in.resume_handle = &resume_handle;
3438 r.in.acct_flags = 0;
3439 r.in.max_size = (uint32_t)-1;
3440 r.out.resume_handle = &resume_handle;
3442 for (i=0;i<ASYNC_COUNT;i++) {
3443 req[i] = dcerpc_samr_EnumDomainUsers_send(p, tctx, &r);
3446 for (i=0;i<ASYNC_COUNT;i++) {
3447 status = dcerpc_ndr_request_recv(req[i]);
3448 if (!NT_STATUS_IS_OK(status)) {
3449 printf("EnumDomainUsers[%d] failed - %s\n",
3450 i, nt_errstr(status));
3455 torture_comment(tctx, "%d async requests OK\n", i);
3460 static bool test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3461 struct policy_handle *handle)
3464 struct samr_EnumDomainGroups r;
3465 uint32_t resume_handle=0;
3466 struct samr_SamArray *sam = NULL;
3467 uint32_t num_entries = 0;
3471 printf("Testing EnumDomainGroups\n");
3473 r.in.domain_handle = handle;
3474 r.in.resume_handle = &resume_handle;
3475 r.in.max_size = (uint32_t)-1;
3476 r.out.resume_handle = &resume_handle;
3477 r.out.num_entries = &num_entries;
3480 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
3481 if (!NT_STATUS_IS_OK(status)) {
3482 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
3490 for (i=0;i<sam->count;i++) {
3491 if (!test_OpenGroup(p, mem_ctx, handle, sam->entries[i].idx)) {
3499 static bool test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3500 struct policy_handle *handle)
3503 struct samr_EnumDomainAliases r;
3504 uint32_t resume_handle=0;
3505 struct samr_SamArray *sam = NULL;
3506 uint32_t num_entries = 0;
3510 printf("Testing EnumDomainAliases\n");
3512 r.in.domain_handle = handle;
3513 r.in.resume_handle = &resume_handle;
3514 r.in.max_size = (uint32_t)-1;
3516 r.out.num_entries = &num_entries;
3517 r.out.resume_handle = &resume_handle;
3519 status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
3520 if (!NT_STATUS_IS_OK(status)) {
3521 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
3529 for (i=0;i<sam->count;i++) {
3530 if (!test_OpenAlias(p, mem_ctx, handle, sam->entries[i].idx)) {
3538 static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3539 struct policy_handle *handle)
3542 struct samr_GetDisplayEnumerationIndex r;
3544 uint16_t levels[] = {1, 2, 3, 4, 5};
3545 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
3546 struct lsa_String name;
3550 for (i=0;i<ARRAY_SIZE(levels);i++) {
3551 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
3553 init_lsa_String(&name, TEST_ACCOUNT_NAME);
3555 r.in.domain_handle = handle;
3556 r.in.level = levels[i];
3560 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
3563 !NT_STATUS_IS_OK(status) &&
3564 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3565 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
3566 levels[i], nt_errstr(status));
3570 init_lsa_String(&name, "zzzzzzzz");
3572 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
3574 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3575 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
3576 levels[i], nt_errstr(status));
3584 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3585 struct policy_handle *handle)
3588 struct samr_GetDisplayEnumerationIndex2 r;
3590 uint16_t levels[] = {1, 2, 3, 4, 5};
3591 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
3592 struct lsa_String name;
3596 for (i=0;i<ARRAY_SIZE(levels);i++) {
3597 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
3599 init_lsa_String(&name, TEST_ACCOUNT_NAME);
3601 r.in.domain_handle = handle;
3602 r.in.level = levels[i];
3606 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
3608 !NT_STATUS_IS_OK(status) &&
3609 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3610 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
3611 levels[i], nt_errstr(status));
3615 init_lsa_String(&name, "zzzzzzzz");
3617 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
3618 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3619 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
3620 levels[i], nt_errstr(status));
3628 #define STRING_EQUAL_QUERY(s1, s2, user) \
3629 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
3630 /* odd, but valid */ \
3631 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
3632 printf("%s mismatch for %s: %s != %s (%s)\n", \
3633 #s1, user.string, s1.string, s2.string, __location__); \
3636 #define INT_EQUAL_QUERY(s1, s2, user) \
3638 printf("%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
3639 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
3643 static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3644 struct samr_QueryDisplayInfo *querydisplayinfo,
3645 bool *seen_testuser)
3647 struct samr_OpenUser r;
3648 struct samr_QueryUserInfo q;
3649 union samr_UserInfo *info;
3650 struct policy_handle user_handle;
3653 r.in.domain_handle = querydisplayinfo->in.domain_handle;
3654 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3655 for (i = 0; ; i++) {
3656 switch (querydisplayinfo->in.level) {
3658 if (i >= querydisplayinfo->out.info->info1.count) {
3661 r.in.rid = querydisplayinfo->out.info->info1.entries[i].rid;
3664 if (i >= querydisplayinfo->out.info->info2.count) {
3667 r.in.rid = querydisplayinfo->out.info->info2.entries[i].rid;
3673 /* Not interested in validating just the account name */
3677 r.out.user_handle = &user_handle;
3679 switch (querydisplayinfo->in.level) {
3682 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3683 if (!NT_STATUS_IS_OK(status)) {
3684 printf("OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(status));
3689 q.in.user_handle = &user_handle;
3692 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
3693 if (!NT_STATUS_IS_OK(status)) {
3694 printf("QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(status));
3698 switch (querydisplayinfo->in.level) {
3700 if (seen_testuser && strcmp(info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
3701 *seen_testuser = true;
3703 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].full_name,
3704 info->info21.full_name, info->info21.account_name);
3705 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].account_name,
3706 info->info21.account_name, info->info21.account_name);
3707 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].description,
3708 info->info21.description, info->info21.account_name);
3709 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].rid,
3710 info->info21.rid, info->info21.account_name);
3711 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].acct_flags,
3712 info->info21.acct_flags, info->info21.account_name);
3716 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].account_name,
3717 info->info21.account_name, info->info21.account_name);
3718 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].description,
3719 info->info21.description, info->info21.account_name);
3720 INT_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].rid,
3721 info->info21.rid, info->info21.account_name);
3722 INT_EQUAL_QUERY((querydisplayinfo->out.info->info2.entries[i].acct_flags & ~ACB_NORMAL),
3723 info->info21.acct_flags, info->info21.account_name);
3725 if (!(querydisplayinfo->out.info->info2.entries[i].acct_flags & ACB_NORMAL)) {
3726 printf("Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
3727 info->info21.account_name.string);
3730 if (!(info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
3731 printf("Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
3732 info->info21.account_name.string,
3733 querydisplayinfo->out.info->info2.entries[i].acct_flags,
3734 info->info21.acct_flags);
3741 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
3748 static bool test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3749 struct policy_handle *handle)
3752 struct samr_QueryDisplayInfo r;
3753 struct samr_QueryDomainInfo dom_info;
3754 union samr_DomainInfo *info = NULL;
3756 uint16_t levels[] = {1, 2, 3, 4, 5};
3758 bool seen_testuser = false;
3759 uint32_t total_size;
3760 uint32_t returned_size;
3761 union samr_DispInfo disp_info;
3764 for (i=0;i<ARRAY_SIZE(levels);i++) {
3765 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
3768 status = STATUS_MORE_ENTRIES;
3769 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
3770 r.in.domain_handle = handle;
3771 r.in.level = levels[i];
3772 r.in.max_entries = 2;
3773 r.in.buf_size = (uint32_t)-1;
3774 r.out.total_size = &total_size;
3775 r.out.returned_size = &returned_size;
3776 r.out.info = &disp_info;
3778 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
3779 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(status)) {
3780 printf("QueryDisplayInfo level %u failed - %s\n",
3781 levels[i], nt_errstr(status));
3784 switch (r.in.level) {
3786 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, &seen_testuser)) {
3789 r.in.start_idx += r.out.info->info1.count;
3792 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, NULL)) {
3795 r.in.start_idx += r.out.info->info2.count;
3798 r.in.start_idx += r.out.info->info3.count;
3801 r.in.start_idx += r.out.info->info4.count;
3804 r.in.start_idx += r.out.info->info5.count;
3808 dom_info.in.domain_handle = handle;
3809 dom_info.in.level = 2;
3810 dom_info.out.info = &info;
3812 /* Check number of users returned is correct */
3813 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &dom_info);
3814 if (!NT_STATUS_IS_OK(status)) {
3815 printf("QueryDomainInfo level %u failed - %s\n",
3816 r.in.level, nt_errstr(status));
3820 switch (r.in.level) {
3823 if (info->general.num_users < r.in.start_idx) {
3824 printf("QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
3825 r.in.start_idx, info->general.num_groups,
3826 info->general.domain_name.string);
3829 if (!seen_testuser) {
3830 struct policy_handle user_handle;
3831 if (NT_STATUS_IS_OK(test_OpenUser_byname(p, mem_ctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
3832 printf("Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
3833 info->general.domain_name.string);
3835 test_samr_handle_Close(p, mem_ctx, &user_handle);
3841 if (info->general.num_groups != r.in.start_idx) {
3842 printf("QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
3843 r.in.start_idx, info->general.num_groups,
3844 info->general.domain_name.string);
3856 static bool test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3857 struct policy_handle *handle)
3860 struct samr_QueryDisplayInfo2 r;
3862 uint16_t levels[] = {1, 2, 3, 4, 5};
3864 uint32_t total_size;
3865 uint32_t returned_size;
3866 union samr_DispInfo info;
3868 for (i=0;i<ARRAY_SIZE(levels);i++) {
3869 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
3871 r.in.domain_handle = handle;
3872 r.in.level = levels[i];
3874 r.in.max_entries = 1000;
3875 r.in.buf_size = (uint32_t)-1;
3876 r.out.total_size = &total_size;
3877 r.out.returned_size = &returned_size;
3880 status = dcerpc_samr_QueryDisplayInfo2(p, mem_ctx, &r);
3881 if (!NT_STATUS_IS_OK(status)) {
3882 printf("QueryDisplayInfo2 level %u failed - %s\n",
3883 levels[i], nt_errstr(status));
3891 static bool test_QueryDisplayInfo3(struct dcerpc_pipe *p, struct torture_context *tctx,
3892 struct policy_handle *handle)
3895 struct samr_QueryDisplayInfo3 r;
3897 uint16_t levels[] = {1, 2, 3, 4, 5};
3899 uint32_t total_size;
3900 uint32_t returned_size;
3901 union samr_DispInfo info;
3903 for (i=0;i<ARRAY_SIZE(levels);i++) {
3904 torture_comment(tctx, "Testing QueryDisplayInfo3 level %u\n", levels[i]);
3906 r.in.domain_handle = handle;
3907 r.in.level = levels[i];
3909 r.in.max_entries = 1000;
3910 r.in.buf_size = (uint32_t)-1;
3911 r.out.total_size = &total_size;
3912 r.out.returned_size = &returned_size;
3915 status = dcerpc_samr_QueryDisplayInfo3(p, tctx, &r);
3916 if (!NT_STATUS_IS_OK(status)) {
3917 printf("QueryDisplayInfo3 level %u failed - %s\n",
3918 levels[i], nt_errstr(status));
3927 static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3928 struct policy_handle *handle)
3931 struct samr_QueryDisplayInfo r;
3933 uint32_t total_size;
3934 uint32_t returned_size;
3935 union samr_DispInfo info;
3937 printf("Testing QueryDisplayInfo continuation\n");
3939 r.in.domain_handle = handle;
3942 r.in.max_entries = 1;
3943 r.in.buf_size = (uint32_t)-1;
3944 r.out.total_size = &total_size;
3945 r.out.returned_size = &returned_size;
3949 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
3950 if (NT_STATUS_IS_OK(status) && *r.out.returned_size != 0) {
3951 if (r.out.info->info1.entries[0].idx != r.in.start_idx + 1) {
3952 printf("expected idx %d but got %d\n",
3954 r.out.info->info1.entries[0].idx);
3958 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
3959 !NT_STATUS_IS_OK(status)) {
3960 printf("QueryDisplayInfo level %u failed - %s\n",
3961 r.in.level, nt_errstr(status));
3966 } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
3967 NT_STATUS_IS_OK(status)) &&
3968 *r.out.returned_size != 0);
3973 static bool test_QueryDomainInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
3974 struct policy_handle *handle)
3977 struct samr_QueryDomainInfo r;
3978 union samr_DomainInfo *info = NULL;
3979 struct samr_SetDomainInfo s;
3980 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
3981 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
3984 const char *domain_comment = talloc_asprintf(tctx,
3985 "Tortured by Samba4 RPC-SAMR: %s",
3986 timestring(tctx, time(NULL)));
3988 s.in.domain_handle = handle;
3990 s.in.info = talloc(tctx, union samr_DomainInfo);
3992 s.in.info->oem.oem_information.string = domain_comment;
3993 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
3994 if (!NT_STATUS_IS_OK(status)) {
3995 printf("SetDomainInfo level %u (set comment) failed - %s\n",
3996 r.in.level, nt_errstr(status));
4000 for (i=0;i<ARRAY_SIZE(levels);i++) {
4001 torture_comment(tctx, "Testing QueryDomainInfo level %u\n", levels[i]);
4003 r.in.domain_handle = handle;
4004 r.in.level = levels[i];
4007 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
4008 if (!NT_STATUS_IS_OK(status)) {
4009 printf("QueryDomainInfo level %u failed - %s\n",
4010 r.in.level, nt_errstr(status));
4015 switch (levels[i]) {
4017 if (strcmp(info->general.oem_information.string, domain_comment) != 0) {
4018 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
4019 levels[i], info->general.oem_information.string, domain_comment);
4022 if (!info->general.primary.string) {
4023 printf("QueryDomainInfo level %u returned no PDC name\n",
4026 } else if (info->general.role == SAMR_ROLE_DOMAIN_PDC) {
4027 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), info->general.primary.string) != 0) {
4028 printf("QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
4029 levels[i], info->general.primary.string, dcerpc_server_name(p));
4034 if (strcmp(info->oem.oem_information.string, domain_comment) != 0) {
4035 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
4036 levels[i], info->oem.oem_information.string, domain_comment);
4041 if (!info->info6.primary.string) {
4042 printf("QueryDomainInfo level %u returned no PDC name\n",
4048 if (strcmp(info->general2.general.oem_information.string, domain_comment) != 0) {
4049 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
4050 levels[i], info->general2.general.oem_information.string, domain_comment);
4056 torture_comment(tctx, "Testing SetDomainInfo level %u\n", levels[i]);
4058 s.in.domain_handle = handle;
4059 s.in.level = levels[i];
4062 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
4064 if (!NT_STATUS_IS_OK(status)) {
4065 printf("SetDomainInfo level %u failed - %s\n",
4066 r.in.level, nt_errstr(status));
4071 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
4072 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
4073 r.in.level, nt_errstr(status));
4079 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
4080 if (!NT_STATUS_IS_OK(status)) {
4081 printf("QueryDomainInfo level %u failed - %s\n",
4082 r.in.level, nt_errstr(status));
4092 static bool test_QueryDomainInfo2(struct dcerpc_pipe *p, struct torture_context *tctx,
4093 struct policy_handle *handle)
4096 struct samr_QueryDomainInfo2 r;
4097 union samr_DomainInfo *info = NULL;
4098 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
4102 for (i=0;i<ARRAY_SIZE(levels);i++) {
4103 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
4105 r.in.domain_handle = handle;
4106 r.in.level = levels[i];
4109 status = dcerpc_samr_QueryDomainInfo2(p, tctx, &r);
4110 if (!NT_STATUS_IS_OK(status)) {
4111 printf("QueryDomainInfo2 level %u failed - %s\n",
4112 r.in.level, nt_errstr(status));
4121 /* Test whether querydispinfo level 5 and enumdomgroups return the same
4122 set of group names. */
4123 static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx,
4124 struct policy_handle *handle)
4126 struct samr_EnumDomainGroups q1;
4127 struct samr_QueryDisplayInfo q2;
4129 uint32_t resume_handle=0;
4130 struct samr_SamArray *sam = NULL;
4131 uint32_t num_entries = 0;
4134 uint32_t total_size;
4135 uint32_t returned_size;
4136 union samr_DispInfo info;
4139 const char **names = NULL;
4141 torture_comment(tctx, "Testing coherency of querydispinfo vs enumdomgroups\n");
4143 q1.in.domain_handle = handle;
4144 q1.in.resume_handle = &resume_handle;
4146 q1.out.resume_handle = &resume_handle;
4147 q1.out.num_entries = &num_entries;
4150 status = STATUS_MORE_ENTRIES;
4151 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
4152 status = dcerpc_samr_EnumDomainGroups(p, tctx, &q1);
4154 if (!NT_STATUS_IS_OK(status) &&
4155 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
4158 for (i=0; i<*q1.out.num_entries; i++) {
4159 add_string_to_array(tctx,
4160 sam->entries[i].name.string,
4161 &names, &num_names);
4165 torture_assert_ntstatus_ok(tctx, status, "EnumDomainGroups");
4167 torture_assert(tctx, sam, "EnumDomainGroups failed to return sam");
4169 q2.in.domain_handle = handle;
4171 q2.in.start_idx = 0;
4172 q2.in.max_entries = 5;
4173 q2.in.buf_size = (uint32_t)-1;
4174 q2.out.total_size = &total_size;
4175 q2.out.returned_size = &returned_size;
4176 q2.out.info = &info;
4178 status = STATUS_MORE_ENTRIES;
4179 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
4180 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &q2);
4182 if (!NT_STATUS_IS_OK(status) &&
4183 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
4186 for (i=0; i<q2.out.info->info5.count; i++) {
4188 const char *name = q2.out.info->info5.entries[i].account_name.string;
4190 for (j=0; j<num_names; j++) {
4191 if (names[j] == NULL)
4193 if (strequal(names[j], name)) {
4201 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
4206 q2.in.start_idx += q2.out.info->info5.count;
4209 if (!NT_STATUS_IS_OK(status)) {
4210 printf("QueryDisplayInfo level 5 failed - %s\n",
4215 for (i=0; i<num_names; i++) {
4216 if (names[i] != NULL) {
4217 printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
4226 static bool test_DeleteDomainGroup(struct dcerpc_pipe *p, struct torture_context *tctx,
4227 struct policy_handle *group_handle)
4229 struct samr_DeleteDomainGroup d;
4232 torture_comment(tctx, "Testing DeleteDomainGroup\n");
4234 d.in.group_handle = group_handle;
4235 d.out.group_handle = group_handle;
4237 status = dcerpc_samr_DeleteDomainGroup(p, tctx, &d);
4238 torture_assert_ntstatus_ok(tctx, status, "DeleteDomainGroup");
4243 static bool test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
4244 struct policy_handle *domain_handle)
4246 struct samr_TestPrivateFunctionsDomain r;
4250 torture_comment(tctx, "Testing TestPrivateFunctionsDomain\n");
4252 r.in.domain_handle = domain_handle;
4254 status = dcerpc_samr_TestPrivateFunctionsDomain(p, tctx, &r);
4255 torture_assert_ntstatus_equal(tctx, NT_STATUS_NOT_IMPLEMENTED, status, "TestPrivateFunctionsDomain");
4260 static bool test_RidToSid(struct dcerpc_pipe *p, struct torture_context *tctx,
4261 struct dom_sid *domain_sid,
4262 struct policy_handle *domain_handle)
4264 struct samr_RidToSid r;
4267 struct dom_sid *calc_sid, *out_sid;
4268 int rids[] = { 0, 42, 512, 10200 };
4271 for (i=0;i<ARRAY_SIZE(rids);i++) {
4272 torture_comment(tctx, "Testing RidToSid\n");
4274 calc_sid = dom_sid_dup(tctx, domain_sid);
4275 r.in.domain_handle = domain_handle;
4277 r.out.sid = &out_sid;
4279 status = dcerpc_samr_RidToSid(p, tctx, &r);
4280 if (!NT_STATUS_IS_OK(status)) {
4281 printf("RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
4284 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
4286 if (!dom_sid_equal(calc_sid, out_sid)) {
4287 printf("RidToSid for %d failed - got %s, expected %s\n", rids[i],
4288 dom_sid_string(tctx, out_sid),
4289 dom_sid_string(tctx, calc_sid));
4298 static bool test_GetBootKeyInformation(struct dcerpc_pipe *p, struct torture_context *tctx,
4299 struct policy_handle *domain_handle)
4301 struct samr_GetBootKeyInformation r;
4304 uint32_t unknown = 0;
4306 torture_comment(tctx, "Testing GetBootKeyInformation\n");
4308 r.in.domain_handle = domain_handle;
4309 r.out.unknown = &unknown;
4311 status = dcerpc_samr_GetBootKeyInformation(p, tctx, &r);
4312 if (!NT_STATUS_IS_OK(status)) {
4313 /* w2k3 seems to fail this sometimes and pass it sometimes */
4314 torture_comment(tctx, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
4320 static bool test_AddGroupMember(struct dcerpc_pipe *p, struct torture_context *tctx,
4321 struct policy_handle *domain_handle,
4322 struct policy_handle *group_handle)
4325 struct samr_AddGroupMember r;
4326 struct samr_DeleteGroupMember d;
4327 struct samr_QueryGroupMember q;
4328 struct samr_RidTypeArray *rids = NULL;
4329 struct samr_SetMemberAttributesOfGroup s;
4332 status = test_LookupName(p, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
4333 torture_assert_ntstatus_ok(tctx, status, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME);
4335 r.in.group_handle = group_handle;
4337 r.in.flags = 0; /* ??? */
4339 torture_comment(tctx, "Testing AddGroupMember and DeleteGroupMember\n");
4341 d.in.group_handle = group_handle;
4344 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
4345 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_NOT_IN_GROUP, status, "DeleteGroupMember");
4347 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4348 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
4350 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4351 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_IN_GROUP, status, "AddGroupMember");
4353 if (torture_setting_bool(tctx, "samba4", false)) {
4354 torture_comment(tctx, "skipping SetMemberAttributesOfGroup test against Samba4\n");
4356 /* this one is quite strange. I am using random inputs in the
4357 hope of triggering an error that might give us a clue */
4359 s.in.group_handle = group_handle;
4360 s.in.unknown1 = random();
4361 s.in.unknown2 = random();
4363 status = dcerpc_samr_SetMemberAttributesOfGroup(p, tctx, &s);
4364 torture_assert_ntstatus_ok(tctx, status, "SetMemberAttributesOfGroup");
4367 q.in.group_handle = group_handle;
4370 status = dcerpc_samr_QueryGroupMember(p, tctx, &q);
4371 torture_assert_ntstatus_ok(tctx, status, "QueryGroupMember");
4373 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
4374 torture_assert_ntstatus_ok(tctx, status, "DeleteGroupMember");
4376 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4377 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
4383 static bool test_CreateDomainGroup(struct dcerpc_pipe *p,
4384 struct torture_context *tctx,
4385 struct policy_handle *domain_handle,
4386 struct policy_handle *group_handle,
4387 struct dom_sid *domain_sid)
4390 struct samr_CreateDomainGroup r;
4392 struct lsa_String name;
4395 init_lsa_String(&name, TEST_GROUPNAME);
4397 r.in.domain_handle = domain_handle;
4399 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4400 r.out.group_handle = group_handle;
4403 printf("Testing CreateDomainGroup(%s)\n", r.in.name->string);
4405 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
4407 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
4408 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
4409 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.name->string);
4412 printf("Server should have refused create of '%s', got %s instead\n", r.in.name->string,
4418 if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS)) {
4419 if (!test_DeleteGroup_byname(p, tctx, domain_handle, r.in.name->string)) {
4420 printf("CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
4424 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
4426 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
4427 if (!test_DeleteUser_byname(p, tctx, domain_handle, r.in.name->string)) {
4429 printf("CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
4433 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
4435 torture_assert_ntstatus_ok(tctx, status, "CreateDomainGroup");
4437 if (!test_AddGroupMember(p, tctx, domain_handle, group_handle)) {
4438 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
4442 if (!test_SetGroupInfo(p, tctx, group_handle)) {
4451 its not totally clear what this does. It seems to accept any sid you like.
4453 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p,
4454 struct torture_context *tctx,
4455 struct policy_handle *domain_handle)
4458 struct samr_RemoveMemberFromForeignDomain r;
4460 r.in.domain_handle = domain_handle;
4461 r.in.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-12-34-56-78");
4463 status = dcerpc_samr_RemoveMemberFromForeignDomain(p, tctx, &r);
4464 torture_assert_ntstatus_ok(tctx, status, "RemoveMemberFromForeignDomain");
4471 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
4472 struct policy_handle *handle);
4474 static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
4475 struct policy_handle *handle, struct dom_sid *sid,
4476 enum torture_samr_choice which_ops)
4479 struct samr_OpenDomain r;
4480 struct policy_handle domain_handle;
4481 struct policy_handle alias_handle;
4482 struct policy_handle user_handle;
4483 struct policy_handle group_handle;
4486 ZERO_STRUCT(alias_handle);
4487 ZERO_STRUCT(user_handle);
4488 ZERO_STRUCT(group_handle);
4489 ZERO_STRUCT(domain_handle);
4491 torture_comment(tctx, "Testing OpenDomain of %s\n", dom_sid_string(tctx, sid));
4493 r.in.connect_handle = handle;
4494 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4496 r.out.domain_handle = &domain_handle;
4498 status = dcerpc_samr_OpenDomain(p, tctx, &r);
4499 torture_assert_ntstatus_ok(tctx, status, "OpenDomain");
4501 /* run the domain tests with the main handle closed - this tests
4502 the servers reference counting */
4503 ret &= test_samr_handle_Close(p, tctx, handle);
4505 switch (which_ops) {
4506 case TORTURE_SAMR_USER_ATTRIBUTES:
4507 case TORTURE_SAMR_PASSWORDS:
4508 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops);
4509 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops);
4510 /* This test needs 'complex' users to validate */
4511 ret &= test_QueryDisplayInfo(p, tctx, &domain_handle);
4513 printf("Testing PASSWORDS or ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
4516 case TORTURE_SAMR_OTHER:
4517 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops);
4519 printf("Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid));
4521 ret &= test_QuerySecurity(p, tctx, &domain_handle);
4522 ret &= test_RemoveMemberFromForeignDomain(p, tctx, &domain_handle);
4523 ret &= test_CreateAlias(p, tctx, &domain_handle, &alias_handle, sid);
4524 ret &= test_CreateDomainGroup(p, tctx, &domain_handle, &group_handle, sid);
4525 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
4526 ret &= test_QueryDomainInfo2(p, tctx, &domain_handle);
4527 ret &= test_EnumDomainUsers(p, tctx, &domain_handle);
4528 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
4529 ret &= test_EnumDomainGroups(p, tctx, &domain_handle);
4530 ret &= test_EnumDomainAliases(p, tctx, &domain_handle);
4531 ret &= test_QueryDisplayInfo2(p, tctx, &domain_handle);
4532 ret &= test_QueryDisplayInfo3(p, tctx, &domain_handle);
4533 ret &= test_QueryDisplayInfo_continue(p, tctx, &domain_handle);
4535 if (torture_setting_bool(tctx, "samba4", false)) {
4536 torture_comment(tctx, "skipping GetDisplayEnumerationIndex test against Samba4\n");
4538 ret &= test_GetDisplayEnumerationIndex(p, tctx, &domain_handle);
4539 ret &= test_GetDisplayEnumerationIndex2(p, tctx, &domain_handle);
4541 ret &= test_GroupList(p, tctx, &domain_handle);
4542 ret &= test_TestPrivateFunctionsDomain(p, tctx, &domain_handle);
4543 ret &= test_RidToSid(p, tctx, sid, &domain_handle);
4544 ret &= test_GetBootKeyInformation(p, tctx, &domain_handle);
4546 torture_comment(tctx, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx, sid));
4551 if (!policy_handle_empty(&user_handle) &&
4552 !test_DeleteUser(p, tctx, &user_handle)) {
4556 if (!policy_handle_empty(&alias_handle) &&
4557 !test_DeleteAlias(p, tctx, &alias_handle)) {
4561 if (!policy_handle_empty(&group_handle) &&
4562 !test_DeleteDomainGroup(p, tctx, &group_handle)) {
4566 ret &= test_samr_handle_Close(p, tctx, &domain_handle);
4568 /* reconnect the main handle */
4569 ret &= test_Connect(p, tctx, handle);
4572 printf("Testing domain %s failed!\n", dom_sid_string(tctx, sid));
4578 static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
4579 struct policy_handle *handle, const char *domain,
4580 enum torture_samr_choice which_ops)
4583 struct samr_LookupDomain r;
4584 struct dom_sid2 *sid = NULL;
4585 struct lsa_String n1;
4586 struct lsa_String n2;
4589 torture_comment(tctx, "Testing LookupDomain(%s)\n", domain);
4591 /* check for correct error codes */
4592 r.in.connect_handle = handle;
4593 r.in.domain_name = &n2;
4597 status = dcerpc_samr_LookupDomain(p, tctx, &r);
4598 torture_assert_ntstatus_equal(tctx, NT_STATUS_INVALID_PARAMETER, status, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
4600 init_lsa_String(&n2, "xxNODOMAINxx");
4602 status = dcerpc_samr_LookupDomain(p, tctx, &r);
4603 torture_assert_ntstatus_equal(tctx, NT_STATUS_NO_SUCH_DOMAIN, status, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
4605 r.in.connect_handle = handle;
4607 init_lsa_String(&n1, domain);
4608 r.in.domain_name = &n1;
4610 status = dcerpc_samr_LookupDomain(p, tctx, &r);
4611 torture_assert_ntstatus_ok(tctx, status, "LookupDomain");
4613 if (!test_GetDomPwInfo(p, tctx, &n1)) {
4617 if (!test_OpenDomain(p, tctx, handle, *r.out.sid, which_ops)) {
4625 static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
4626 struct policy_handle *handle, enum torture_samr_choice which_ops)
4629 struct samr_EnumDomains r;
4630 uint32_t resume_handle = 0;
4631 uint32_t num_entries = 0;
4632 struct samr_SamArray *sam = NULL;
4636 r.in.connect_handle = handle;
4637 r.in.resume_handle = &resume_handle;
4638 r.in.buf_size = (uint32_t)-1;
4639 r.out.resume_handle = &resume_handle;
4640 r.out.num_entries = &num_entries;
4643 status = dcerpc_samr_EnumDomains(p, tctx, &r);
4644 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
4650 for (i=0;i<sam->count;i++) {
4651 if (!test_LookupDomain(p, tctx, handle,
4652 sam->entries[i].name.string, which_ops)) {
4657 status = dcerpc_samr_EnumDomains(p, tctx, &r);
4658 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
4664 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
4665 struct policy_handle *handle)
4668 struct samr_Connect r;
4669 struct samr_Connect2 r2;
4670 struct samr_Connect3 r3;
4671 struct samr_Connect4 r4;
4672 struct samr_Connect5 r5;
4673 union samr_ConnectInfo info;
4674 struct policy_handle h;
4675 uint32_t level_out = 0;
4676 bool ret = true, got_handle = false;
4678 torture_comment(tctx, "testing samr_Connect\n");
4680 r.in.system_name = 0;
4681 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4682 r.out.connect_handle = &h;
4684 status = dcerpc_samr_Connect(p, tctx, &r);
4685 if (!NT_STATUS_IS_OK(status)) {
4686 torture_comment(tctx, "Connect failed - %s\n", nt_errstr(status));
4693 torture_comment(tctx, "testing samr_Connect2\n");
4695 r2.in.system_name = NULL;
4696 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4697 r2.out.connect_handle = &h;
4699 status = dcerpc_samr_Connect2(p, tctx, &r2);
4700 if (!NT_STATUS_IS_OK(status)) {
4701 torture_comment(tctx, "Connect2 failed - %s\n", nt_errstr(status));
4705 test_samr_handle_Close(p, tctx, handle);
4711 torture_comment(tctx, "testing samr_Connect3\n");
4713 r3.in.system_name = NULL;
4715 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4716 r3.out.connect_handle = &h;
4718 status = dcerpc_samr_Connect3(p, tctx, &r3);
4719 if (!NT_STATUS_IS_OK(status)) {
4720 printf("Connect3 failed - %s\n", nt_errstr(status));
4724 test_samr_handle_Close(p, tctx, handle);
4730 torture_comment(tctx, "testing samr_Connect4\n");
4732 r4.in.system_name = "";
4733 r4.in.client_version = 0;
4734 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4735 r4.out.connect_handle = &h;
4737 status = dcerpc_samr_Connect4(p, tctx, &r4);
4738 if (!NT_STATUS_IS_OK(status)) {
4739 printf("Connect4 failed - %s\n", nt_errstr(status));
4743 test_samr_handle_Close(p, tctx, handle);
4749 torture_comment(tctx, "testing samr_Connect5\n");
4751 info.info1.client_version = 0;
4752 info.info1.unknown2 = 0;
4754 r5.in.system_name = "";
4755 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4757 r5.out.level_out = &level_out;
4758 r5.in.info_in = &info;
4759 r5.out.info_out = &info;
4760 r5.out.connect_handle = &h;
4762 status = dcerpc_samr_Connect5(p, tctx, &r5);
4763 if (!NT_STATUS_IS_OK(status)) {
4764 printf("Connect5 failed - %s\n", nt_errstr(status));
4768 test_samr_handle_Close(p, tctx, handle);
4778 bool torture_rpc_samr(struct torture_context *torture)
4781 struct dcerpc_pipe *p;
4783 struct policy_handle handle;
4785 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4786 if (!NT_STATUS_IS_OK(status)) {
4790 ret &= test_Connect(p, torture, &handle);
4792 ret &= test_QuerySecurity(p, torture, &handle);
4794 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_OTHER);
4796 ret &= test_SetDsrmPassword(p, torture, &handle);
4798 ret &= test_Shutdown(p, torture, &handle);
4800 ret &= test_samr_handle_Close(p, torture, &handle);
4806 bool torture_rpc_samr_users(struct torture_context *torture)
4809 struct dcerpc_pipe *p;
4811 struct policy_handle handle;
4813 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4814 if (!NT_STATUS_IS_OK(status)) {
4818 ret &= test_Connect(p, torture, &handle);
4820 ret &= test_QuerySecurity(p, torture, &handle);
4822 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_USER_ATTRIBUTES);
4824 ret &= test_SetDsrmPassword(p, torture, &handle);
4826 ret &= test_Shutdown(p, torture, &handle);
4828 ret &= test_samr_handle_Close(p, torture, &handle);
4834 bool torture_rpc_samr_passwords(struct torture_context *torture)
4837 struct dcerpc_pipe *p;
4839 struct policy_handle handle;
4841 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4842 if (!NT_STATUS_IS_OK(status)) {
4846 ret &= test_Connect(p, torture, &handle);
4848 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_PASSWORDS);
4850 ret &= test_samr_handle_Close(p, torture, &handle);