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 bool test_samr_handle_Close(struct dcerpc_pipe *p, struct torture_context *tctx,
63 struct policy_handle *handle)
69 r.out.handle = handle;
71 status = dcerpc_samr_Close(p, tctx, &r);
72 torture_assert_ntstatus_ok(tctx, status, "Close");
77 static bool test_Shutdown(struct dcerpc_pipe *p, struct torture_context *tctx,
78 struct policy_handle *handle)
81 struct samr_Shutdown r;
83 if (!torture_setting_bool(tctx, "dangerous", false)) {
84 torture_skip(tctx, "samr_Shutdown disabled - enable dangerous tests to use\n");
88 r.in.connect_handle = handle;
90 torture_comment(tctx, "testing samr_Shutdown\n");
92 status = dcerpc_samr_Shutdown(p, tctx, &r);
93 torture_assert_ntstatus_ok(tctx, status, "samr_Shutdown");
98 static bool test_SetDsrmPassword(struct dcerpc_pipe *p, struct torture_context *tctx,
99 struct policy_handle *handle)
102 struct samr_SetDsrmPassword r;
103 struct lsa_String string;
104 struct samr_Password hash;
106 if (!torture_setting_bool(tctx, "dangerous", false)) {
107 torture_skip(tctx, "samr_SetDsrmPassword disabled - enable dangerous tests to use");
110 E_md4hash("TeSTDSRM123", hash.hash);
112 init_lsa_String(&string, "Administrator");
118 torture_comment(tctx, "testing samr_SetDsrmPassword\n");
120 status = dcerpc_samr_SetDsrmPassword(p, tctx, &r);
121 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_SUPPORTED, "samr_SetDsrmPassword");
127 static bool test_QuerySecurity(struct dcerpc_pipe *p,
128 struct torture_context *tctx,
129 struct policy_handle *handle)
132 struct samr_QuerySecurity r;
133 struct samr_SetSecurity s;
135 r.in.handle = handle;
138 status = dcerpc_samr_QuerySecurity(p, tctx, &r);
139 torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
141 torture_assert(tctx, r.out.sdbuf != NULL, "sdbuf is NULL");
143 s.in.handle = handle;
145 s.in.sdbuf = r.out.sdbuf;
147 if (torture_setting_bool(tctx, "samba4", false)) {
148 torture_skip(tctx, "skipping SetSecurity test against Samba4\n");
151 status = dcerpc_samr_SetSecurity(p, tctx, &s);
152 torture_assert_ntstatus_ok(tctx, status, "SetSecurity");
154 status = dcerpc_samr_QuerySecurity(p, tctx, &r);
155 torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
161 static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
162 struct policy_handle *handle, uint32_t base_acct_flags,
163 const char *base_account_name)
166 struct samr_SetUserInfo s;
167 struct samr_SetUserInfo2 s2;
168 struct samr_QueryUserInfo q;
169 struct samr_QueryUserInfo q0;
170 union samr_UserInfo u;
172 const char *test_account_name;
174 uint32_t user_extra_flags = 0;
175 if (base_acct_flags == ACB_NORMAL) {
176 /* When created, accounts are expired by default */
177 user_extra_flags = ACB_PW_EXPIRED;
180 s.in.user_handle = handle;
183 s2.in.user_handle = handle;
186 q.in.user_handle = handle;
190 #define TESTCALL(call, r) \
191 status = dcerpc_samr_ ##call(p, tctx, &r); \
192 if (!NT_STATUS_IS_OK(status)) { \
193 torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
194 r.in.level, nt_errstr(status), __location__); \
199 #define STRING_EQUAL(s1, s2, field) \
200 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
201 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
202 #field, s2, __location__); \
207 #define INT_EQUAL(i1, i2, field) \
209 torture_comment(tctx, "Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \
210 #field, (unsigned long long)i2, (unsigned long long)i1, __location__); \
215 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
216 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
218 TESTCALL(QueryUserInfo, q) \
220 s2.in.level = lvl1; \
223 ZERO_STRUCT(u.info21); \
224 u.info21.fields_present = fpval; \
226 init_lsa_String(&u.info ## lvl1.field1, value); \
227 TESTCALL(SetUserInfo, s) \
228 TESTCALL(SetUserInfo2, s2) \
229 init_lsa_String(&u.info ## lvl1.field1, ""); \
230 TESTCALL(QueryUserInfo, q); \
232 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
234 TESTCALL(QueryUserInfo, q) \
236 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
239 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
240 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
242 TESTCALL(QueryUserInfo, q) \
244 s2.in.level = lvl1; \
247 uint8_t *bits = u.info21.logon_hours.bits; \
248 ZERO_STRUCT(u.info21); \
249 if (fpval == SAMR_FIELD_LOGON_HOURS) { \
250 u.info21.logon_hours.units_per_week = 168; \
251 u.info21.logon_hours.bits = bits; \
253 u.info21.fields_present = fpval; \
255 u.info ## lvl1.field1 = value; \
256 TESTCALL(SetUserInfo, s) \
257 TESTCALL(SetUserInfo2, s2) \
258 u.info ## lvl1.field1 = 0; \
259 TESTCALL(QueryUserInfo, q); \
261 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
263 TESTCALL(QueryUserInfo, q) \
265 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
268 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
269 TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
273 do { TESTCALL(QueryUserInfo, q0) } while (0);
275 TEST_USERINFO_STRING(2, comment, 1, comment, "xx2-1 comment", 0);
276 TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
277 TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment",
280 test_account_name = talloc_asprintf(tctx, "%sxx7-1", base_account_name);
281 TEST_USERINFO_STRING(7, account_name, 1, account_name, base_account_name, 0);
282 test_account_name = talloc_asprintf(tctx, "%sxx7-3", base_account_name);
283 TEST_USERINFO_STRING(7, account_name, 3, account_name, base_account_name, 0);
284 test_account_name = talloc_asprintf(tctx, "%sxx7-5", base_account_name);
285 TEST_USERINFO_STRING(7, account_name, 5, account_name, base_account_name, 0);
286 test_account_name = talloc_asprintf(tctx, "%sxx7-6", base_account_name);
287 TEST_USERINFO_STRING(7, account_name, 6, account_name, base_account_name, 0);
288 test_account_name = talloc_asprintf(tctx, "%sxx7-7", base_account_name);
289 TEST_USERINFO_STRING(7, account_name, 7, account_name, base_account_name, 0);
290 test_account_name = talloc_asprintf(tctx, "%sxx7-21", base_account_name);
291 TEST_USERINFO_STRING(7, account_name, 21, account_name, base_account_name, 0);
292 test_account_name = base_account_name;
293 TEST_USERINFO_STRING(21, account_name, 21, account_name, base_account_name,
294 SAMR_FIELD_ACCOUNT_NAME);
296 TEST_USERINFO_STRING(6, full_name, 1, full_name, "xx6-1 full_name", 0);
297 TEST_USERINFO_STRING(6, full_name, 3, full_name, "xx6-3 full_name", 0);
298 TEST_USERINFO_STRING(6, full_name, 5, full_name, "xx6-5 full_name", 0);
299 TEST_USERINFO_STRING(6, full_name, 6, full_name, "xx6-6 full_name", 0);
300 TEST_USERINFO_STRING(6, full_name, 8, full_name, "xx6-8 full_name", 0);
301 TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
302 TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
303 TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name",
304 SAMR_FIELD_FULL_NAME);
306 TEST_USERINFO_STRING(6, full_name, 1, full_name, "", 0);
307 TEST_USERINFO_STRING(6, full_name, 3, full_name, "", 0);
308 TEST_USERINFO_STRING(6, full_name, 5, full_name, "", 0);
309 TEST_USERINFO_STRING(6, full_name, 6, full_name, "", 0);
310 TEST_USERINFO_STRING(6, full_name, 8, full_name, "", 0);
311 TEST_USERINFO_STRING(6, full_name, 21, full_name, "", 0);
312 TEST_USERINFO_STRING(8, full_name, 21, full_name, "", 0);
313 TEST_USERINFO_STRING(21, full_name, 21, full_name, "",
314 SAMR_FIELD_FULL_NAME);
316 TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
317 TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
318 TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
319 TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script",
320 SAMR_FIELD_LOGON_SCRIPT);
322 TEST_USERINFO_STRING(12, profile_path, 3, profile_path, "xx12-3 profile_path", 0);
323 TEST_USERINFO_STRING(12, profile_path, 5, profile_path, "xx12-5 profile_path", 0);
324 TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
325 TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path",
326 SAMR_FIELD_PROFILE_PATH);
328 TEST_USERINFO_STRING(10, home_directory, 3, home_directory, "xx10-3 home_directory", 0);
329 TEST_USERINFO_STRING(10, home_directory, 5, home_directory, "xx10-5 home_directory", 0);
330 TEST_USERINFO_STRING(10, home_directory, 21, home_directory, "xx10-21 home_directory", 0);
331 TEST_USERINFO_STRING(21, home_directory, 21, home_directory, "xx21-21 home_directory",
332 SAMR_FIELD_HOME_DIRECTORY);
333 TEST_USERINFO_STRING(21, home_directory, 10, home_directory, "xx21-10 home_directory",
334 SAMR_FIELD_HOME_DIRECTORY);
336 TEST_USERINFO_STRING(10, home_drive, 3, home_drive, "xx10-3 home_drive", 0);
337 TEST_USERINFO_STRING(10, home_drive, 5, home_drive, "xx10-5 home_drive", 0);
338 TEST_USERINFO_STRING(10, home_drive, 21, home_drive, "xx10-21 home_drive", 0);
339 TEST_USERINFO_STRING(21, home_drive, 21, home_drive, "xx21-21 home_drive",
340 SAMR_FIELD_HOME_DRIVE);
341 TEST_USERINFO_STRING(21, home_drive, 10, home_drive, "xx21-10 home_drive",
342 SAMR_FIELD_HOME_DRIVE);
344 TEST_USERINFO_STRING(13, description, 1, description, "xx13-1 description", 0);
345 TEST_USERINFO_STRING(13, description, 5, description, "xx13-5 description", 0);
346 TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
347 TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description",
348 SAMR_FIELD_DESCRIPTION);
350 TEST_USERINFO_STRING(14, workstations, 3, workstations, "14workstation3", 0);
351 TEST_USERINFO_STRING(14, workstations, 5, workstations, "14workstation4", 0);
352 TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
353 TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21",
354 SAMR_FIELD_WORKSTATIONS);
355 TEST_USERINFO_STRING(21, workstations, 3, workstations, "21workstation3",
356 SAMR_FIELD_WORKSTATIONS);
357 TEST_USERINFO_STRING(21, workstations, 5, workstations, "21workstation5",
358 SAMR_FIELD_WORKSTATIONS);
359 TEST_USERINFO_STRING(21, workstations, 14, workstations, "21workstation14",
360 SAMR_FIELD_WORKSTATIONS);
362 TEST_USERINFO_STRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
363 TEST_USERINFO_STRING(21, parameters, 21, parameters, "xx21-21 parameters",
364 SAMR_FIELD_PARAMETERS);
365 TEST_USERINFO_STRING(21, parameters, 20, parameters, "xx21-20 parameters",
366 SAMR_FIELD_PARAMETERS);
368 TEST_USERINFO_INT(2, country_code, 2, country_code, __LINE__, 0);
369 TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
370 TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__,
371 SAMR_FIELD_COUNTRY_CODE);
372 TEST_USERINFO_INT(21, country_code, 2, country_code, __LINE__,
373 SAMR_FIELD_COUNTRY_CODE);
375 TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
376 TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__,
377 SAMR_FIELD_CODE_PAGE);
378 TEST_USERINFO_INT(21, code_page, 2, code_page, __LINE__,
379 SAMR_FIELD_CODE_PAGE);
381 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, __LINE__, 0);
382 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, __LINE__, 0);
383 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, __LINE__,
384 SAMR_FIELD_ACCT_EXPIRY);
385 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, __LINE__,
386 SAMR_FIELD_ACCT_EXPIRY);
387 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, __LINE__,
388 SAMR_FIELD_ACCT_EXPIRY);
390 TEST_USERINFO_INT(4, logon_hours.bits[3], 3, logon_hours.bits[3], 1, 0);
391 TEST_USERINFO_INT(4, logon_hours.bits[3], 5, logon_hours.bits[3], 2, 0);
392 TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
393 TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4,
394 SAMR_FIELD_LOGON_HOURS);
396 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
397 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
398 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
400 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
401 (base_acct_flags | ACB_DISABLED),
402 (base_acct_flags | ACB_DISABLED | user_extra_flags),
405 /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
406 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
407 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
408 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
410 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
411 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
412 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
416 /* The 'autolock' flag doesn't stick - check this */
417 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
418 (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK),
419 (base_acct_flags | ACB_DISABLED | user_extra_flags),
422 /* Removing the 'disabled' flag doesn't stick - check this */
423 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
425 (base_acct_flags | ACB_DISABLED | user_extra_flags),
428 /* The 'store plaintext' flag does stick */
429 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
430 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED),
431 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags),
433 /* The 'use DES' flag does stick */
434 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
435 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY),
436 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags),
438 /* The 'don't require kerberos pre-authentication flag does stick */
439 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
440 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH),
441 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags),
443 /* The 'no kerberos PAC required' flag sticks */
444 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
445 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD),
446 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags),
449 TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags,
450 (base_acct_flags | ACB_DISABLED),
451 (base_acct_flags | ACB_DISABLED | user_extra_flags),
452 SAMR_FIELD_ACCT_FLAGS);
455 /* these fail with win2003 - it appears you can't set the primary gid?
456 the set succeeds, but the gid isn't changed. Very weird! */
457 TEST_USERINFO_INT(9, primary_gid, 1, primary_gid, 513);
458 TEST_USERINFO_INT(9, primary_gid, 3, primary_gid, 513);
459 TEST_USERINFO_INT(9, primary_gid, 5, primary_gid, 513);
460 TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
467 generate a random password for password change tests
469 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
471 size_t len = MAX(8, min_len) + (random() % 6);
472 char *s = generate_random_str(mem_ctx, len);
473 printf("Generated password '%s'\n", s);
478 generate a random password for password change tests
480 static DATA_BLOB samr_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
483 DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
484 generate_random_buffer(password.data, password.length);
486 for (i=0; i < len; i++) {
487 if (((uint16_t *)password.data)[i] == 0) {
488 ((uint16_t *)password.data)[i] = 1;
496 generate a random password for password change tests (fixed length)
498 static char *samr_rand_pass_fixed_len(TALLOC_CTX *mem_ctx, int len)
500 char *s = generate_random_str(mem_ctx, len);
501 printf("Generated password '%s'\n", s);
505 static bool test_SetUserPass(struct dcerpc_pipe *p, struct torture_context *tctx,
506 struct policy_handle *handle, char **password)
509 struct samr_SetUserInfo s;
510 union samr_UserInfo u;
512 DATA_BLOB session_key;
514 struct samr_GetUserPwInfo pwp;
515 int policy_min_pw_len = 0;
516 pwp.in.user_handle = handle;
518 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
519 if (NT_STATUS_IS_OK(status)) {
520 policy_min_pw_len = pwp.out.info.min_password_length;
522 newpass = samr_rand_pass(tctx, policy_min_pw_len);
524 s.in.user_handle = handle;
528 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
529 /* w2k3 ignores this length */
530 u.info24.pw_len = strlen_m(newpass) * 2;
532 status = dcerpc_fetch_session_key(p, &session_key);
533 if (!NT_STATUS_IS_OK(status)) {
534 printf("SetUserInfo level %u - no session key - %s\n",
535 s.in.level, nt_errstr(status));
539 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
541 torture_comment(tctx, "Testing SetUserInfo level 24 (set password)\n");
543 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
544 if (!NT_STATUS_IS_OK(status)) {
545 printf("SetUserInfo level %u failed - %s\n",
546 s.in.level, nt_errstr(status));
556 static bool test_SetUserPass_23(struct dcerpc_pipe *p, struct torture_context *tctx,
557 struct policy_handle *handle, uint32_t fields_present,
561 struct samr_SetUserInfo s;
562 union samr_UserInfo u;
564 DATA_BLOB session_key;
566 struct samr_GetUserPwInfo pwp;
567 int policy_min_pw_len = 0;
568 pwp.in.user_handle = handle;
570 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
571 if (NT_STATUS_IS_OK(status)) {
572 policy_min_pw_len = pwp.out.info.min_password_length;
574 newpass = samr_rand_pass(tctx, policy_min_pw_len);
576 s.in.user_handle = handle;
582 u.info23.info.fields_present = fields_present;
584 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
586 status = dcerpc_fetch_session_key(p, &session_key);
587 if (!NT_STATUS_IS_OK(status)) {
588 printf("SetUserInfo level %u - no session key - %s\n",
589 s.in.level, nt_errstr(status));
593 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
595 torture_comment(tctx, "Testing SetUserInfo level 23 (set password)\n");
597 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
598 if (!NT_STATUS_IS_OK(status)) {
599 printf("SetUserInfo level %u failed - %s\n",
600 s.in.level, nt_errstr(status));
606 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
608 status = dcerpc_fetch_session_key(p, &session_key);
609 if (!NT_STATUS_IS_OK(status)) {
610 printf("SetUserInfo level %u - no session key - %s\n",
611 s.in.level, nt_errstr(status));
615 /* This should break the key nicely */
616 session_key.length--;
617 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
619 torture_comment(tctx, "Testing SetUserInfo level 23 (set password) with wrong password\n");
621 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
622 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
623 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
624 s.in.level, nt_errstr(status));
632 static bool test_SetUserPassEx(struct dcerpc_pipe *p, struct torture_context *tctx,
633 struct policy_handle *handle, bool makeshort,
637 struct samr_SetUserInfo s;
638 union samr_UserInfo u;
640 DATA_BLOB session_key;
641 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
642 uint8_t confounder[16];
644 struct MD5Context ctx;
645 struct samr_GetUserPwInfo pwp;
646 int policy_min_pw_len = 0;
647 pwp.in.user_handle = handle;
649 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
650 if (NT_STATUS_IS_OK(status)) {
651 policy_min_pw_len = pwp.out.info.min_password_length;
653 if (makeshort && policy_min_pw_len) {
654 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len - 1);
656 newpass = samr_rand_pass(tctx, policy_min_pw_len);
659 s.in.user_handle = handle;
663 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
664 u.info26.pw_len = strlen(newpass);
666 status = dcerpc_fetch_session_key(p, &session_key);
667 if (!NT_STATUS_IS_OK(status)) {
668 printf("SetUserInfo level %u - no session key - %s\n",
669 s.in.level, nt_errstr(status));
673 generate_random_buffer((uint8_t *)confounder, 16);
676 MD5Update(&ctx, confounder, 16);
677 MD5Update(&ctx, session_key.data, session_key.length);
678 MD5Final(confounded_session_key.data, &ctx);
680 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
681 memcpy(&u.info26.password.data[516], confounder, 16);
683 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex)\n");
685 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
686 if (!NT_STATUS_IS_OK(status)) {
687 printf("SetUserInfo level %u failed - %s\n",
688 s.in.level, nt_errstr(status));
694 /* This should break the key nicely */
695 confounded_session_key.data[0]++;
697 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
698 memcpy(&u.info26.password.data[516], confounder, 16);
700 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
702 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
703 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
704 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
705 s.in.level, nt_errstr(status));
714 static bool test_SetUserPass_25(struct dcerpc_pipe *p, struct torture_context *tctx,
715 struct policy_handle *handle, uint32_t fields_present,
719 struct samr_SetUserInfo s;
720 union samr_UserInfo u;
722 DATA_BLOB session_key;
723 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
724 struct MD5Context ctx;
725 uint8_t confounder[16];
727 struct samr_GetUserPwInfo pwp;
728 int policy_min_pw_len = 0;
729 pwp.in.user_handle = handle;
731 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
732 if (NT_STATUS_IS_OK(status)) {
733 policy_min_pw_len = pwp.out.info.min_password_length;
735 newpass = samr_rand_pass(tctx, policy_min_pw_len);
737 s.in.user_handle = handle;
743 u.info25.info.fields_present = fields_present;
745 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
747 status = dcerpc_fetch_session_key(p, &session_key);
748 if (!NT_STATUS_IS_OK(status)) {
749 printf("SetUserInfo level %u - no session key - %s\n",
750 s.in.level, nt_errstr(status));
754 generate_random_buffer((uint8_t *)confounder, 16);
757 MD5Update(&ctx, confounder, 16);
758 MD5Update(&ctx, session_key.data, session_key.length);
759 MD5Final(confounded_session_key.data, &ctx);
761 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
762 memcpy(&u.info25.password.data[516], confounder, 16);
764 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex)\n");
766 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
767 if (!NT_STATUS_IS_OK(status)) {
768 printf("SetUserInfo level %u failed - %s\n",
769 s.in.level, nt_errstr(status));
775 /* This should break the key nicely */
776 confounded_session_key.data[0]++;
778 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
779 memcpy(&u.info25.password.data[516], confounder, 16);
781 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
783 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
784 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
785 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
786 s.in.level, nt_errstr(status));
793 static bool test_SetAliasInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
794 struct policy_handle *handle)
797 struct samr_SetAliasInfo r;
798 struct samr_QueryAliasInfo q;
799 uint16_t levels[] = {2, 3};
803 /* Ignoring switch level 1, as that includes the number of members for the alias
804 * and setting this to a wrong value might have negative consequences
807 for (i=0;i<ARRAY_SIZE(levels);i++) {
808 torture_comment(tctx, "Testing SetAliasInfo level %u\n", levels[i]);
810 r.in.alias_handle = handle;
811 r.in.level = levels[i];
812 r.in.info = talloc(tctx, union samr_AliasInfo);
813 switch (r.in.level) {
814 case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
815 case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
816 "Test Description, should test I18N as well"); break;
817 case ALIASINFOALL: printf("ALIASINFOALL ignored\n"); break;
820 status = dcerpc_samr_SetAliasInfo(p, tctx, &r);
821 if (!NT_STATUS_IS_OK(status)) {
822 printf("SetAliasInfo level %u failed - %s\n",
823 levels[i], nt_errstr(status));
827 q.in.alias_handle = handle;
828 q.in.level = levels[i];
830 status = dcerpc_samr_QueryAliasInfo(p, tctx, &q);
831 if (!NT_STATUS_IS_OK(status)) {
832 printf("QueryAliasInfo level %u failed - %s\n",
833 levels[i], nt_errstr(status));
841 static bool test_GetGroupsForUser(struct dcerpc_pipe *p, struct torture_context *tctx,
842 struct policy_handle *user_handle)
844 struct samr_GetGroupsForUser r;
847 torture_comment(tctx, "testing GetGroupsForUser\n");
849 r.in.user_handle = user_handle;
851 status = dcerpc_samr_GetGroupsForUser(p, tctx, &r);
852 torture_assert_ntstatus_ok(tctx, status, "GetGroupsForUser");
858 static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
859 struct lsa_String *domain_name)
862 struct samr_GetDomPwInfo r;
864 r.in.domain_name = domain_name;
865 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
867 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
868 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
870 r.in.domain_name->string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
871 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
873 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
874 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
876 r.in.domain_name->string = "\\\\__NONAME__";
877 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
879 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
880 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
882 r.in.domain_name->string = "\\\\Builtin";
883 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
885 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
886 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
891 static bool test_GetUserPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
892 struct policy_handle *handle)
895 struct samr_GetUserPwInfo r;
897 torture_comment(tctx, "Testing GetUserPwInfo\n");
899 r.in.user_handle = handle;
901 status = dcerpc_samr_GetUserPwInfo(p, tctx, &r);
902 torture_assert_ntstatus_ok(tctx, status, "GetUserPwInfo");
907 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, struct torture_context *tctx,
908 struct policy_handle *domain_handle, const char *name,
912 struct samr_LookupNames n;
913 struct lsa_String sname[2];
915 init_lsa_String(&sname[0], name);
917 n.in.domain_handle = domain_handle;
920 status = dcerpc_samr_LookupNames(p, tctx, &n);
921 if (NT_STATUS_IS_OK(status)) {
922 *rid = n.out.rids.ids[0];
927 init_lsa_String(&sname[1], "xxNONAMExx");
929 status = dcerpc_samr_LookupNames(p, tctx, &n);
930 if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
931 printf("LookupNames[2] failed - %s\n", nt_errstr(status));
932 if (NT_STATUS_IS_OK(status)) {
933 return NT_STATUS_UNSUCCESSFUL;
939 status = dcerpc_samr_LookupNames(p, tctx, &n);
940 if (!NT_STATUS_IS_OK(status)) {
941 printf("LookupNames[0] failed - %s\n", nt_errstr(status));
945 init_lsa_String(&sname[0], "xxNONAMExx");
947 status = dcerpc_samr_LookupNames(p, tctx, &n);
948 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
949 printf("LookupNames[1 bad name] failed - %s\n", nt_errstr(status));
950 if (NT_STATUS_IS_OK(status)) {
951 return NT_STATUS_UNSUCCESSFUL;
956 init_lsa_String(&sname[0], "xxNONAMExx");
957 init_lsa_String(&sname[1], "xxNONAME2xx");
959 status = dcerpc_samr_LookupNames(p, tctx, &n);
960 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
961 printf("LookupNames[2 bad names] failed - %s\n", nt_errstr(status));
962 if (NT_STATUS_IS_OK(status)) {
963 return NT_STATUS_UNSUCCESSFUL;
971 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
972 struct policy_handle *domain_handle,
973 const char *name, struct policy_handle *user_handle)
976 struct samr_OpenUser r;
979 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
980 if (!NT_STATUS_IS_OK(status)) {
984 r.in.domain_handle = domain_handle;
985 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
987 r.out.user_handle = user_handle;
988 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
989 if (!NT_STATUS_IS_OK(status)) {
990 printf("OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(status));
997 static bool test_ChangePasswordNT3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
998 struct policy_handle *handle)
1001 struct samr_ChangePasswordUser r;
1003 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1004 struct policy_handle user_handle;
1005 char *oldpass = "test";
1006 char *newpass = "test2";
1007 uint8_t old_nt_hash[16], new_nt_hash[16];
1008 uint8_t old_lm_hash[16], new_lm_hash[16];
1010 status = test_OpenUser_byname(p, mem_ctx, handle, "testuser", &user_handle);
1011 if (!NT_STATUS_IS_OK(status)) {
1015 printf("Testing ChangePasswordUser for user 'testuser'\n");
1017 printf("old password: %s\n", oldpass);
1018 printf("new password: %s\n", newpass);
1020 E_md4hash(oldpass, old_nt_hash);
1021 E_md4hash(newpass, new_nt_hash);
1022 E_deshash(oldpass, old_lm_hash);
1023 E_deshash(newpass, new_lm_hash);
1025 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1026 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1027 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1028 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1029 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1030 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1032 r.in.handle = &user_handle;
1033 r.in.lm_present = 1;
1034 r.in.old_lm_crypted = &hash1;
1035 r.in.new_lm_crypted = &hash2;
1036 r.in.nt_present = 1;
1037 r.in.old_nt_crypted = &hash3;
1038 r.in.new_nt_crypted = &hash4;
1039 r.in.cross1_present = 1;
1040 r.in.nt_cross = &hash5;
1041 r.in.cross2_present = 1;
1042 r.in.lm_cross = &hash6;
1044 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1045 if (!NT_STATUS_IS_OK(status)) {
1046 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1050 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1058 static bool test_ChangePasswordUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1059 const char *acct_name,
1060 struct policy_handle *handle, char **password)
1063 struct samr_ChangePasswordUser r;
1065 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1066 struct policy_handle user_handle;
1068 uint8_t old_nt_hash[16], new_nt_hash[16];
1069 uint8_t old_lm_hash[16], new_lm_hash[16];
1070 bool changed = true;
1073 struct samr_GetUserPwInfo pwp;
1074 int policy_min_pw_len = 0;
1076 status = test_OpenUser_byname(p, tctx, handle, acct_name, &user_handle);
1077 if (!NT_STATUS_IS_OK(status)) {
1080 pwp.in.user_handle = &user_handle;
1082 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1083 if (NT_STATUS_IS_OK(status)) {
1084 policy_min_pw_len = pwp.out.info.min_password_length;
1086 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1088 torture_comment(tctx, "Testing ChangePasswordUser\n");
1090 torture_assert(tctx, *password != NULL,
1091 "Failing ChangePasswordUser as old password was NULL. Previous test failed?");
1093 oldpass = *password;
1095 E_md4hash(oldpass, old_nt_hash);
1096 E_md4hash(newpass, new_nt_hash);
1097 E_deshash(oldpass, old_lm_hash);
1098 E_deshash(newpass, new_lm_hash);
1100 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1101 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1102 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1103 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1104 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1105 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1107 r.in.user_handle = &user_handle;
1108 r.in.lm_present = 1;
1109 /* Break the LM hash */
1111 r.in.old_lm_crypted = &hash1;
1112 r.in.new_lm_crypted = &hash2;
1113 r.in.nt_present = 1;
1114 r.in.old_nt_crypted = &hash3;
1115 r.in.new_nt_crypted = &hash4;
1116 r.in.cross1_present = 1;
1117 r.in.nt_cross = &hash5;
1118 r.in.cross2_present = 1;
1119 r.in.lm_cross = &hash6;
1121 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1122 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1123 "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash");
1125 /* Unbreak the LM hash */
1128 r.in.user_handle = &user_handle;
1129 r.in.lm_present = 1;
1130 r.in.old_lm_crypted = &hash1;
1131 r.in.new_lm_crypted = &hash2;
1132 /* Break the NT hash */
1134 r.in.nt_present = 1;
1135 r.in.old_nt_crypted = &hash3;
1136 r.in.new_nt_crypted = &hash4;
1137 r.in.cross1_present = 1;
1138 r.in.nt_cross = &hash5;
1139 r.in.cross2_present = 1;
1140 r.in.lm_cross = &hash6;
1142 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1143 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1144 "expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash");
1146 /* Unbreak the NT hash */
1149 r.in.user_handle = &user_handle;
1150 r.in.lm_present = 1;
1151 r.in.old_lm_crypted = &hash1;
1152 r.in.new_lm_crypted = &hash2;
1153 r.in.nt_present = 1;
1154 r.in.old_nt_crypted = &hash3;
1155 r.in.new_nt_crypted = &hash4;
1156 r.in.cross1_present = 1;
1157 r.in.nt_cross = &hash5;
1158 r.in.cross2_present = 1;
1159 /* Break the LM cross */
1161 r.in.lm_cross = &hash6;
1163 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1164 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1165 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status));
1169 /* Unbreak the LM cross */
1172 r.in.user_handle = &user_handle;
1173 r.in.lm_present = 1;
1174 r.in.old_lm_crypted = &hash1;
1175 r.in.new_lm_crypted = &hash2;
1176 r.in.nt_present = 1;
1177 r.in.old_nt_crypted = &hash3;
1178 r.in.new_nt_crypted = &hash4;
1179 r.in.cross1_present = 1;
1180 /* Break the NT cross */
1182 r.in.nt_cross = &hash5;
1183 r.in.cross2_present = 1;
1184 r.in.lm_cross = &hash6;
1186 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1187 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1188 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status));
1192 /* Unbreak the NT cross */
1196 /* Reset the hashes to not broken values */
1197 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1198 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1199 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1200 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1201 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1202 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1204 r.in.user_handle = &user_handle;
1205 r.in.lm_present = 1;
1206 r.in.old_lm_crypted = &hash1;
1207 r.in.new_lm_crypted = &hash2;
1208 r.in.nt_present = 1;
1209 r.in.old_nt_crypted = &hash3;
1210 r.in.new_nt_crypted = &hash4;
1211 r.in.cross1_present = 1;
1212 r.in.nt_cross = &hash5;
1213 r.in.cross2_present = 0;
1214 r.in.lm_cross = NULL;
1216 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1217 if (NT_STATUS_IS_OK(status)) {
1219 *password = newpass;
1220 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1221 printf("ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(status));
1226 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1228 E_md4hash(oldpass, old_nt_hash);
1229 E_md4hash(newpass, new_nt_hash);
1230 E_deshash(oldpass, old_lm_hash);
1231 E_deshash(newpass, new_lm_hash);
1234 /* Reset the hashes to not broken values */
1235 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1236 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1237 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1238 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1239 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1240 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
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 = 0;
1250 r.in.nt_cross = NULL;
1251 r.in.cross2_present = 1;
1252 r.in.lm_cross = &hash6;
1254 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1255 if (NT_STATUS_IS_OK(status)) {
1257 *password = newpass;
1258 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1259 printf("ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status));
1264 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1266 E_md4hash(oldpass, old_nt_hash);
1267 E_md4hash(newpass, new_nt_hash);
1268 E_deshash(oldpass, old_lm_hash);
1269 E_deshash(newpass, new_lm_hash);
1272 /* Reset the hashes to not broken values */
1273 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1274 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1275 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1276 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1277 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1278 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1280 r.in.user_handle = &user_handle;
1281 r.in.lm_present = 1;
1282 r.in.old_lm_crypted = &hash1;
1283 r.in.new_lm_crypted = &hash2;
1284 r.in.nt_present = 1;
1285 r.in.old_nt_crypted = &hash3;
1286 r.in.new_nt_crypted = &hash4;
1287 r.in.cross1_present = 1;
1288 r.in.nt_cross = &hash5;
1289 r.in.cross2_present = 1;
1290 r.in.lm_cross = &hash6;
1292 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1293 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1294 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1295 } else if (!NT_STATUS_IS_OK(status)) {
1296 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1300 *password = newpass;
1303 r.in.user_handle = &user_handle;
1304 r.in.lm_present = 1;
1305 r.in.old_lm_crypted = &hash1;
1306 r.in.new_lm_crypted = &hash2;
1307 r.in.nt_present = 1;
1308 r.in.old_nt_crypted = &hash3;
1309 r.in.new_nt_crypted = &hash4;
1310 r.in.cross1_present = 1;
1311 r.in.nt_cross = &hash5;
1312 r.in.cross2_present = 1;
1313 r.in.lm_cross = &hash6;
1316 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1317 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1318 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1319 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1320 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status));
1326 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
1334 static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
1335 const char *acct_name,
1336 struct policy_handle *handle, char **password)
1339 struct samr_OemChangePasswordUser2 r;
1341 struct samr_Password lm_verifier;
1342 struct samr_CryptPassword lm_pass;
1343 struct lsa_AsciiString server, account, account_bad;
1346 uint8_t old_lm_hash[16], new_lm_hash[16];
1348 struct samr_GetDomPwInfo dom_pw_info;
1349 int policy_min_pw_len = 0;
1351 struct lsa_String domain_name;
1353 domain_name.string = "";
1354 dom_pw_info.in.domain_name = &domain_name;
1356 torture_comment(tctx, "Testing OemChangePasswordUser2\n");
1358 torture_assert(tctx, *password != NULL,
1359 "Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?");
1361 oldpass = *password;
1363 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
1364 if (NT_STATUS_IS_OK(status)) {
1365 policy_min_pw_len = dom_pw_info.out.info.min_password_length;
1368 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1370 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1371 account.string = acct_name;
1373 E_deshash(oldpass, old_lm_hash);
1374 E_deshash(newpass, new_lm_hash);
1376 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1377 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1378 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1380 r.in.server = &server;
1381 r.in.account = &account;
1382 r.in.password = &lm_pass;
1383 r.in.hash = &lm_verifier;
1385 /* Break the verification */
1386 lm_verifier.hash[0]++;
1388 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1390 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1391 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1392 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1397 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1398 /* Break the old password */
1400 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1401 /* unbreak it for the next operation */
1403 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1405 r.in.server = &server;
1406 r.in.account = &account;
1407 r.in.password = &lm_pass;
1408 r.in.hash = &lm_verifier;
1410 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1412 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1413 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1414 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1419 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1420 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1422 r.in.server = &server;
1423 r.in.account = &account;
1424 r.in.password = &lm_pass;
1427 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1429 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1430 && !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1431 printf("ChangePasswordUser3 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
1436 /* This shouldn't be a valid name */
1437 account_bad.string = TEST_ACCOUNT_NAME "XX";
1438 r.in.account = &account_bad;
1440 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1442 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1443 printf("ChangePasswordUser3 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
1448 /* This shouldn't be a valid name */
1449 account_bad.string = TEST_ACCOUNT_NAME "XX";
1450 r.in.account = &account_bad;
1451 r.in.password = &lm_pass;
1452 r.in.hash = &lm_verifier;
1454 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1456 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1457 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1462 /* This shouldn't be a valid name */
1463 account_bad.string = TEST_ACCOUNT_NAME "XX";
1464 r.in.account = &account_bad;
1465 r.in.password = NULL;
1466 r.in.hash = &lm_verifier;
1468 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1470 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1471 printf("ChangePasswordUser3 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
1476 E_deshash(oldpass, old_lm_hash);
1477 E_deshash(newpass, new_lm_hash);
1479 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1480 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1481 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1483 r.in.server = &server;
1484 r.in.account = &account;
1485 r.in.password = &lm_pass;
1486 r.in.hash = &lm_verifier;
1488 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1489 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1490 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1491 } else if (!NT_STATUS_IS_OK(status)) {
1492 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
1495 *password = newpass;
1502 static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
1503 const char *acct_name,
1505 char *newpass, bool allow_password_restriction)
1508 struct samr_ChangePasswordUser2 r;
1510 struct lsa_String server, account;
1511 struct samr_CryptPassword nt_pass, lm_pass;
1512 struct samr_Password nt_verifier, lm_verifier;
1514 uint8_t old_nt_hash[16], new_nt_hash[16];
1515 uint8_t old_lm_hash[16], new_lm_hash[16];
1517 struct samr_GetDomPwInfo dom_pw_info;
1519 struct lsa_String domain_name;
1521 domain_name.string = "";
1522 dom_pw_info.in.domain_name = &domain_name;
1524 torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name);
1526 torture_assert(tctx, *password != NULL,
1527 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
1528 oldpass = *password;
1531 int policy_min_pw_len = 0;
1532 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
1533 if (NT_STATUS_IS_OK(status)) {
1534 policy_min_pw_len = dom_pw_info.out.info.min_password_length;
1537 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1540 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1541 init_lsa_String(&account, acct_name);
1543 E_md4hash(oldpass, old_nt_hash);
1544 E_md4hash(newpass, new_nt_hash);
1546 E_deshash(oldpass, old_lm_hash);
1547 E_deshash(newpass, new_lm_hash);
1549 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
1550 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1551 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1553 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1554 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1555 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1557 r.in.server = &server;
1558 r.in.account = &account;
1559 r.in.nt_password = &nt_pass;
1560 r.in.nt_verifier = &nt_verifier;
1562 r.in.lm_password = &lm_pass;
1563 r.in.lm_verifier = &lm_verifier;
1565 status = dcerpc_samr_ChangePasswordUser2(p, tctx, &r);
1566 if (allow_password_restriction && NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1567 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1568 } else if (!NT_STATUS_IS_OK(status)) {
1569 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
1572 *password = newpass;
1579 bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tctx,
1580 const char *account_string,
1581 int policy_min_pw_len,
1583 const char *newpass,
1584 NTTIME last_password_change,
1585 bool handle_reject_reason)
1588 struct samr_ChangePasswordUser3 r;
1590 struct lsa_String server, account, account_bad;
1591 struct samr_CryptPassword nt_pass, lm_pass;
1592 struct samr_Password nt_verifier, lm_verifier;
1594 uint8_t old_nt_hash[16], new_nt_hash[16];
1595 uint8_t old_lm_hash[16], new_lm_hash[16];
1598 torture_comment(tctx, "Testing ChangePasswordUser3\n");
1600 if (newpass == NULL) {
1602 if (policy_min_pw_len == 0) {
1603 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1605 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len);
1607 } while (check_password_quality(newpass) == false);
1609 torture_comment(tctx, "Using password '%s'\n", newpass);
1612 torture_assert(tctx, *password != NULL,
1613 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
1615 oldpass = *password;
1616 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1617 init_lsa_String(&account, account_string);
1619 E_md4hash(oldpass, old_nt_hash);
1620 E_md4hash(newpass, new_nt_hash);
1622 E_deshash(oldpass, old_lm_hash);
1623 E_deshash(newpass, new_lm_hash);
1625 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1626 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1627 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1629 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1630 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1631 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1633 /* Break the verification */
1634 nt_verifier.hash[0]++;
1636 r.in.server = &server;
1637 r.in.account = &account;
1638 r.in.nt_password = &nt_pass;
1639 r.in.nt_verifier = &nt_verifier;
1641 r.in.lm_password = &lm_pass;
1642 r.in.lm_verifier = &lm_verifier;
1643 r.in.password3 = NULL;
1645 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1646 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1647 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1648 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1653 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1654 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1655 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1657 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1658 /* Break the NT hash */
1660 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1661 /* Unbreak it again */
1663 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1665 r.in.server = &server;
1666 r.in.account = &account;
1667 r.in.nt_password = &nt_pass;
1668 r.in.nt_verifier = &nt_verifier;
1670 r.in.lm_password = &lm_pass;
1671 r.in.lm_verifier = &lm_verifier;
1672 r.in.password3 = NULL;
1674 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1675 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1676 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1677 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1682 /* This shouldn't be a valid name */
1683 init_lsa_String(&account_bad, talloc_asprintf(tctx, "%sXX", account_string));
1685 r.in.account = &account_bad;
1686 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1687 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1688 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
1693 E_md4hash(oldpass, old_nt_hash);
1694 E_md4hash(newpass, new_nt_hash);
1696 E_deshash(oldpass, old_lm_hash);
1697 E_deshash(newpass, new_lm_hash);
1699 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1700 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1701 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1703 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1704 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1705 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1707 r.in.server = &server;
1708 r.in.account = &account;
1709 r.in.nt_password = &nt_pass;
1710 r.in.nt_verifier = &nt_verifier;
1712 r.in.lm_password = &lm_pass;
1713 r.in.lm_verifier = &lm_verifier;
1714 r.in.password3 = NULL;
1716 unix_to_nt_time(&t, time(NULL));
1718 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1720 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1723 && handle_reject_reason
1724 && (!null_nttime(last_password_change) || !r.out.dominfo->min_password_age)) {
1725 if (r.out.dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
1727 if (r.out.reject && (r.out.reject->reason != SAMR_REJECT_OTHER)) {
1728 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1729 SAMR_REJECT_OTHER, r.out.reject->reason);
1734 /* We tested the order of precendence which is as follows:
1743 if ((r.out.dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
1744 (last_password_change + r.out.dominfo->min_password_age > t)) {
1746 if (r.out.reject->reason != SAMR_REJECT_OTHER) {
1747 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1748 SAMR_REJECT_OTHER, r.out.reject->reason);
1752 } else if ((r.out.dominfo->min_password_length > 0) &&
1753 (strlen(newpass) < r.out.dominfo->min_password_length)) {
1755 if (r.out.reject->reason != SAMR_REJECT_TOO_SHORT) {
1756 printf("expected SAMR_REJECT_TOO_SHORT (%d), got %d\n",
1757 SAMR_REJECT_TOO_SHORT, r.out.reject->reason);
1761 } else if ((r.out.dominfo->password_history_length > 0) &&
1762 strequal(oldpass, newpass)) {
1764 if (r.out.reject->reason != SAMR_REJECT_IN_HISTORY) {
1765 printf("expected SAMR_REJECT_IN_HISTORY (%d), got %d\n",
1766 SAMR_REJECT_IN_HISTORY, r.out.reject->reason);
1769 } else if (r.out.dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
1771 if (r.out.reject->reason != SAMR_REJECT_COMPLEXITY) {
1772 printf("expected SAMR_REJECT_COMPLEXITY (%d), got %d\n",
1773 SAMR_REJECT_COMPLEXITY, r.out.reject->reason);
1779 if (r.out.reject->reason == SAMR_REJECT_TOO_SHORT) {
1780 /* retry with adjusted size */
1781 return test_ChangePasswordUser3(p, tctx, account_string,
1782 r.out.dominfo->min_password_length,
1783 password, NULL, 0, false);
1787 } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1788 if (r.out.reject && r.out.reject->reason != SAMR_REJECT_OTHER) {
1789 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1790 SAMR_REJECT_OTHER, r.out.reject->reason);
1793 /* Perhaps the server has a 'min password age' set? */
1796 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3");
1797 *password = talloc_strdup(tctx, newpass);
1803 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_context *tctx,
1804 const char *account_string,
1805 struct policy_handle *handle,
1809 struct samr_ChangePasswordUser3 r;
1810 struct samr_SetUserInfo s;
1811 union samr_UserInfo u;
1812 DATA_BLOB session_key;
1813 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
1814 uint8_t confounder[16];
1815 struct MD5Context ctx;
1818 struct lsa_String server, account;
1819 struct samr_CryptPassword nt_pass;
1820 struct samr_Password nt_verifier;
1821 DATA_BLOB new_random_pass;
1824 uint8_t old_nt_hash[16], new_nt_hash[16];
1827 new_random_pass = samr_very_rand_pass(tctx, 128);
1829 torture_assert(tctx, *password != NULL,
1830 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
1832 oldpass = *password;
1833 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1834 init_lsa_String(&account, account_string);
1836 s.in.user_handle = handle;
1842 u.info25.info.fields_present = SAMR_FIELD_PASSWORD;
1844 set_pw_in_buffer(u.info25.password.data, &new_random_pass);
1846 status = dcerpc_fetch_session_key(p, &session_key);
1847 if (!NT_STATUS_IS_OK(status)) {
1848 printf("SetUserInfo level %u - no session key - %s\n",
1849 s.in.level, nt_errstr(status));
1853 generate_random_buffer((uint8_t *)confounder, 16);
1856 MD5Update(&ctx, confounder, 16);
1857 MD5Update(&ctx, session_key.data, session_key.length);
1858 MD5Final(confounded_session_key.data, &ctx);
1860 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
1861 memcpy(&u.info25.password.data[516], confounder, 16);
1863 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
1865 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1866 if (!NT_STATUS_IS_OK(status)) {
1867 printf("SetUserInfo level %u failed - %s\n",
1868 s.in.level, nt_errstr(status));
1872 torture_comment(tctx, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
1874 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
1876 new_random_pass = samr_very_rand_pass(tctx, 128);
1878 mdfour(new_nt_hash, new_random_pass.data, new_random_pass.length);
1880 set_pw_in_buffer(nt_pass.data, &new_random_pass);
1881 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1882 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1884 r.in.server = &server;
1885 r.in.account = &account;
1886 r.in.nt_password = &nt_pass;
1887 r.in.nt_verifier = &nt_verifier;
1889 r.in.lm_password = NULL;
1890 r.in.lm_verifier = NULL;
1891 r.in.password3 = NULL;
1893 unix_to_nt_time(&t, time(NULL));
1895 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1897 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1898 if (r.out.reject && r.out.reject->reason != SAMR_REJECT_OTHER) {
1899 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1900 SAMR_REJECT_OTHER, r.out.reject->reason);
1903 /* Perhaps the server has a 'min password age' set? */
1905 } else if (!NT_STATUS_IS_OK(status)) {
1906 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
1910 newpass = samr_rand_pass(tctx, 128);
1912 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
1914 E_md4hash(newpass, new_nt_hash);
1916 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1917 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1918 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1920 r.in.server = &server;
1921 r.in.account = &account;
1922 r.in.nt_password = &nt_pass;
1923 r.in.nt_verifier = &nt_verifier;
1925 r.in.lm_password = NULL;
1926 r.in.lm_verifier = NULL;
1927 r.in.password3 = NULL;
1929 unix_to_nt_time(&t, time(NULL));
1931 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1933 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1934 if (r.out.reject && r.out.reject->reason != SAMR_REJECT_OTHER) {
1935 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1936 SAMR_REJECT_OTHER, r.out.reject->reason);
1939 /* Perhaps the server has a 'min password age' set? */
1942 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3 (on second random password)");
1943 *password = talloc_strdup(tctx, newpass);
1950 static bool test_GetMembersInAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
1951 struct policy_handle *alias_handle)
1953 struct samr_GetMembersInAlias r;
1954 struct lsa_SidArray sids;
1957 torture_comment(tctx, "Testing GetMembersInAlias\n");
1959 r.in.alias_handle = alias_handle;
1962 status = dcerpc_samr_GetMembersInAlias(p, tctx, &r);
1963 torture_assert_ntstatus_ok(tctx, status, "GetMembersInAlias");
1968 static bool test_AddMemberToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
1969 struct policy_handle *alias_handle,
1970 const struct dom_sid *domain_sid)
1972 struct samr_AddAliasMember r;
1973 struct samr_DeleteAliasMember d;
1975 struct dom_sid *sid;
1977 sid = dom_sid_add_rid(tctx, domain_sid, 512);
1979 torture_comment(tctx, "testing AddAliasMember\n");
1980 r.in.alias_handle = alias_handle;
1983 status = dcerpc_samr_AddAliasMember(p, tctx, &r);
1984 torture_assert_ntstatus_ok(tctx, status, "AddAliasMember");
1986 d.in.alias_handle = alias_handle;
1989 status = dcerpc_samr_DeleteAliasMember(p, tctx, &d);
1990 torture_assert_ntstatus_ok(tctx, status, "DelAliasMember");
1995 static bool test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
1996 struct policy_handle *alias_handle)
1998 struct samr_AddMultipleMembersToAlias a;
1999 struct samr_RemoveMultipleMembersFromAlias r;
2001 struct lsa_SidArray sids;
2003 torture_comment(tctx, "testing AddMultipleMembersToAlias\n");
2004 a.in.alias_handle = alias_handle;
2008 sids.sids = talloc_array(tctx, struct lsa_SidPtr, 3);
2010 sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2011 sids.sids[1].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-2");
2012 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-3");
2014 status = dcerpc_samr_AddMultipleMembersToAlias(p, tctx, &a);
2015 torture_assert_ntstatus_ok(tctx, status, "AddMultipleMembersToAlias");
2018 torture_comment(tctx, "testing RemoveMultipleMembersFromAlias\n");
2019 r.in.alias_handle = alias_handle;
2022 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2023 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2025 /* strange! removing twice doesn't give any error */
2026 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2027 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2029 /* but removing an alias that isn't there does */
2030 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-4");
2032 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2033 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, "RemoveMultipleMembersFromAlias");
2038 static bool test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2039 struct policy_handle *user_handle)
2041 struct samr_TestPrivateFunctionsUser r;
2044 torture_comment(tctx, "Testing TestPrivateFunctionsUser\n");
2046 r.in.user_handle = user_handle;
2048 status = dcerpc_samr_TestPrivateFunctionsUser(p, tctx, &r);
2049 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsUser");
2055 static bool test_user_ops(struct dcerpc_pipe *p,
2056 struct torture_context *tctx,
2057 struct policy_handle *user_handle,
2058 struct policy_handle *domain_handle,
2059 uint32_t base_acct_flags,
2060 const char *base_acct_name, enum torture_samr_choice which_ops)
2062 char *password = NULL;
2063 struct samr_QueryUserInfo q;
2069 const uint32_t password_fields[] = {
2070 SAMR_FIELD_PASSWORD,
2071 SAMR_FIELD_PASSWORD2,
2072 SAMR_FIELD_PASSWORD | SAMR_FIELD_PASSWORD2,
2076 status = test_LookupName(p, tctx, domain_handle, base_acct_name, &rid);
2077 if (!NT_STATUS_IS_OK(status)) {
2081 switch (which_ops) {
2082 case TORTURE_SAMR_USER_ATTRIBUTES:
2083 if (!test_QuerySecurity(p, tctx, user_handle)) {
2087 if (!test_QueryUserInfo(p, tctx, user_handle)) {
2091 if (!test_QueryUserInfo2(p, tctx, user_handle)) {
2095 if (!test_SetUserInfo(p, tctx, user_handle, base_acct_flags,
2100 if (!test_GetUserPwInfo(p, tctx, user_handle)) {
2104 if (!test_TestPrivateFunctionsUser(p, tctx, user_handle)) {
2108 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
2112 case TORTURE_SAMR_PASSWORDS:
2113 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
2114 char simple_pass[9];
2115 char *v = generate_random_str(tctx, 1);
2117 ZERO_STRUCT(simple_pass);
2118 memset(simple_pass, *v, sizeof(simple_pass) - 1);
2120 printf("Testing machine account password policy rules\n");
2122 /* Workstation trust accounts don't seem to need to honour password quality policy */
2123 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
2127 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
2131 /* reset again, to allow another 'user' password change */
2132 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
2136 /* Try a 'short' password */
2137 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
2141 /* Try a compleatly random password */
2142 if (!test_ChangePasswordRandomBytes(p, tctx, base_acct_name, user_handle, &password)) {
2147 for (i = 0; password_fields[i]; i++) {
2148 if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
2152 /* check it was set right */
2153 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
2158 for (i = 0; password_fields[i]; i++) {
2159 if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
2163 /* check it was set right */
2164 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
2169 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
2173 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
2177 q.in.user_handle = user_handle;
2180 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
2181 if (!NT_STATUS_IS_OK(status)) {
2182 printf("QueryUserInfo level %u failed - %s\n",
2183 q.in.level, nt_errstr(status));
2186 uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
2187 if ((q.out.info->info5.acct_flags) != expected_flags) {
2188 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2189 q.out.info->info5.acct_flags,
2193 if (q.out.info->info5.rid != rid) {
2194 printf("QuerUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
2195 q.out.info->info5.rid, rid);
2201 case TORTURE_SAMR_OTHER:
2202 /* We just need the account to exist */
2208 static bool test_alias_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
2209 struct policy_handle *alias_handle,
2210 const struct dom_sid *domain_sid)
2214 if (!test_QuerySecurity(p, tctx, alias_handle)) {
2218 if (!test_QueryAliasInfo(p, tctx, alias_handle)) {
2222 if (!test_SetAliasInfo(p, tctx, alias_handle)) {
2226 if (!test_AddMemberToAlias(p, tctx, alias_handle, domain_sid)) {
2230 if (torture_setting_bool(tctx, "samba4", false)) {
2231 printf("skipping MultipleMembers Alias tests against Samba4\n");
2235 if (!test_AddMultipleMembersToAlias(p, tctx, alias_handle)) {
2243 static bool test_DeleteUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2244 struct policy_handle *user_handle)
2246 struct samr_DeleteUser d;
2248 torture_comment(tctx, "Testing DeleteUser\n");
2250 d.in.user_handle = user_handle;
2251 d.out.user_handle = user_handle;
2253 status = dcerpc_samr_DeleteUser(p, tctx, &d);
2254 torture_assert_ntstatus_ok(tctx, status, "DeleteUser");
2259 bool test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2260 struct policy_handle *handle, const char *name)
2263 struct samr_DeleteUser d;
2264 struct policy_handle user_handle;
2267 status = test_LookupName(p, mem_ctx, handle, name, &rid);
2268 if (!NT_STATUS_IS_OK(status)) {
2272 status = test_OpenUser_byname(p, mem_ctx, handle, name, &user_handle);
2273 if (!NT_STATUS_IS_OK(status)) {
2277 d.in.user_handle = &user_handle;
2278 d.out.user_handle = &user_handle;
2279 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
2280 if (!NT_STATUS_IS_OK(status)) {
2287 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
2292 static bool test_DeleteGroup_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2293 struct policy_handle *handle, const char *name)
2296 struct samr_OpenGroup r;
2297 struct samr_DeleteDomainGroup d;
2298 struct policy_handle group_handle;
2301 status = test_LookupName(p, mem_ctx, handle, name, &rid);
2302 if (!NT_STATUS_IS_OK(status)) {
2306 r.in.domain_handle = handle;
2307 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2309 r.out.group_handle = &group_handle;
2310 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
2311 if (!NT_STATUS_IS_OK(status)) {
2315 d.in.group_handle = &group_handle;
2316 d.out.group_handle = &group_handle;
2317 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
2318 if (!NT_STATUS_IS_OK(status)) {
2325 printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
2330 static bool test_DeleteAlias_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2331 struct policy_handle *domain_handle, const char *name)
2334 struct samr_OpenAlias r;
2335 struct samr_DeleteDomAlias d;
2336 struct policy_handle alias_handle;
2339 printf("testing DeleteAlias_byname\n");
2341 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
2342 if (!NT_STATUS_IS_OK(status)) {
2346 r.in.domain_handle = domain_handle;
2347 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2349 r.out.alias_handle = &alias_handle;
2350 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
2351 if (!NT_STATUS_IS_OK(status)) {
2355 d.in.alias_handle = &alias_handle;
2356 d.out.alias_handle = &alias_handle;
2357 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
2358 if (!NT_STATUS_IS_OK(status)) {
2365 printf("DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
2369 static bool test_DeleteAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2370 struct policy_handle *alias_handle)
2372 struct samr_DeleteDomAlias d;
2375 printf("Testing DeleteAlias\n");
2377 d.in.alias_handle = alias_handle;
2378 d.out.alias_handle = alias_handle;
2380 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
2381 if (!NT_STATUS_IS_OK(status)) {
2382 printf("DeleteAlias failed - %s\n", nt_errstr(status));
2389 static bool test_CreateAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2390 struct policy_handle *domain_handle,
2391 struct policy_handle *alias_handle,
2392 const struct dom_sid *domain_sid)
2395 struct samr_CreateDomAlias r;
2396 struct lsa_String name;
2400 init_lsa_String(&name, TEST_ALIASNAME);
2401 r.in.domain_handle = domain_handle;
2402 r.in.alias_name = &name;
2403 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2404 r.out.alias_handle = alias_handle;
2407 printf("Testing CreateAlias (%s)\n", r.in.alias_name->string);
2409 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
2411 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
2412 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2413 printf("Server correctly refused create of '%s'\n", r.in.alias_name->string);
2416 printf("Server should have refused create of '%s', got %s instead\n", r.in.alias_name->string,
2422 if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
2423 if (!test_DeleteAlias_byname(p, tctx, domain_handle, r.in.alias_name->string)) {
2426 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
2429 if (!NT_STATUS_IS_OK(status)) {
2430 printf("CreateAlias failed - %s\n", nt_errstr(status));
2434 if (!test_alias_ops(p, tctx, alias_handle, domain_sid)) {
2441 static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2442 const char *acct_name,
2443 struct policy_handle *domain_handle, char **password)
2451 if (!test_ChangePasswordUser(p, mem_ctx, acct_name, domain_handle, password)) {
2455 if (!test_ChangePasswordUser2(p, mem_ctx, acct_name, password, 0, true)) {
2459 if (!test_OemChangePasswordUser2(p, mem_ctx, acct_name, domain_handle, password)) {
2463 /* test what happens when setting the old password again */
2464 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, *password, 0, true)) {
2469 char simple_pass[9];
2470 char *v = generate_random_str(mem_ctx, 1);
2472 ZERO_STRUCT(simple_pass);
2473 memset(simple_pass, *v, sizeof(simple_pass) - 1);
2475 /* test what happens when picking a simple password */
2476 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, simple_pass, 0, true)) {
2481 /* set samr_SetDomainInfo level 1 with min_length 5 */
2483 struct samr_QueryDomainInfo r;
2484 struct samr_SetDomainInfo s;
2485 uint16_t len_old, len;
2486 uint32_t pwd_prop_old;
2487 int64_t min_pwd_age_old;
2492 r.in.domain_handle = domain_handle;
2495 printf("testing samr_QueryDomainInfo level 1\n");
2496 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2497 if (!NT_STATUS_IS_OK(status)) {
2501 s.in.domain_handle = domain_handle;
2503 s.in.info = r.out.info;
2505 /* remember the old min length, so we can reset it */
2506 len_old = s.in.info->info1.min_password_length;
2507 s.in.info->info1.min_password_length = len;
2508 pwd_prop_old = s.in.info->info1.password_properties;
2509 /* turn off password complexity checks for this test */
2510 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
2512 min_pwd_age_old = s.in.info->info1.min_password_age;
2513 s.in.info->info1.min_password_age = 0;
2515 printf("testing samr_SetDomainInfo level 1\n");
2516 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2517 if (!NT_STATUS_IS_OK(status)) {
2521 printf("calling test_ChangePasswordUser3 with too short password\n");
2523 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, len - 1, password, NULL, 0, true)) {
2527 s.in.info->info1.min_password_length = len_old;
2528 s.in.info->info1.password_properties = pwd_prop_old;
2529 s.in.info->info1.min_password_age = min_pwd_age_old;
2531 printf("testing samr_SetDomainInfo level 1\n");
2532 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2533 if (!NT_STATUS_IS_OK(status)) {
2541 struct samr_OpenUser r;
2542 struct samr_QueryUserInfo q;
2543 struct samr_LookupNames n;
2544 struct policy_handle user_handle;
2546 n.in.domain_handle = domain_handle;
2548 n.in.names = talloc_array(mem_ctx, struct lsa_String, 1);
2549 n.in.names[0].string = acct_name;
2551 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
2552 if (!NT_STATUS_IS_OK(status)) {
2553 printf("LookupNames failed - %s\n", nt_errstr(status));
2557 r.in.domain_handle = domain_handle;
2558 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2559 r.in.rid = n.out.rids.ids[0];
2560 r.out.user_handle = &user_handle;
2562 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
2563 if (!NT_STATUS_IS_OK(status)) {
2564 printf("OpenUser(%u) failed - %s\n", n.out.rids.ids[0], nt_errstr(status));
2568 q.in.user_handle = &user_handle;
2571 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
2572 if (!NT_STATUS_IS_OK(status)) {
2573 printf("QueryUserInfo failed - %s\n", nt_errstr(status));
2577 printf("calling test_ChangePasswordUser3 with too early password change\n");
2579 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL,
2580 q.out.info->info5.last_password_change, true)) {
2585 /* we change passwords twice - this has the effect of verifying
2586 they were changed correctly for the final call */
2587 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, true)) {
2591 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, true)) {
2598 static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2599 struct policy_handle *domain_handle,
2600 struct policy_handle *user_handle_out,
2601 struct dom_sid *domain_sid,
2602 enum torture_samr_choice which_ops)
2605 TALLOC_CTX *user_ctx;
2608 struct samr_CreateUser r;
2609 struct samr_QueryUserInfo q;
2610 struct samr_DeleteUser d;
2613 /* This call creates a 'normal' account - check that it really does */
2614 const uint32_t acct_flags = ACB_NORMAL;
2615 struct lsa_String name;
2618 struct policy_handle user_handle;
2619 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
2620 init_lsa_String(&name, TEST_ACCOUNT_NAME);
2622 r.in.domain_handle = domain_handle;
2623 r.in.account_name = &name;
2624 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2625 r.out.user_handle = &user_handle;
2628 printf("Testing CreateUser(%s)\n", r.in.account_name->string);
2630 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
2632 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
2633 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
2634 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
2637 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
2643 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
2644 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
2645 talloc_free(user_ctx);
2648 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
2650 if (!NT_STATUS_IS_OK(status)) {
2651 talloc_free(user_ctx);
2652 printf("CreateUser failed - %s\n", nt_errstr(status));
2655 q.in.user_handle = &user_handle;
2658 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
2659 if (!NT_STATUS_IS_OK(status)) {
2660 printf("QueryUserInfo level %u failed - %s\n",
2661 q.in.level, nt_errstr(status));
2664 if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
2665 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2666 q.out.info->info16.acct_flags,
2672 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
2673 acct_flags, name.string, which_ops)) {
2677 if (user_handle_out) {
2678 *user_handle_out = user_handle;
2680 printf("Testing DeleteUser (createuser test)\n");
2682 d.in.user_handle = &user_handle;
2683 d.out.user_handle = &user_handle;
2685 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
2686 if (!NT_STATUS_IS_OK(status)) {
2687 printf("DeleteUser failed - %s\n", nt_errstr(status));
2694 talloc_free(user_ctx);
2700 static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
2701 struct policy_handle *domain_handle,
2702 struct dom_sid *domain_sid,
2703 enum torture_samr_choice which_ops)
2706 struct samr_CreateUser2 r;
2707 struct samr_QueryUserInfo q;
2708 struct samr_DeleteUser d;
2709 struct policy_handle user_handle;
2711 struct lsa_String name;
2716 uint32_t acct_flags;
2717 const char *account_name;
2719 } account_types[] = {
2720 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
2721 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2722 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2723 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
2724 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2725 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2726 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
2727 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2728 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2729 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
2730 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
2731 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
2732 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2733 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2734 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
2737 for (i = 0; account_types[i].account_name; i++) {
2738 TALLOC_CTX *user_ctx;
2739 uint32_t acct_flags = account_types[i].acct_flags;
2740 uint32_t access_granted;
2741 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
2742 init_lsa_String(&name, account_types[i].account_name);
2744 r.in.domain_handle = domain_handle;
2745 r.in.account_name = &name;
2746 r.in.acct_flags = acct_flags;
2747 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2748 r.out.user_handle = &user_handle;
2749 r.out.access_granted = &access_granted;
2752 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
2754 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
2756 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
2757 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
2758 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
2761 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
2768 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
2769 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
2770 talloc_free(user_ctx);
2774 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
2777 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
2778 printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
2779 nt_errstr(status), nt_errstr(account_types[i].nt_status));
2783 if (NT_STATUS_IS_OK(status)) {
2784 q.in.user_handle = &user_handle;
2787 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
2788 if (!NT_STATUS_IS_OK(status)) {
2789 printf("QueryUserInfo level %u failed - %s\n",
2790 q.in.level, nt_errstr(status));
2793 uint32_t expected_flags = (acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
2794 if (acct_flags == ACB_NORMAL) {
2795 expected_flags |= ACB_PW_EXPIRED;
2797 if ((q.out.info->info5.acct_flags) != expected_flags) {
2798 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2799 q.out.info->info5.acct_flags,
2803 switch (acct_flags) {
2805 if (q.out.info->info5.primary_gid != DOMAIN_RID_DCS) {
2806 printf("QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n",
2807 DOMAIN_RID_DCS, q.out.info->info5.primary_gid);
2812 if (q.out.info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
2813 printf("QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
2814 DOMAIN_RID_DOMAIN_MEMBERS, q.out.info->info5.primary_gid);
2819 if (q.out.info->info5.primary_gid != DOMAIN_RID_USERS) {
2820 printf("QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n",
2821 DOMAIN_RID_USERS, q.out.info->info5.primary_gid);
2828 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
2829 acct_flags, name.string, which_ops)) {
2833 printf("Testing DeleteUser (createuser2 test)\n");
2835 d.in.user_handle = &user_handle;
2836 d.out.user_handle = &user_handle;
2838 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
2839 if (!NT_STATUS_IS_OK(status)) {
2840 printf("DeleteUser failed - %s\n", nt_errstr(status));
2844 talloc_free(user_ctx);
2850 static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2851 struct policy_handle *handle)
2854 struct samr_QueryAliasInfo r;
2855 uint16_t levels[] = {1, 2, 3};
2859 for (i=0;i<ARRAY_SIZE(levels);i++) {
2860 printf("Testing QueryAliasInfo level %u\n", levels[i]);
2862 r.in.alias_handle = handle;
2863 r.in.level = levels[i];
2865 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
2866 if (!NT_STATUS_IS_OK(status)) {
2867 printf("QueryAliasInfo level %u failed - %s\n",
2868 levels[i], nt_errstr(status));
2876 static bool test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2877 struct policy_handle *handle)
2880 struct samr_QueryGroupInfo r;
2881 uint16_t levels[] = {1, 2, 3, 4, 5};
2885 for (i=0;i<ARRAY_SIZE(levels);i++) {
2886 printf("Testing QueryGroupInfo level %u\n", levels[i]);
2888 r.in.group_handle = handle;
2889 r.in.level = levels[i];
2891 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
2892 if (!NT_STATUS_IS_OK(status)) {
2893 printf("QueryGroupInfo level %u failed - %s\n",
2894 levels[i], nt_errstr(status));
2902 static bool test_QueryGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2903 struct policy_handle *handle)
2906 struct samr_QueryGroupMember r;
2909 printf("Testing QueryGroupMember\n");
2911 r.in.group_handle = handle;
2913 status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &r);
2914 if (!NT_STATUS_IS_OK(status)) {
2915 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
2923 static bool test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2924 struct policy_handle *handle)
2927 struct samr_QueryGroupInfo r;
2928 struct samr_SetGroupInfo s;
2929 uint16_t levels[] = {1, 2, 3, 4};
2930 uint16_t set_ok[] = {0, 1, 1, 1};
2934 for (i=0;i<ARRAY_SIZE(levels);i++) {
2935 printf("Testing QueryGroupInfo level %u\n", levels[i]);
2937 r.in.group_handle = handle;
2938 r.in.level = levels[i];
2940 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
2941 if (!NT_STATUS_IS_OK(status)) {
2942 printf("QueryGroupInfo level %u failed - %s\n",
2943 levels[i], nt_errstr(status));
2947 printf("Testing SetGroupInfo level %u\n", levels[i]);
2949 s.in.group_handle = handle;
2950 s.in.level = levels[i];
2951 s.in.info = r.out.info;
2954 /* disabled this, as it changes the name only from the point of view of samr,
2955 but leaves the name from the point of view of w2k3 internals (and ldap). This means
2956 the name is still reserved, so creating the old name fails, but deleting by the old name
2958 if (s.in.level == 2) {
2959 init_lsa_String(&s.in.info->string, "NewName");
2963 if (s.in.level == 4) {
2964 init_lsa_String(&s.in.info->description, "test description");
2967 status = dcerpc_samr_SetGroupInfo(p, mem_ctx, &s);
2969 if (!NT_STATUS_IS_OK(status)) {
2970 printf("SetGroupInfo level %u failed - %s\n",
2971 r.in.level, nt_errstr(status));
2976 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
2977 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
2978 r.in.level, nt_errstr(status));
2988 static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2989 struct policy_handle *handle)
2992 struct samr_QueryUserInfo r;
2993 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
2994 11, 12, 13, 14, 16, 17, 20, 21};
2998 for (i=0;i<ARRAY_SIZE(levels);i++) {
2999 printf("Testing QueryUserInfo level %u\n", levels[i]);
3001 r.in.user_handle = handle;
3002 r.in.level = levels[i];
3004 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
3005 if (!NT_STATUS_IS_OK(status)) {
3006 printf("QueryUserInfo level %u failed - %s\n",
3007 levels[i], nt_errstr(status));
3015 static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3016 struct policy_handle *handle)
3019 struct samr_QueryUserInfo2 r;
3020 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
3021 11, 12, 13, 14, 16, 17, 20, 21};
3025 for (i=0;i<ARRAY_SIZE(levels);i++) {
3026 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
3028 r.in.user_handle = handle;
3029 r.in.level = levels[i];
3031 status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r);
3032 if (!NT_STATUS_IS_OK(status)) {
3033 printf("QueryUserInfo2 level %u failed - %s\n",
3034 levels[i], nt_errstr(status));
3042 static bool test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3043 struct policy_handle *handle, uint32_t rid)
3046 struct samr_OpenUser r;
3047 struct policy_handle user_handle;
3050 printf("Testing OpenUser(%u)\n", rid);
3052 r.in.domain_handle = handle;
3053 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3055 r.out.user_handle = &user_handle;
3057 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3058 if (!NT_STATUS_IS_OK(status)) {
3059 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
3063 if (!test_QuerySecurity(p, mem_ctx, &user_handle)) {
3067 if (!test_QueryUserInfo(p, mem_ctx, &user_handle)) {
3071 if (!test_QueryUserInfo2(p, mem_ctx, &user_handle)) {
3075 if (!test_GetUserPwInfo(p, mem_ctx, &user_handle)) {
3079 if (!test_GetGroupsForUser(p,mem_ctx, &user_handle)) {
3083 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
3090 static bool test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3091 struct policy_handle *handle, uint32_t rid)
3094 struct samr_OpenGroup r;
3095 struct policy_handle group_handle;
3098 printf("Testing OpenGroup(%u)\n", rid);
3100 r.in.domain_handle = handle;
3101 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3103 r.out.group_handle = &group_handle;
3105 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
3106 if (!NT_STATUS_IS_OK(status)) {
3107 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
3111 if (!test_QuerySecurity(p, mem_ctx, &group_handle)) {
3115 if (!test_QueryGroupInfo(p, mem_ctx, &group_handle)) {
3119 if (!test_QueryGroupMember(p, mem_ctx, &group_handle)) {
3123 if (!test_samr_handle_Close(p, mem_ctx, &group_handle)) {
3130 static bool test_OpenAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
3131 struct policy_handle *handle, uint32_t rid)
3134 struct samr_OpenAlias r;
3135 struct policy_handle alias_handle;
3138 torture_comment(tctx, "Testing OpenAlias(%u)\n", rid);
3140 r.in.domain_handle = handle;
3141 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3143 r.out.alias_handle = &alias_handle;
3145 status = dcerpc_samr_OpenAlias(p, tctx, &r);
3146 if (!NT_STATUS_IS_OK(status)) {
3147 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
3151 if (!test_QuerySecurity(p, tctx, &alias_handle)) {
3155 if (!test_QueryAliasInfo(p, tctx, &alias_handle)) {
3159 if (!test_GetMembersInAlias(p, tctx, &alias_handle)) {
3163 if (!test_samr_handle_Close(p, tctx, &alias_handle)) {
3170 static bool check_mask(struct dcerpc_pipe *p, struct torture_context *tctx,
3171 struct policy_handle *handle, uint32_t rid,
3172 uint32_t acct_flag_mask)
3175 struct samr_OpenUser r;
3176 struct samr_QueryUserInfo q;
3177 struct policy_handle user_handle;
3180 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
3182 r.in.domain_handle = handle;
3183 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3185 r.out.user_handle = &user_handle;
3187 status = dcerpc_samr_OpenUser(p, tctx, &r);
3188 if (!NT_STATUS_IS_OK(status)) {
3189 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
3193 q.in.user_handle = &user_handle;
3196 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
3197 if (!NT_STATUS_IS_OK(status)) {
3198 printf("QueryUserInfo level 16 failed - %s\n",