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"
34 #define TEST_ACCOUNT_NAME "samrtorturetest"
35 #define TEST_ALIASNAME "samrtorturetestalias"
36 #define TEST_GROUPNAME "samrtorturetestgroup"
37 #define TEST_MACHINENAME "samrtestmach$"
38 #define TEST_DOMAINNAME "samrtestdom$"
40 enum torture_samr_choice {
41 TORTURE_SAMR_PASSWORDS,
42 TORTURE_SAMR_USER_ATTRIBUTES,
46 static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
47 struct policy_handle *handle);
49 static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
50 struct policy_handle *handle);
52 static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
53 struct policy_handle *handle);
55 static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
56 const char *acct_name,
57 struct policy_handle *domain_handle, char **password);
59 static void init_lsa_String(struct lsa_String *string, const char *s)
64 static void init_lsa_BinaryString(struct lsa_BinaryString *string, const char *s, uint32_t length)
66 string->length = length;
67 string->size = length;
68 string->array = (uint16_t *)discard_const(s);
71 bool test_samr_handle_Close(struct dcerpc_pipe *p, struct torture_context *tctx,
72 struct policy_handle *handle)
78 r.out.handle = handle;
80 status = dcerpc_samr_Close(p, tctx, &r);
81 torture_assert_ntstatus_ok(tctx, status, "Close");
86 static bool test_Shutdown(struct dcerpc_pipe *p, struct torture_context *tctx,
87 struct policy_handle *handle)
90 struct samr_Shutdown r;
92 if (!torture_setting_bool(tctx, "dangerous", false)) {
93 torture_skip(tctx, "samr_Shutdown disabled - enable dangerous tests to use\n");
97 r.in.connect_handle = handle;
99 torture_comment(tctx, "testing samr_Shutdown\n");
101 status = dcerpc_samr_Shutdown(p, tctx, &r);
102 torture_assert_ntstatus_ok(tctx, status, "samr_Shutdown");
107 static bool test_SetDsrmPassword(struct dcerpc_pipe *p, struct torture_context *tctx,
108 struct policy_handle *handle)
111 struct samr_SetDsrmPassword r;
112 struct lsa_String string;
113 struct samr_Password hash;
115 if (!torture_setting_bool(tctx, "dangerous", false)) {
116 torture_skip(tctx, "samr_SetDsrmPassword disabled - enable dangerous tests to use");
119 E_md4hash("TeSTDSRM123", hash.hash);
121 init_lsa_String(&string, "Administrator");
127 torture_comment(tctx, "testing samr_SetDsrmPassword\n");
129 status = dcerpc_samr_SetDsrmPassword(p, tctx, &r);
130 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_SUPPORTED, "samr_SetDsrmPassword");
136 static bool test_QuerySecurity(struct dcerpc_pipe *p,
137 struct torture_context *tctx,
138 struct policy_handle *handle)
141 struct samr_QuerySecurity r;
142 struct samr_SetSecurity s;
143 struct sec_desc_buf *sdbuf = NULL;
145 r.in.handle = handle;
147 r.out.sdbuf = &sdbuf;
149 status = dcerpc_samr_QuerySecurity(p, tctx, &r);
150 torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
152 torture_assert(tctx, sdbuf != NULL, "sdbuf is NULL");
154 s.in.handle = handle;
158 if (torture_setting_bool(tctx, "samba4", false)) {
159 torture_skip(tctx, "skipping SetSecurity test against Samba4\n");
162 status = dcerpc_samr_SetSecurity(p, tctx, &s);
163 torture_assert_ntstatus_ok(tctx, status, "SetSecurity");
165 status = dcerpc_samr_QuerySecurity(p, tctx, &r);
166 torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
172 static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
173 struct policy_handle *handle, uint32_t base_acct_flags,
174 const char *base_account_name)
177 struct samr_SetUserInfo s;
178 struct samr_SetUserInfo2 s2;
179 struct samr_QueryUserInfo q;
180 struct samr_QueryUserInfo q0;
181 union samr_UserInfo u;
182 union samr_UserInfo *info;
184 const char *test_account_name;
186 uint32_t user_extra_flags = 0;
187 if (base_acct_flags == ACB_NORMAL) {
188 /* When created, accounts are expired by default */
189 user_extra_flags = ACB_PW_EXPIRED;
192 s.in.user_handle = handle;
195 s2.in.user_handle = handle;
198 q.in.user_handle = handle;
202 #define TESTCALL(call, r) \
203 status = dcerpc_samr_ ##call(p, tctx, &r); \
204 if (!NT_STATUS_IS_OK(status)) { \
205 torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
206 r.in.level, nt_errstr(status), __location__); \
211 #define STRING_EQUAL(s1, s2, field) \
212 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
213 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
214 #field, s2, __location__); \
219 #define MEM_EQUAL(s1, s2, length, field) \
220 if ((s1 && !s2) || (s2 && !s1) || memcmp(s1, s2, length)) { \
221 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
222 #field, (const char *)s2, __location__); \
227 #define INT_EQUAL(i1, i2, field) \
229 torture_comment(tctx, "Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \
230 #field, (unsigned long long)i2, (unsigned long long)i1, __location__); \
235 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
236 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
238 TESTCALL(QueryUserInfo, q) \
240 s2.in.level = lvl1; \
243 ZERO_STRUCT(u.info21); \
244 u.info21.fields_present = fpval; \
246 init_lsa_String(&u.info ## lvl1.field1, value); \
247 TESTCALL(SetUserInfo, s) \
248 TESTCALL(SetUserInfo2, s2) \
249 init_lsa_String(&u.info ## lvl1.field1, ""); \
250 TESTCALL(QueryUserInfo, q); \
252 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
254 TESTCALL(QueryUserInfo, q) \
256 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
259 #define TEST_USERINFO_BINARYSTRING(lvl1, field1, lvl2, field2, value, fpval) do { \
260 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
262 TESTCALL(QueryUserInfo, q) \
264 s2.in.level = lvl1; \
267 ZERO_STRUCT(u.info21); \
268 u.info21.fields_present = fpval; \
270 init_lsa_BinaryString(&u.info ## lvl1.field1, value, strlen(value)); \
271 TESTCALL(SetUserInfo, s) \
272 TESTCALL(SetUserInfo2, s2) \
273 init_lsa_BinaryString(&u.info ## lvl1.field1, "", 1); \
274 TESTCALL(QueryUserInfo, q); \
276 MEM_EQUAL(u.info ## lvl1.field1.array, value, strlen(value), field1); \
278 TESTCALL(QueryUserInfo, q) \
280 MEM_EQUAL(u.info ## lvl2.field2.array, value, strlen(value), field2); \
283 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
284 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
286 TESTCALL(QueryUserInfo, q) \
288 s2.in.level = lvl1; \
291 uint8_t *bits = u.info21.logon_hours.bits; \
292 ZERO_STRUCT(u.info21); \
293 if (fpval == SAMR_FIELD_LOGON_HOURS) { \
294 u.info21.logon_hours.units_per_week = 168; \
295 u.info21.logon_hours.bits = bits; \
297 u.info21.fields_present = fpval; \
299 u.info ## lvl1.field1 = value; \
300 TESTCALL(SetUserInfo, s) \
301 TESTCALL(SetUserInfo2, s2) \
302 u.info ## lvl1.field1 = 0; \
303 TESTCALL(QueryUserInfo, q); \
305 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
307 TESTCALL(QueryUserInfo, q) \
309 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
312 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
313 TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
317 do { TESTCALL(QueryUserInfo, q0) } while (0);
319 TEST_USERINFO_STRING(2, comment, 1, comment, "xx2-1 comment", 0);
320 TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
321 TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment",
324 test_account_name = talloc_asprintf(tctx, "%sxx7-1", base_account_name);
325 TEST_USERINFO_STRING(7, account_name, 1, account_name, base_account_name, 0);
326 test_account_name = talloc_asprintf(tctx, "%sxx7-3", base_account_name);
327 TEST_USERINFO_STRING(7, account_name, 3, account_name, base_account_name, 0);
328 test_account_name = talloc_asprintf(tctx, "%sxx7-5", base_account_name);
329 TEST_USERINFO_STRING(7, account_name, 5, account_name, base_account_name, 0);
330 test_account_name = talloc_asprintf(tctx, "%sxx7-6", base_account_name);
331 TEST_USERINFO_STRING(7, account_name, 6, account_name, base_account_name, 0);
332 test_account_name = talloc_asprintf(tctx, "%sxx7-7", base_account_name);
333 TEST_USERINFO_STRING(7, account_name, 7, account_name, base_account_name, 0);
334 test_account_name = talloc_asprintf(tctx, "%sxx7-21", base_account_name);
335 TEST_USERINFO_STRING(7, account_name, 21, account_name, base_account_name, 0);
336 test_account_name = base_account_name;
337 TEST_USERINFO_STRING(21, account_name, 21, account_name, base_account_name,
338 SAMR_FIELD_ACCOUNT_NAME);
340 TEST_USERINFO_STRING(6, full_name, 1, full_name, "xx6-1 full_name", 0);
341 TEST_USERINFO_STRING(6, full_name, 3, full_name, "xx6-3 full_name", 0);
342 TEST_USERINFO_STRING(6, full_name, 5, full_name, "xx6-5 full_name", 0);
343 TEST_USERINFO_STRING(6, full_name, 6, full_name, "xx6-6 full_name", 0);
344 TEST_USERINFO_STRING(6, full_name, 8, full_name, "xx6-8 full_name", 0);
345 TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
346 TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
347 TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name",
348 SAMR_FIELD_FULL_NAME);
350 TEST_USERINFO_STRING(6, full_name, 1, full_name, "", 0);
351 TEST_USERINFO_STRING(6, full_name, 3, full_name, "", 0);
352 TEST_USERINFO_STRING(6, full_name, 5, full_name, "", 0);
353 TEST_USERINFO_STRING(6, full_name, 6, full_name, "", 0);
354 TEST_USERINFO_STRING(6, full_name, 8, full_name, "", 0);
355 TEST_USERINFO_STRING(6, full_name, 21, full_name, "", 0);
356 TEST_USERINFO_STRING(8, full_name, 21, full_name, "", 0);
357 TEST_USERINFO_STRING(21, full_name, 21, full_name, "",
358 SAMR_FIELD_FULL_NAME);
360 TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
361 TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
362 TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
363 TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script",
364 SAMR_FIELD_LOGON_SCRIPT);
366 TEST_USERINFO_STRING(12, profile_path, 3, profile_path, "xx12-3 profile_path", 0);
367 TEST_USERINFO_STRING(12, profile_path, 5, profile_path, "xx12-5 profile_path", 0);
368 TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
369 TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path",
370 SAMR_FIELD_PROFILE_PATH);
372 TEST_USERINFO_STRING(10, home_directory, 3, home_directory, "xx10-3 home_directory", 0);
373 TEST_USERINFO_STRING(10, home_directory, 5, home_directory, "xx10-5 home_directory", 0);
374 TEST_USERINFO_STRING(10, home_directory, 21, home_directory, "xx10-21 home_directory", 0);
375 TEST_USERINFO_STRING(21, home_directory, 21, home_directory, "xx21-21 home_directory",
376 SAMR_FIELD_HOME_DIRECTORY);
377 TEST_USERINFO_STRING(21, home_directory, 10, home_directory, "xx21-10 home_directory",
378 SAMR_FIELD_HOME_DIRECTORY);
380 TEST_USERINFO_STRING(10, home_drive, 3, home_drive, "xx10-3 home_drive", 0);
381 TEST_USERINFO_STRING(10, home_drive, 5, home_drive, "xx10-5 home_drive", 0);
382 TEST_USERINFO_STRING(10, home_drive, 21, home_drive, "xx10-21 home_drive", 0);
383 TEST_USERINFO_STRING(21, home_drive, 21, home_drive, "xx21-21 home_drive",
384 SAMR_FIELD_HOME_DRIVE);
385 TEST_USERINFO_STRING(21, home_drive, 10, home_drive, "xx21-10 home_drive",
386 SAMR_FIELD_HOME_DRIVE);
388 TEST_USERINFO_STRING(13, description, 1, description, "xx13-1 description", 0);
389 TEST_USERINFO_STRING(13, description, 5, description, "xx13-5 description", 0);
390 TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
391 TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description",
392 SAMR_FIELD_DESCRIPTION);
394 TEST_USERINFO_STRING(14, workstations, 3, workstations, "14workstation3", 0);
395 TEST_USERINFO_STRING(14, workstations, 5, workstations, "14workstation4", 0);
396 TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
397 TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21",
398 SAMR_FIELD_WORKSTATIONS);
399 TEST_USERINFO_STRING(21, workstations, 3, workstations, "21workstation3",
400 SAMR_FIELD_WORKSTATIONS);
401 TEST_USERINFO_STRING(21, workstations, 5, workstations, "21workstation5",
402 SAMR_FIELD_WORKSTATIONS);
403 TEST_USERINFO_STRING(21, workstations, 14, workstations, "21workstation14",
404 SAMR_FIELD_WORKSTATIONS);
406 TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
407 TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "xx21-21 parameters",
408 SAMR_FIELD_PARAMETERS);
409 TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "xx21-20 parameters",
410 SAMR_FIELD_PARAMETERS);
412 TEST_USERINFO_INT(2, country_code, 2, country_code, __LINE__, 0);
413 TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
414 TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__,
415 SAMR_FIELD_COUNTRY_CODE);
416 TEST_USERINFO_INT(21, country_code, 2, country_code, __LINE__,
417 SAMR_FIELD_COUNTRY_CODE);
419 TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
420 TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__,
421 SAMR_FIELD_CODE_PAGE);
422 TEST_USERINFO_INT(21, code_page, 2, code_page, __LINE__,
423 SAMR_FIELD_CODE_PAGE);
425 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, __LINE__, 0);
426 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, __LINE__, 0);
427 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, __LINE__,
428 SAMR_FIELD_ACCT_EXPIRY);
429 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, __LINE__,
430 SAMR_FIELD_ACCT_EXPIRY);
431 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, __LINE__,
432 SAMR_FIELD_ACCT_EXPIRY);
434 TEST_USERINFO_INT(4, logon_hours.bits[3], 3, logon_hours.bits[3], 1, 0);
435 TEST_USERINFO_INT(4, logon_hours.bits[3], 5, logon_hours.bits[3], 2, 0);
436 TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
437 TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4,
438 SAMR_FIELD_LOGON_HOURS);
440 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
441 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
442 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
444 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
445 (base_acct_flags | ACB_DISABLED),
446 (base_acct_flags | ACB_DISABLED | user_extra_flags),
449 /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
450 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
451 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
452 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
454 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
455 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
456 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
460 /* The 'autolock' flag doesn't stick - check this */
461 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
462 (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK),
463 (base_acct_flags | ACB_DISABLED | user_extra_flags),
466 /* Removing the 'disabled' flag doesn't stick - check this */
467 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
469 (base_acct_flags | ACB_DISABLED | user_extra_flags),
472 /* The 'store plaintext' flag does stick */
473 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
474 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED),
475 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags),
477 /* The 'use DES' flag does stick */
478 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
479 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY),
480 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags),
482 /* The 'don't require kerberos pre-authentication flag does stick */
483 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
484 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH),
485 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags),
487 /* The 'no kerberos PAC required' flag sticks */
488 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
489 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD),
490 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags),
493 TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags,
494 (base_acct_flags | ACB_DISABLED),
495 (base_acct_flags | ACB_DISABLED | user_extra_flags),
496 SAMR_FIELD_ACCT_FLAGS);
499 /* these fail with win2003 - it appears you can't set the primary gid?
500 the set succeeds, but the gid isn't changed. Very weird! */
501 TEST_USERINFO_INT(9, primary_gid, 1, primary_gid, 513);
502 TEST_USERINFO_INT(9, primary_gid, 3, primary_gid, 513);
503 TEST_USERINFO_INT(9, primary_gid, 5, primary_gid, 513);
504 TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
511 generate a random password for password change tests
513 static char *samr_rand_pass_silent(TALLOC_CTX *mem_ctx, int min_len)
515 size_t len = MAX(8, min_len) + (random() % 6);
516 char *s = generate_random_str(mem_ctx, len);
520 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
522 char *s = samr_rand_pass_silent(mem_ctx, min_len);
523 printf("Generated password '%s'\n", s);
529 generate a random password for password change tests
531 static DATA_BLOB samr_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
534 DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
535 generate_random_buffer(password.data, password.length);
537 for (i=0; i < len; i++) {
538 if (((uint16_t *)password.data)[i] == 0) {
539 ((uint16_t *)password.data)[i] = 1;
547 generate a random password for password change tests (fixed length)
549 static char *samr_rand_pass_fixed_len(TALLOC_CTX *mem_ctx, int len)
551 char *s = generate_random_str(mem_ctx, len);
552 printf("Generated password '%s'\n", s);
556 static bool test_SetUserPass(struct dcerpc_pipe *p, struct torture_context *tctx,
557 struct policy_handle *handle, char **password)
560 struct samr_SetUserInfo s;
561 union samr_UserInfo u;
563 DATA_BLOB session_key;
565 struct samr_GetUserPwInfo pwp;
566 struct samr_PwInfo info;
567 int policy_min_pw_len = 0;
568 pwp.in.user_handle = handle;
569 pwp.out.info = &info;
571 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
572 if (NT_STATUS_IS_OK(status)) {
573 policy_min_pw_len = pwp.out.info->min_password_length;
575 newpass = samr_rand_pass(tctx, policy_min_pw_len);
577 s.in.user_handle = handle;
581 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
582 u.info24.password_expired = 0;
584 status = dcerpc_fetch_session_key(p, &session_key);
585 if (!NT_STATUS_IS_OK(status)) {
586 printf("SetUserInfo level %u - no session key - %s\n",
587 s.in.level, nt_errstr(status));
591 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
593 torture_comment(tctx, "Testing SetUserInfo level 24 (set password)\n");
595 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
596 if (!NT_STATUS_IS_OK(status)) {
597 printf("SetUserInfo level %u failed - %s\n",
598 s.in.level, nt_errstr(status));
608 static bool test_SetUserPass_23(struct dcerpc_pipe *p, struct torture_context *tctx,
609 struct policy_handle *handle, uint32_t fields_present,
613 struct samr_SetUserInfo s;
614 union samr_UserInfo u;
616 DATA_BLOB session_key;
618 struct samr_GetUserPwInfo pwp;
619 struct samr_PwInfo info;
620 int policy_min_pw_len = 0;
621 pwp.in.user_handle = handle;
622 pwp.out.info = &info;
624 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
625 if (NT_STATUS_IS_OK(status)) {
626 policy_min_pw_len = pwp.out.info->min_password_length;
628 newpass = samr_rand_pass(tctx, policy_min_pw_len);
630 s.in.user_handle = handle;
636 u.info23.info.fields_present = fields_present;
638 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
640 status = dcerpc_fetch_session_key(p, &session_key);
641 if (!NT_STATUS_IS_OK(status)) {
642 printf("SetUserInfo level %u - no session key - %s\n",
643 s.in.level, nt_errstr(status));
647 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
649 torture_comment(tctx, "Testing SetUserInfo level 23 (set password)\n");
651 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
652 if (!NT_STATUS_IS_OK(status)) {
653 printf("SetUserInfo level %u failed - %s\n",
654 s.in.level, nt_errstr(status));
660 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
662 status = dcerpc_fetch_session_key(p, &session_key);
663 if (!NT_STATUS_IS_OK(status)) {
664 printf("SetUserInfo level %u - no session key - %s\n",
665 s.in.level, nt_errstr(status));
669 /* This should break the key nicely */
670 session_key.length--;
671 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
673 torture_comment(tctx, "Testing SetUserInfo level 23 (set password) with wrong password\n");
675 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
676 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
677 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
678 s.in.level, nt_errstr(status));
686 static bool test_SetUserPassEx(struct dcerpc_pipe *p, struct torture_context *tctx,
687 struct policy_handle *handle, bool makeshort,
691 struct samr_SetUserInfo s;
692 union samr_UserInfo u;
694 DATA_BLOB session_key;
695 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
696 uint8_t confounder[16];
698 struct MD5Context ctx;
699 struct samr_GetUserPwInfo pwp;
700 struct samr_PwInfo info;
701 int policy_min_pw_len = 0;
702 pwp.in.user_handle = handle;
703 pwp.out.info = &info;
705 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
706 if (NT_STATUS_IS_OK(status)) {
707 policy_min_pw_len = pwp.out.info->min_password_length;
709 if (makeshort && policy_min_pw_len) {
710 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len - 1);
712 newpass = samr_rand_pass(tctx, policy_min_pw_len);
715 s.in.user_handle = handle;
719 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
720 u.info26.password_expired = 0;
722 status = dcerpc_fetch_session_key(p, &session_key);
723 if (!NT_STATUS_IS_OK(status)) {
724 printf("SetUserInfo level %u - no session key - %s\n",
725 s.in.level, nt_errstr(status));
729 generate_random_buffer((uint8_t *)confounder, 16);
732 MD5Update(&ctx, confounder, 16);
733 MD5Update(&ctx, session_key.data, session_key.length);
734 MD5Final(confounded_session_key.data, &ctx);
736 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
737 memcpy(&u.info26.password.data[516], confounder, 16);
739 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex)\n");
741 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
742 if (!NT_STATUS_IS_OK(status)) {
743 printf("SetUserInfo level %u failed - %s\n",
744 s.in.level, nt_errstr(status));
750 /* This should break the key nicely */
751 confounded_session_key.data[0]++;
753 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
754 memcpy(&u.info26.password.data[516], confounder, 16);
756 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
758 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
759 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
760 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
761 s.in.level, nt_errstr(status));
770 static bool test_SetUserPass_25(struct dcerpc_pipe *p, struct torture_context *tctx,
771 struct policy_handle *handle, uint32_t fields_present,
775 struct samr_SetUserInfo s;
776 union samr_UserInfo u;
778 DATA_BLOB session_key;
779 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
780 struct MD5Context ctx;
781 uint8_t confounder[16];
783 struct samr_GetUserPwInfo pwp;
784 struct samr_PwInfo info;
785 int policy_min_pw_len = 0;
786 pwp.in.user_handle = handle;
787 pwp.out.info = &info;
789 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
790 if (NT_STATUS_IS_OK(status)) {
791 policy_min_pw_len = pwp.out.info->min_password_length;
793 newpass = samr_rand_pass(tctx, policy_min_pw_len);
795 s.in.user_handle = handle;
801 u.info25.info.fields_present = fields_present;
803 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
805 status = dcerpc_fetch_session_key(p, &session_key);
806 if (!NT_STATUS_IS_OK(status)) {
807 printf("SetUserInfo level %u - no session key - %s\n",
808 s.in.level, nt_errstr(status));
812 generate_random_buffer((uint8_t *)confounder, 16);
815 MD5Update(&ctx, confounder, 16);
816 MD5Update(&ctx, session_key.data, session_key.length);
817 MD5Final(confounded_session_key.data, &ctx);
819 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
820 memcpy(&u.info25.password.data[516], confounder, 16);
822 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex)\n");
824 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
825 if (!NT_STATUS_IS_OK(status)) {
826 printf("SetUserInfo level %u failed - %s\n",
827 s.in.level, nt_errstr(status));
833 /* This should break the key nicely */
834 confounded_session_key.data[0]++;
836 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
837 memcpy(&u.info25.password.data[516], confounder, 16);
839 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
841 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
842 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
843 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
844 s.in.level, nt_errstr(status));
851 static bool test_SetUserPass_level_ex(struct dcerpc_pipe *p,
852 struct torture_context *tctx,
853 struct policy_handle *handle,
855 uint32_t fields_present,
856 char **password, uint8_t password_expired,
857 bool use_setinfo2, NTSTATUS expected_error)
860 struct samr_SetUserInfo s;
861 struct samr_SetUserInfo2 s2;
862 union samr_UserInfo u;
864 DATA_BLOB session_key;
865 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
866 struct MD5Context ctx;
867 uint8_t confounder[16];
869 struct samr_GetUserPwInfo pwp;
870 struct samr_PwInfo info;
871 int policy_min_pw_len = 0;
872 pwp.in.user_handle = handle;
873 pwp.out.info = &info;
875 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
876 if (NT_STATUS_IS_OK(status)) {
877 policy_min_pw_len = pwp.out.info->min_password_length;
879 newpass = samr_rand_pass_silent(tctx, policy_min_pw_len);
882 s2.in.user_handle = handle;
886 s.in.user_handle = handle;
895 u.info21.fields_present = fields_present;
896 u.info21.password_expired = password_expired;
900 u.info23.info.fields_present = fields_present;
901 u.info23.info.password_expired = password_expired;
903 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
907 u.info24.password_expired = password_expired;
909 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
913 u.info25.info.fields_present = fields_present;
914 u.info25.info.password_expired = password_expired;
916 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
920 u.info26.password_expired = password_expired;
922 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
927 status = dcerpc_fetch_session_key(p, &session_key);
928 if (!NT_STATUS_IS_OK(status)) {
929 printf("SetUserInfo level %u - no session key - %s\n",
930 s.in.level, nt_errstr(status));
934 generate_random_buffer((uint8_t *)confounder, 16);
937 MD5Update(&ctx, confounder, 16);
938 MD5Update(&ctx, session_key.data, session_key.length);
939 MD5Final(confounded_session_key.data, &ctx);
943 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
946 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
949 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
950 memcpy(&u.info25.password.data[516], confounder, 16);
953 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
954 memcpy(&u.info26.password.data[516], confounder, 16);
959 status = dcerpc_samr_SetUserInfo2(p, tctx, &s2);
961 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
964 if (NT_STATUS_IS_ERR(expected_error)) {
965 torture_assert_ntstatus_equal(tctx, status, expected_error, "");
969 if (!NT_STATUS_IS_OK(status)) {
970 printf("SetUserInfo%s level %u failed - %s\n",
971 use_setinfo2 ? "2":"", level, nt_errstr(status));
982 static bool test_SetAliasInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
983 struct policy_handle *handle)
986 struct samr_SetAliasInfo r;
987 struct samr_QueryAliasInfo q;
988 union samr_AliasInfo *info;
989 uint16_t levels[] = {2, 3};
993 /* Ignoring switch level 1, as that includes the number of members for the alias
994 * and setting this to a wrong value might have negative consequences
997 for (i=0;i<ARRAY_SIZE(levels);i++) {
998 torture_comment(tctx, "Testing SetAliasInfo level %u\n", levels[i]);
1000 r.in.alias_handle = handle;
1001 r.in.level = levels[i];
1002 r.in.info = talloc(tctx, union samr_AliasInfo);
1003 switch (r.in.level) {
1004 case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
1005 case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
1006 "Test Description, should test I18N as well"); break;
1007 case ALIASINFOALL: printf("ALIASINFOALL ignored\n"); break;
1010 status = dcerpc_samr_SetAliasInfo(p, tctx, &r);
1011 if (!NT_STATUS_IS_OK(status)) {
1012 printf("SetAliasInfo level %u failed - %s\n",
1013 levels[i], nt_errstr(status));
1017 q.in.alias_handle = handle;
1018 q.in.level = levels[i];
1021 status = dcerpc_samr_QueryAliasInfo(p, tctx, &q);
1022 if (!NT_STATUS_IS_OK(status)) {
1023 printf("QueryAliasInfo level %u failed - %s\n",
1024 levels[i], nt_errstr(status));
1032 static bool test_GetGroupsForUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1033 struct policy_handle *user_handle)
1035 struct samr_GetGroupsForUser r;
1036 struct samr_RidWithAttributeArray *rids = NULL;
1039 torture_comment(tctx, "testing GetGroupsForUser\n");
1041 r.in.user_handle = user_handle;
1044 status = dcerpc_samr_GetGroupsForUser(p, tctx, &r);
1045 torture_assert_ntstatus_ok(tctx, status, "GetGroupsForUser");
1051 static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1052 struct lsa_String *domain_name)
1055 struct samr_GetDomPwInfo r;
1056 struct samr_PwInfo info;
1058 r.in.domain_name = domain_name;
1061 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1063 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1064 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1066 r.in.domain_name->string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1067 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1069 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1070 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1072 r.in.domain_name->string = "\\\\__NONAME__";
1073 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1075 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1076 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1078 r.in.domain_name->string = "\\\\Builtin";
1079 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1081 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1082 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1087 static bool test_GetUserPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1088 struct policy_handle *handle)
1091 struct samr_GetUserPwInfo r;
1092 struct samr_PwInfo info;
1094 torture_comment(tctx, "Testing GetUserPwInfo\n");
1096 r.in.user_handle = handle;
1099 status = dcerpc_samr_GetUserPwInfo(p, tctx, &r);
1100 torture_assert_ntstatus_ok(tctx, status, "GetUserPwInfo");
1105 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, struct torture_context *tctx,
1106 struct policy_handle *domain_handle, const char *name,
1110 struct samr_LookupNames n;
1111 struct lsa_String sname[2];
1112 struct samr_Ids rids, types;
1114 init_lsa_String(&sname[0], name);
1116 n.in.domain_handle = domain_handle;
1120 n.out.types = &types;
1121 status = dcerpc_samr_LookupNames(p, tctx, &n);
1122 if (NT_STATUS_IS_OK(status)) {
1123 *rid = n.out.rids->ids[0];
1128 init_lsa_String(&sname[1], "xxNONAMExx");
1130 status = dcerpc_samr_LookupNames(p, tctx, &n);
1131 if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
1132 printf("LookupNames[2] failed - %s\n", nt_errstr(status));
1133 if (NT_STATUS_IS_OK(status)) {
1134 return NT_STATUS_UNSUCCESSFUL;
1140 status = dcerpc_samr_LookupNames(p, tctx, &n);
1141 if (!NT_STATUS_IS_OK(status)) {
1142 printf("LookupNames[0] failed - %s\n", nt_errstr(status));
1146 init_lsa_String(&sname[0], "xxNONAMExx");
1148 status = dcerpc_samr_LookupNames(p, tctx, &n);
1149 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1150 printf("LookupNames[1 bad name] failed - %s\n", nt_errstr(status));
1151 if (NT_STATUS_IS_OK(status)) {
1152 return NT_STATUS_UNSUCCESSFUL;
1157 init_lsa_String(&sname[0], "xxNONAMExx");
1158 init_lsa_String(&sname[1], "xxNONAME2xx");
1160 status = dcerpc_samr_LookupNames(p, tctx, &n);
1161 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1162 printf("LookupNames[2 bad names] failed - %s\n", nt_errstr(status));
1163 if (NT_STATUS_IS_OK(status)) {
1164 return NT_STATUS_UNSUCCESSFUL;
1169 return NT_STATUS_OK;
1172 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1173 struct policy_handle *domain_handle,
1174 const char *name, struct policy_handle *user_handle)
1177 struct samr_OpenUser r;
1180 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
1181 if (!NT_STATUS_IS_OK(status)) {
1185 r.in.domain_handle = domain_handle;
1186 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1188 r.out.user_handle = user_handle;
1189 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
1190 if (!NT_STATUS_IS_OK(status)) {
1191 printf("OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(status));
1198 static bool test_ChangePasswordNT3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1199 struct policy_handle *handle)
1202 struct samr_ChangePasswordUser r;
1204 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1205 struct policy_handle user_handle;
1206 char *oldpass = "test";
1207 char *newpass = "test2";
1208 uint8_t old_nt_hash[16], new_nt_hash[16];
1209 uint8_t old_lm_hash[16], new_lm_hash[16];
1211 status = test_OpenUser_byname(p, mem_ctx, handle, "testuser", &user_handle);
1212 if (!NT_STATUS_IS_OK(status)) {
1216 printf("Testing ChangePasswordUser for user 'testuser'\n");
1218 printf("old password: %s\n", oldpass);
1219 printf("new password: %s\n", newpass);
1221 E_md4hash(oldpass, old_nt_hash);
1222 E_md4hash(newpass, new_nt_hash);
1223 E_deshash(oldpass, old_lm_hash);
1224 E_deshash(newpass, new_lm_hash);
1226 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1227 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1228 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1229 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1230 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1231 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1233 r.in.handle = &user_handle;
1234 r.in.lm_present = 1;
1235 r.in.old_lm_crypted = &hash1;
1236 r.in.new_lm_crypted = &hash2;
1237 r.in.nt_present = 1;
1238 r.in.old_nt_crypted = &hash3;
1239 r.in.new_nt_crypted = &hash4;
1240 r.in.cross1_present = 1;
1241 r.in.nt_cross = &hash5;
1242 r.in.cross2_present = 1;
1243 r.in.lm_cross = &hash6;
1245 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1246 if (!NT_STATUS_IS_OK(status)) {
1247 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1251 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1259 static bool test_ChangePasswordUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1260 const char *acct_name,
1261 struct policy_handle *handle, char **password)
1264 struct samr_ChangePasswordUser r;
1266 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1267 struct policy_handle user_handle;
1269 uint8_t old_nt_hash[16], new_nt_hash[16];
1270 uint8_t old_lm_hash[16], new_lm_hash[16];
1271 bool changed = true;
1274 struct samr_GetUserPwInfo pwp;
1275 struct samr_PwInfo info;
1276 int policy_min_pw_len = 0;
1278 status = test_OpenUser_byname(p, tctx, handle, acct_name, &user_handle);
1279 if (!NT_STATUS_IS_OK(status)) {
1282 pwp.in.user_handle = &user_handle;
1283 pwp.out.info = &info;
1285 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1286 if (NT_STATUS_IS_OK(status)) {
1287 policy_min_pw_len = pwp.out.info->min_password_length;
1289 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1291 torture_comment(tctx, "Testing ChangePasswordUser\n");
1293 torture_assert(tctx, *password != NULL,
1294 "Failing ChangePasswordUser as old password was NULL. Previous test failed?");
1296 oldpass = *password;
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);
1303 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1304 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1305 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1306 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1307 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1308 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1310 r.in.user_handle = &user_handle;
1311 r.in.lm_present = 1;
1312 /* Break the LM hash */
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 = 1;
1320 r.in.nt_cross = &hash5;
1321 r.in.cross2_present = 1;
1322 r.in.lm_cross = &hash6;
1324 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1325 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1326 "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash");
1328 /* Unbreak the LM hash */
1331 r.in.user_handle = &user_handle;
1332 r.in.lm_present = 1;
1333 r.in.old_lm_crypted = &hash1;
1334 r.in.new_lm_crypted = &hash2;
1335 /* Break the NT hash */
1337 r.in.nt_present = 1;
1338 r.in.old_nt_crypted = &hash3;
1339 r.in.new_nt_crypted = &hash4;
1340 r.in.cross1_present = 1;
1341 r.in.nt_cross = &hash5;
1342 r.in.cross2_present = 1;
1343 r.in.lm_cross = &hash6;
1345 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1346 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1347 "expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash");
1349 /* Unbreak the NT hash */
1352 r.in.user_handle = &user_handle;
1353 r.in.lm_present = 1;
1354 r.in.old_lm_crypted = &hash1;
1355 r.in.new_lm_crypted = &hash2;
1356 r.in.nt_present = 1;
1357 r.in.old_nt_crypted = &hash3;
1358 r.in.new_nt_crypted = &hash4;
1359 r.in.cross1_present = 1;
1360 r.in.nt_cross = &hash5;
1361 r.in.cross2_present = 1;
1362 /* Break the LM cross */
1364 r.in.lm_cross = &hash6;
1366 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1367 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1368 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status));
1372 /* Unbreak the LM cross */
1375 r.in.user_handle = &user_handle;
1376 r.in.lm_present = 1;
1377 r.in.old_lm_crypted = &hash1;
1378 r.in.new_lm_crypted = &hash2;
1379 r.in.nt_present = 1;
1380 r.in.old_nt_crypted = &hash3;
1381 r.in.new_nt_crypted = &hash4;
1382 r.in.cross1_present = 1;
1383 /* Break the NT cross */
1385 r.in.nt_cross = &hash5;
1386 r.in.cross2_present = 1;
1387 r.in.lm_cross = &hash6;
1389 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1390 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1391 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status));
1395 /* Unbreak the NT cross */
1399 /* Reset the hashes to not broken values */
1400 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1401 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1402 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1403 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1404 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1405 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1407 r.in.user_handle = &user_handle;
1408 r.in.lm_present = 1;
1409 r.in.old_lm_crypted = &hash1;
1410 r.in.new_lm_crypted = &hash2;
1411 r.in.nt_present = 1;
1412 r.in.old_nt_crypted = &hash3;
1413 r.in.new_nt_crypted = &hash4;
1414 r.in.cross1_present = 1;
1415 r.in.nt_cross = &hash5;
1416 r.in.cross2_present = 0;
1417 r.in.lm_cross = NULL;
1419 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1420 if (NT_STATUS_IS_OK(status)) {
1422 *password = newpass;
1423 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1424 printf("ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(status));
1429 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1431 E_md4hash(oldpass, old_nt_hash);
1432 E_md4hash(newpass, new_nt_hash);
1433 E_deshash(oldpass, old_lm_hash);
1434 E_deshash(newpass, new_lm_hash);
1437 /* Reset the hashes to not broken values */
1438 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1439 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1440 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1441 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1442 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1443 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1445 r.in.user_handle = &user_handle;
1446 r.in.lm_present = 1;
1447 r.in.old_lm_crypted = &hash1;
1448 r.in.new_lm_crypted = &hash2;
1449 r.in.nt_present = 1;
1450 r.in.old_nt_crypted = &hash3;
1451 r.in.new_nt_crypted = &hash4;
1452 r.in.cross1_present = 0;
1453 r.in.nt_cross = NULL;
1454 r.in.cross2_present = 1;
1455 r.in.lm_cross = &hash6;
1457 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1458 if (NT_STATUS_IS_OK(status)) {
1460 *password = newpass;
1461 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1462 printf("ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status));
1467 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1469 E_md4hash(oldpass, old_nt_hash);
1470 E_md4hash(newpass, new_nt_hash);
1471 E_deshash(oldpass, old_lm_hash);
1472 E_deshash(newpass, new_lm_hash);
1475 /* Reset the hashes to not broken values */
1476 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1477 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1478 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1479 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1480 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1481 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1483 r.in.user_handle = &user_handle;
1484 r.in.lm_present = 1;
1485 r.in.old_lm_crypted = &hash1;
1486 r.in.new_lm_crypted = &hash2;
1487 r.in.nt_present = 1;
1488 r.in.old_nt_crypted = &hash3;
1489 r.in.new_nt_crypted = &hash4;
1490 r.in.cross1_present = 1;
1491 r.in.nt_cross = &hash5;
1492 r.in.cross2_present = 1;
1493 r.in.lm_cross = &hash6;
1495 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1496 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1497 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1498 } else if (!NT_STATUS_IS_OK(status)) {
1499 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1503 *password = newpass;
1506 r.in.user_handle = &user_handle;
1507 r.in.lm_present = 1;
1508 r.in.old_lm_crypted = &hash1;
1509 r.in.new_lm_crypted = &hash2;
1510 r.in.nt_present = 1;
1511 r.in.old_nt_crypted = &hash3;
1512 r.in.new_nt_crypted = &hash4;
1513 r.in.cross1_present = 1;
1514 r.in.nt_cross = &hash5;
1515 r.in.cross2_present = 1;
1516 r.in.lm_cross = &hash6;
1519 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1520 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1521 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1522 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1523 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status));
1529 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
1537 static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
1538 const char *acct_name,
1539 struct policy_handle *handle, char **password)
1542 struct samr_OemChangePasswordUser2 r;
1544 struct samr_Password lm_verifier;
1545 struct samr_CryptPassword lm_pass;
1546 struct lsa_AsciiString server, account, account_bad;
1549 uint8_t old_lm_hash[16], new_lm_hash[16];
1551 struct samr_GetDomPwInfo dom_pw_info;
1552 struct samr_PwInfo info;
1553 int policy_min_pw_len = 0;
1555 struct lsa_String domain_name;
1557 domain_name.string = "";
1558 dom_pw_info.in.domain_name = &domain_name;
1559 dom_pw_info.out.info = &info;
1561 torture_comment(tctx, "Testing OemChangePasswordUser2\n");
1563 torture_assert(tctx, *password != NULL,
1564 "Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?");
1566 oldpass = *password;
1568 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
1569 if (NT_STATUS_IS_OK(status)) {
1570 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
1573 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1575 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1576 account.string = acct_name;
1578 E_deshash(oldpass, old_lm_hash);
1579 E_deshash(newpass, new_lm_hash);
1581 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1582 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1583 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1585 r.in.server = &server;
1586 r.in.account = &account;
1587 r.in.password = &lm_pass;
1588 r.in.hash = &lm_verifier;
1590 /* Break the verification */
1591 lm_verifier.hash[0]++;
1593 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1595 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1596 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1597 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1602 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1603 /* Break the old password */
1605 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1606 /* unbreak it for the next operation */
1608 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1610 r.in.server = &server;
1611 r.in.account = &account;
1612 r.in.password = &lm_pass;
1613 r.in.hash = &lm_verifier;
1615 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1617 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1618 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1619 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1624 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1625 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1627 r.in.server = &server;
1628 r.in.account = &account;
1629 r.in.password = &lm_pass;
1632 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1634 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1635 && !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1636 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
1641 /* This shouldn't be a valid name */
1642 account_bad.string = TEST_ACCOUNT_NAME "XX";
1643 r.in.account = &account_bad;
1645 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1647 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1648 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
1653 /* This shouldn't be a valid name */
1654 account_bad.string = TEST_ACCOUNT_NAME "XX";
1655 r.in.account = &account_bad;
1656 r.in.password = &lm_pass;
1657 r.in.hash = &lm_verifier;
1659 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1661 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1662 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1667 /* This shouldn't be a valid name */
1668 account_bad.string = TEST_ACCOUNT_NAME "XX";
1669 r.in.account = &account_bad;
1670 r.in.password = NULL;
1671 r.in.hash = &lm_verifier;
1673 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1675 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1676 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
1681 E_deshash(oldpass, old_lm_hash);
1682 E_deshash(newpass, new_lm_hash);
1684 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1685 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1686 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1688 r.in.server = &server;
1689 r.in.account = &account;
1690 r.in.password = &lm_pass;
1691 r.in.hash = &lm_verifier;
1693 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1694 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1695 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1696 } else if (!NT_STATUS_IS_OK(status)) {
1697 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
1700 *password = newpass;
1707 static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
1708 const char *acct_name,
1710 char *newpass, bool allow_password_restriction)
1713 struct samr_ChangePasswordUser2 r;
1715 struct lsa_String server, account;
1716 struct samr_CryptPassword nt_pass, lm_pass;
1717 struct samr_Password nt_verifier, lm_verifier;
1719 uint8_t old_nt_hash[16], new_nt_hash[16];
1720 uint8_t old_lm_hash[16], new_lm_hash[16];
1722 struct samr_GetDomPwInfo dom_pw_info;
1723 struct samr_PwInfo info;
1725 struct lsa_String domain_name;
1727 domain_name.string = "";
1728 dom_pw_info.in.domain_name = &domain_name;
1729 dom_pw_info.out.info = &info;
1731 torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name);
1733 torture_assert(tctx, *password != NULL,
1734 "Failing ChangePasswordUser2 as old password was NULL. Previous test failed?");
1735 oldpass = *password;
1738 int policy_min_pw_len = 0;
1739 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
1740 if (NT_STATUS_IS_OK(status)) {
1741 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
1744 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1747 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1748 init_lsa_String(&account, acct_name);
1750 E_md4hash(oldpass, old_nt_hash);
1751 E_md4hash(newpass, new_nt_hash);
1753 E_deshash(oldpass, old_lm_hash);
1754 E_deshash(newpass, new_lm_hash);
1756 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
1757 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1758 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1760 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1761 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1762 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1764 r.in.server = &server;
1765 r.in.account = &account;
1766 r.in.nt_password = &nt_pass;
1767 r.in.nt_verifier = &nt_verifier;
1769 r.in.lm_password = &lm_pass;
1770 r.in.lm_verifier = &lm_verifier;
1772 status = dcerpc_samr_ChangePasswordUser2(p, tctx, &r);
1773 if (allow_password_restriction && NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1774 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1775 } else if (!NT_STATUS_IS_OK(status)) {
1776 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
1779 *password = newpass;
1786 bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tctx,
1787 const char *account_string,
1788 int policy_min_pw_len,
1790 const char *newpass,
1791 NTTIME last_password_change,
1792 bool handle_reject_reason)
1795 struct samr_ChangePasswordUser3 r;
1797 struct lsa_String server, account, account_bad;
1798 struct samr_CryptPassword nt_pass, lm_pass;
1799 struct samr_Password nt_verifier, lm_verifier;
1801 uint8_t old_nt_hash[16], new_nt_hash[16];
1802 uint8_t old_lm_hash[16], new_lm_hash[16];
1804 struct samr_DomInfo1 *dominfo = NULL;
1805 struct samr_ChangeReject *reject = NULL;
1807 torture_comment(tctx, "Testing ChangePasswordUser3\n");
1809 if (newpass == NULL) {
1811 if (policy_min_pw_len == 0) {
1812 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1814 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len);
1816 } while (check_password_quality(newpass) == false);
1818 torture_comment(tctx, "Using password '%s'\n", newpass);
1821 torture_assert(tctx, *password != NULL,
1822 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
1824 oldpass = *password;
1825 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1826 init_lsa_String(&account, account_string);
1828 E_md4hash(oldpass, old_nt_hash);
1829 E_md4hash(newpass, new_nt_hash);
1831 E_deshash(oldpass, old_lm_hash);
1832 E_deshash(newpass, new_lm_hash);
1834 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1835 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1836 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1838 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1839 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1840 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1842 /* Break the verification */
1843 nt_verifier.hash[0]++;
1845 r.in.server = &server;
1846 r.in.account = &account;
1847 r.in.nt_password = &nt_pass;
1848 r.in.nt_verifier = &nt_verifier;
1850 r.in.lm_password = &lm_pass;
1851 r.in.lm_verifier = &lm_verifier;
1852 r.in.password3 = NULL;
1853 r.out.dominfo = &dominfo;
1854 r.out.reject = &reject;
1856 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1857 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1858 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1859 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1864 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1865 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1866 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1868 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1869 /* Break the NT hash */
1871 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1872 /* Unbreak it again */
1874 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1876 r.in.server = &server;
1877 r.in.account = &account;
1878 r.in.nt_password = &nt_pass;
1879 r.in.nt_verifier = &nt_verifier;
1881 r.in.lm_password = &lm_pass;
1882 r.in.lm_verifier = &lm_verifier;
1883 r.in.password3 = NULL;
1884 r.out.dominfo = &dominfo;
1885 r.out.reject = &reject;
1887 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1888 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1889 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1890 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1895 /* This shouldn't be a valid name */
1896 init_lsa_String(&account_bad, talloc_asprintf(tctx, "%sXX", account_string));
1898 r.in.account = &account_bad;
1899 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1900 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1901 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
1906 E_md4hash(oldpass, old_nt_hash);
1907 E_md4hash(newpass, new_nt_hash);
1909 E_deshash(oldpass, old_lm_hash);
1910 E_deshash(newpass, new_lm_hash);
1912 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1913 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1914 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.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 = &lm_pass;
1926 r.in.lm_verifier = &lm_verifier;
1927 r.in.password3 = NULL;
1928 r.out.dominfo = &dominfo;
1929 r.out.reject = &reject;
1931 unix_to_nt_time(&t, time(NULL));
1933 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1935 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1938 && handle_reject_reason
1939 && (!null_nttime(last_password_change) || !dominfo->min_password_age)) {
1940 if (dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
1942 if (reject && (reject->reason != SAMR_REJECT_OTHER)) {
1943 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1944 SAMR_REJECT_OTHER, reject->reason);
1949 /* We tested the order of precendence which is as follows:
1958 if ((dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
1959 (last_password_change + dominfo->min_password_age > t)) {
1961 if (reject->reason != SAMR_REJECT_OTHER) {
1962 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1963 SAMR_REJECT_OTHER, reject->reason);
1967 } else if ((dominfo->min_password_length > 0) &&
1968 (strlen(newpass) < dominfo->min_password_length)) {
1970 if (reject->reason != SAMR_REJECT_TOO_SHORT) {
1971 printf("expected SAMR_REJECT_TOO_SHORT (%d), got %d\n",
1972 SAMR_REJECT_TOO_SHORT, reject->reason);
1976 } else if ((dominfo->password_history_length > 0) &&
1977 strequal(oldpass, newpass)) {
1979 if (reject->reason != SAMR_REJECT_IN_HISTORY) {
1980 printf("expected SAMR_REJECT_IN_HISTORY (%d), got %d\n",
1981 SAMR_REJECT_IN_HISTORY, reject->reason);
1984 } else if (dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
1986 if (reject->reason != SAMR_REJECT_COMPLEXITY) {
1987 printf("expected SAMR_REJECT_COMPLEXITY (%d), got %d\n",
1988 SAMR_REJECT_COMPLEXITY, reject->reason);
1994 if (reject->reason == SAMR_REJECT_TOO_SHORT) {
1995 /* retry with adjusted size */
1996 return test_ChangePasswordUser3(p, tctx, account_string,
1997 dominfo->min_password_length,
1998 password, NULL, 0, false);
2002 } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2003 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2004 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2005 SAMR_REJECT_OTHER, reject->reason);
2008 /* Perhaps the server has a 'min password age' set? */
2011 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3");
2012 *password = talloc_strdup(tctx, newpass);
2018 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_context *tctx,
2019 const char *account_string,
2020 struct policy_handle *handle,
2024 struct samr_ChangePasswordUser3 r;
2025 struct samr_SetUserInfo s;
2026 union samr_UserInfo u;
2027 DATA_BLOB session_key;
2028 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
2029 uint8_t confounder[16];
2030 struct MD5Context ctx;
2033 struct lsa_String server, account;
2034 struct samr_CryptPassword nt_pass;
2035 struct samr_Password nt_verifier;
2036 DATA_BLOB new_random_pass;
2039 uint8_t old_nt_hash[16], new_nt_hash[16];
2041 struct samr_DomInfo1 *dominfo = NULL;
2042 struct samr_ChangeReject *reject = NULL;
2044 new_random_pass = samr_very_rand_pass(tctx, 128);
2046 torture_assert(tctx, *password != NULL,
2047 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2049 oldpass = *password;
2050 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2051 init_lsa_String(&account, account_string);
2053 s.in.user_handle = handle;
2059 u.info25.info.fields_present = SAMR_FIELD_PASSWORD;
2061 set_pw_in_buffer(u.info25.password.data, &new_random_pass);
2063 status = dcerpc_fetch_session_key(p, &session_key);
2064 if (!NT_STATUS_IS_OK(status)) {
2065 printf("SetUserInfo level %u - no session key - %s\n",
2066 s.in.level, nt_errstr(status));
2070 generate_random_buffer((uint8_t *)confounder, 16);
2073 MD5Update(&ctx, confounder, 16);
2074 MD5Update(&ctx, session_key.data, session_key.length);
2075 MD5Final(confounded_session_key.data, &ctx);
2077 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
2078 memcpy(&u.info25.password.data[516], confounder, 16);
2080 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
2082 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
2083 if (!NT_STATUS_IS_OK(status)) {
2084 printf("SetUserInfo level %u failed - %s\n",
2085 s.in.level, nt_errstr(status));
2089 torture_comment(tctx, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
2091 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2093 new_random_pass = samr_very_rand_pass(tctx, 128);
2095 mdfour(new_nt_hash, new_random_pass.data, new_random_pass.length);
2097 set_pw_in_buffer(nt_pass.data, &new_random_pass);
2098 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2099 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2101 r.in.server = &server;
2102 r.in.account = &account;
2103 r.in.nt_password = &nt_pass;
2104 r.in.nt_verifier = &nt_verifier;
2106 r.in.lm_password = NULL;
2107 r.in.lm_verifier = NULL;
2108 r.in.password3 = NULL;
2109 r.out.dominfo = &dominfo;
2110 r.out.reject = &reject;
2112 unix_to_nt_time(&t, time(NULL));
2114 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2116 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2117 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2118 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2119 SAMR_REJECT_OTHER, reject->reason);
2122 /* Perhaps the server has a 'min password age' set? */
2124 } else if (!NT_STATUS_IS_OK(status)) {
2125 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
2129 newpass = samr_rand_pass(tctx, 128);
2131 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2133 E_md4hash(newpass, new_nt_hash);
2135 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2136 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2137 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2139 r.in.server = &server;
2140 r.in.account = &account;
2141 r.in.nt_password = &nt_pass;
2142 r.in.nt_verifier = &nt_verifier;
2144 r.in.lm_password = NULL;
2145 r.in.lm_verifier = NULL;
2146 r.in.password3 = NULL;
2147 r.out.dominfo = &dominfo;
2148 r.out.reject = &reject;
2150 unix_to_nt_time(&t, time(NULL));
2152 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2154 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2155 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2156 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2157 SAMR_REJECT_OTHER, reject->reason);
2160 /* Perhaps the server has a 'min password age' set? */
2163 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3 (on second random password)");
2164 *password = talloc_strdup(tctx, newpass);
2171 static bool test_GetMembersInAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2172 struct policy_handle *alias_handle)
2174 struct samr_GetMembersInAlias r;
2175 struct lsa_SidArray sids;
2178 torture_comment(tctx, "Testing GetMembersInAlias\n");
2180 r.in.alias_handle = alias_handle;
2183 status = dcerpc_samr_GetMembersInAlias(p, tctx, &r);
2184 torture_assert_ntstatus_ok(tctx, status, "GetMembersInAlias");
2189 static bool test_AddMemberToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2190 struct policy_handle *alias_handle,
2191 const struct dom_sid *domain_sid)
2193 struct samr_AddAliasMember r;
2194 struct samr_DeleteAliasMember d;
2196 struct dom_sid *sid;
2198 sid = dom_sid_add_rid(tctx, domain_sid, 512);
2200 torture_comment(tctx, "testing AddAliasMember\n");
2201 r.in.alias_handle = alias_handle;
2204 status = dcerpc_samr_AddAliasMember(p, tctx, &r);
2205 torture_assert_ntstatus_ok(tctx, status, "AddAliasMember");
2207 d.in.alias_handle = alias_handle;
2210 status = dcerpc_samr_DeleteAliasMember(p, tctx, &d);
2211 torture_assert_ntstatus_ok(tctx, status, "DelAliasMember");
2216 static bool test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2217 struct policy_handle *alias_handle)
2219 struct samr_AddMultipleMembersToAlias a;
2220 struct samr_RemoveMultipleMembersFromAlias r;
2222 struct lsa_SidArray sids;
2224 torture_comment(tctx, "testing AddMultipleMembersToAlias\n");
2225 a.in.alias_handle = alias_handle;
2229 sids.sids = talloc_array(tctx, struct lsa_SidPtr, 3);
2231 sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2232 sids.sids[1].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-2");
2233 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-3");
2235 status = dcerpc_samr_AddMultipleMembersToAlias(p, tctx, &a);
2236 torture_assert_ntstatus_ok(tctx, status, "AddMultipleMembersToAlias");
2239 torture_comment(tctx, "testing RemoveMultipleMembersFromAlias\n");
2240 r.in.alias_handle = alias_handle;
2243 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2244 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2246 /* strange! removing twice doesn't give any error */
2247 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2248 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2250 /* but removing an alias that isn't there does */
2251 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-4");
2253 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2254 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, "RemoveMultipleMembersFromAlias");
2259 static bool test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2260 struct policy_handle *user_handle)
2262 struct samr_TestPrivateFunctionsUser r;
2265 torture_comment(tctx, "Testing TestPrivateFunctionsUser\n");
2267 r.in.user_handle = user_handle;
2269 status = dcerpc_samr_TestPrivateFunctionsUser(p, tctx, &r);
2270 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsUser");
2275 static bool test_QueryUserInfo_pwdlastset(struct dcerpc_pipe *p,
2276 struct torture_context *tctx,
2277 struct policy_handle *handle,
2282 uint16_t levels[] = { /* 3, */ 5, 21 };
2284 NTTIME pwdlastset3 = 0;
2285 NTTIME pwdlastset5 = 0;
2286 NTTIME pwdlastset21 = 0;
2288 torture_comment(tctx, "Testing QueryUserInfo%s level 5 and 21 call ",
2289 use_info2 ? "2":"");
2291 for (i=0; i<ARRAY_SIZE(levels); i++) {
2293 struct samr_QueryUserInfo r;
2294 struct samr_QueryUserInfo2 r2;
2295 union samr_UserInfo *info;
2298 r2.in.user_handle = handle;
2299 r2.in.level = levels[i];
2300 r2.out.info = &info;
2301 status = dcerpc_samr_QueryUserInfo2(p, tctx, &r2);
2304 r.in.user_handle = handle;
2305 r.in.level = levels[i];
2307 status = dcerpc_samr_QueryUserInfo(p, tctx, &r);
2310 if (!NT_STATUS_IS_OK(status) &&
2311 !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
2312 printf("QueryUserInfo%s level %u failed - %s\n",
2313 use_info2 ? "2":"", levels[i], nt_errstr(status));
2317 switch (levels[i]) {
2319 pwdlastset3 = info->info3.last_password_change;
2322 pwdlastset5 = info->info5.last_password_change;
2325 pwdlastset21 = info->info21.last_password_change;
2331 /* torture_assert_int_equal(tctx, pwdlastset3, pwdlastset5,
2332 "pwdlastset mixup"); */
2333 torture_assert_int_equal(tctx, pwdlastset5, pwdlastset21,
2334 "pwdlastset mixup");
2336 *pwdlastset = pwdlastset21;
2338 torture_comment(tctx, "(pwdlastset: %lld)\n", *pwdlastset);
2343 static bool test_SetPassword_level(struct dcerpc_pipe *p,
2344 struct torture_context *tctx,
2345 struct policy_handle *handle,
2347 uint32_t fields_present,
2348 uint8_t password_expired,
2349 NTSTATUS expected_error,
2352 bool use_queryinfo2,
2355 const char *fields = NULL;
2362 fields = talloc_asprintf(tctx, "(fields_present: 0x%08x)",
2369 torture_comment(tctx, "Testing SetUserInfo%s level %d call "
2370 "(password_expired: %d) %s\n",
2371 use_setinfo2 ? "2":"", level, password_expired,
2372 fields ? fields : "");
2380 if (!test_SetUserPass_level_ex(p, tctx, handle, level,
2393 if (!test_QueryUserInfo_pwdlastset(p, tctx, handle,
2402 static bool test_SetPassword_pwdlastset(struct dcerpc_pipe *p,
2403 struct torture_context *tctx,
2404 uint32_t acct_flags,
2405 struct policy_handle *handle,
2411 bool set_levels[] = { false, true };
2412 bool query_levels[] = { false, true };
2416 uint8_t password_expired_nonzero;
2417 uint32_t fields_present;
2426 .password_expired_nonzero = 1,
2427 .fields_present = SAMR_FIELD_EXPIRED_FLAG
2430 .password_expired_nonzero = 1,
2431 .fields_present = SAMR_FIELD_LAST_PWD_CHANGE,
2432 .set_error = NT_STATUS_ACCESS_DENIED
2437 .password_expired_nonzero = 1,
2438 .fields_present = SAMR_FIELD_PASSWORD |
2439 SAMR_FIELD_PASSWORD2 |
2440 SAMR_FIELD_LAST_PWD_CHANGE,
2441 .query_info2 = false,
2442 .set_error = NT_STATUS_ACCESS_DENIED
2448 .password_expired_nonzero = 1,
2449 .fields_present = SAMR_FIELD_EXPIRED_FLAG
2452 .password_expired_nonzero = 1,
2453 .fields_present = SAMR_FIELD_LAST_PWD_CHANGE,
2454 .set_error = NT_STATUS_ACCESS_DENIED
2457 .password_expired_nonzero = 1,
2458 .fields_present = SAMR_FIELD_LAST_PWD_CHANGE |
2459 SAMR_FIELD_PASSWORD |
2460 SAMR_FIELD_PASSWORD2,
2461 .set_error = NT_STATUS_ACCESS_DENIED
2464 .password_expired_nonzero = 1,
2465 .fields_present = SAMR_FIELD_LAST_PWD_CHANGE |
2466 SAMR_FIELD_PASSWORD |
2467 SAMR_FIELD_PASSWORD2 |
2468 SAMR_FIELD_EXPIRED_FLAG,
2469 .set_error = NT_STATUS_ACCESS_DENIED
2472 .password_expired_nonzero = 1,
2473 .fields_present = SAMR_FIELD_PASSWORD |
2474 SAMR_FIELD_PASSWORD2 |
2475 SAMR_FIELD_EXPIRED_FLAG
2478 .password_expired_nonzero = 1,
2479 .fields_present = SAMR_FIELD_PASSWORD |
2480 SAMR_FIELD_PASSWORD2
2486 .password_expired_nonzero = 1
2489 .password_expired_nonzero = 24
2495 .password_expired_nonzero = 1,
2496 .fields_present = SAMR_FIELD_LAST_PWD_CHANGE,
2497 .set_error = NT_STATUS_ACCESS_DENIED
2500 .password_expired_nonzero = 1,
2501 .fields_present = SAMR_FIELD_EXPIRED_FLAG,
2504 .password_expired_nonzero = 1,
2505 .fields_present = SAMR_FIELD_PASSWORD |
2506 SAMR_FIELD_PASSWORD2 |
2507 SAMR_FIELD_EXPIRED_FLAG
2510 .password_expired_nonzero = 1,
2511 .fields_present = SAMR_FIELD_PASSWORD |
2512 SAMR_FIELD_PASSWORD2
2518 .password_expired_nonzero = 1
2521 .password_expired_nonzero = 24
2525 if (torture_setting_bool(tctx, "samba3", false)) {
2527 printf("Samba3 has second granularity, setting delay to: %d\n",
2532 for (i=0; i<ARRAY_SIZE(pwd_tests); i++) {
2533 for (s=0; s<ARRAY_SIZE(set_levels); s++) {
2534 for (q=0; q<ARRAY_SIZE(query_levels); q++) {
2536 NTTIME pwdlastset_old = 0;
2537 NTTIME pwdlastset_new = 0;
2541 torture_comment(tctx, "------------------------------\n"
2542 "Testing pwdLastSet attribute for flags: 0x%08x "
2543 "(s: %d (l: %d), q: %d)\n",
2544 acct_flags, s, pwd_tests[i].level, q);
2546 if (!test_SetPassword_level(p, tctx, handle,
2548 pwd_tests[i].fields_present,
2549 pwd_tests[i].password_expired_nonzero, /* will set pwdlast to 0 */
2550 pwd_tests[i].set_error,
2558 if (!NT_STATUS_IS_OK(pwd_tests[i].set_error)) {
2559 /* skipping on expected failure */
2563 /* pwdlastset must be 0 afterwards, except for a level 23 and 25
2564 * set without the SAMR_FIELD_EXPIRED_FLAG */
2566 switch (pwd_tests[i].level) {
2569 if ((pwdlastset_new != 0) &&
2570 !(pwd_tests[i].fields_present & SAMR_FIELD_EXPIRED_FLAG)) {
2571 torture_comment(tctx, "not considering a non-0 "
2572 "pwdLastSet as a an error as the "
2573 "SAMR_FIELD_EXPIRED_FLAG has not "
2578 if (pwdlastset_new != 0) {
2579 torture_warning(tctx, "pwdLastSet test failed: "
2580 "expected pwdLastSet 0 but got %lld\n",
2591 if (!test_SetPassword_level(p, tctx, handle, pwd_tests[i].level,
2592 pwd_tests[i].fields_present,
2594 /* will normally update (increase) the pwdlast */
2595 pwd_tests[i].set_error,
2604 /* pwdlastset must not be 0 afterwards and must be larger then
2607 if (pwdlastset_old >= pwdlastset_new) {
2608 torture_warning(tctx, "pwdLastSet test failed: "
2609 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
2610 pwdlastset_old, pwdlastset_new);
2613 if (pwdlastset_new == 0) {
2614 torture_warning(tctx, "pwdLastSet test failed: "
2615 "expected non-0 pwdlastset, got: %lld\n",
2619 pwdlastset_old = pwdlastset_new;
2625 if (!test_SetPassword_level(p, tctx, handle, pwd_tests[i].level,
2626 pwd_tests[i].fields_present,
2627 pwd_tests[i].password_expired_nonzero,
2628 pwd_tests[i].set_error,
2636 if (pwdlastset_old == pwdlastset_new) {
2637 torture_warning(tctx, "pwdLastSet test failed: "
2638 "expected last pwdlastset (%lld) != new pwdlastset (%lld)\n",
2639 pwdlastset_old, pwdlastset_new);
2643 /* pwdlastset must be 0 afterwards, except for a level 23 and 25
2644 * set without the SAMR_FIELD_EXPIRED_FLAG */
2646 switch (pwd_tests[i].level) {
2649 if ((pwdlastset_new != 0) &&
2650 !(pwd_tests[i].fields_present & SAMR_FIELD_EXPIRED_FLAG)) {
2654 if (pwdlastset_new != 0) {
2655 torture_warning(tctx, "pwdLastSet test failed: "
2656 "expected pwdLastSet 0, got %lld\n",
2669 static bool test_user_ops(struct dcerpc_pipe *p,
2670 struct torture_context *tctx,
2671 struct policy_handle *user_handle,
2672 struct policy_handle *domain_handle,
2673 uint32_t base_acct_flags,
2674 const char *base_acct_name, enum torture_samr_choice which_ops)
2676 char *password = NULL;
2677 struct samr_QueryUserInfo q;
2678 union samr_UserInfo *info;
2684 const uint32_t password_fields[] = {
2685 SAMR_FIELD_PASSWORD,
2686 SAMR_FIELD_PASSWORD2,
2687 SAMR_FIELD_PASSWORD | SAMR_FIELD_PASSWORD2,
2691 status = test_LookupName(p, tctx, domain_handle, base_acct_name, &rid);
2692 if (!NT_STATUS_IS_OK(status)) {
2696 switch (which_ops) {
2697 case TORTURE_SAMR_USER_ATTRIBUTES:
2698 if (!test_QuerySecurity(p, tctx, user_handle)) {
2702 if (!test_QueryUserInfo(p, tctx, user_handle)) {
2706 if (!test_QueryUserInfo2(p, tctx, user_handle)) {
2710 if (!test_SetUserInfo(p, tctx, user_handle, base_acct_flags,
2715 if (!test_GetUserPwInfo(p, tctx, user_handle)) {
2719 if (!test_TestPrivateFunctionsUser(p, tctx, user_handle)) {
2723 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
2727 case TORTURE_SAMR_PASSWORDS:
2728 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
2729 char simple_pass[9];
2730 char *v = generate_random_str(tctx, 1);
2732 ZERO_STRUCT(simple_pass);
2733 memset(simple_pass, *v, sizeof(simple_pass) - 1);
2735 printf("Testing machine account password policy rules\n");
2737 /* Workstation trust accounts don't seem to need to honour password quality policy */
2738 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
2742 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
2746 /* reset again, to allow another 'user' password change */
2747 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
2751 /* Try a 'short' password */
2752 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
2756 /* Try a compleatly random password */
2757 if (!test_ChangePasswordRandomBytes(p, tctx, base_acct_name, user_handle, &password)) {
2762 /* test last password change timestamp behaviour */
2763 if (!test_SetPassword_pwdlastset(p, tctx, user_handle, &password)) {
2767 for (i = 0; password_fields[i]; i++) {
2768 if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
2772 /* check it was set right */
2773 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
2778 for (i = 0; password_fields[i]; i++) {
2779 if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
2783 /* check it was set right */
2784 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
2789 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
2793 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
2797 q.in.user_handle = user_handle;
2801 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
2802 if (!NT_STATUS_IS_OK(status)) {
2803 printf("QueryUserInfo level %u failed - %s\n",
2804 q.in.level, nt_errstr(status));
2807 uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
2808 if ((info->info5.acct_flags) != expected_flags) {
2809 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2810 info->info5.acct_flags,
2814 if (info->info5.rid != rid) {
2815 printf("QuerUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
2816 info->info5.rid, rid);
2822 case TORTURE_SAMR_OTHER:
2823 /* We just need the account to exist */
2829 static bool test_alias_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
2830 struct policy_handle *alias_handle,
2831 const struct dom_sid *domain_sid)
2835 if (!test_QuerySecurity(p, tctx, alias_handle)) {
2839 if (!test_QueryAliasInfo(p, tctx, alias_handle)) {
2843 if (!test_SetAliasInfo(p, tctx, alias_handle)) {
2847 if (!test_AddMemberToAlias(p, tctx, alias_handle, domain_sid)) {
2851 if (torture_setting_bool(tctx, "samba4", false)) {
2852 printf("skipping MultipleMembers Alias tests against Samba4\n");
2856 if (!test_AddMultipleMembersToAlias(p, tctx, alias_handle)) {
2864 static bool test_DeleteUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2865 struct policy_handle *user_handle)
2867 struct samr_DeleteUser d;
2869 torture_comment(tctx, "Testing DeleteUser\n");
2871 d.in.user_handle = user_handle;
2872 d.out.user_handle = user_handle;
2874 status = dcerpc_samr_DeleteUser(p, tctx, &d);
2875 torture_assert_ntstatus_ok(tctx, status, "DeleteUser");
2880 bool test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2881 struct policy_handle *handle, const char *name)
2884 struct samr_DeleteUser d;
2885 struct policy_handle user_handle;
2888 status = test_LookupName(p, mem_ctx, handle, name, &rid);
2889 if (!NT_STATUS_IS_OK(status)) {
2893 status = test_OpenUser_byname(p, mem_ctx, handle, name, &user_handle);
2894 if (!NT_STATUS_IS_OK(status)) {
2898 d.in.user_handle = &user_handle;
2899 d.out.user_handle = &user_handle;
2900 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
2901 if (!NT_STATUS_IS_OK(status)) {
2908 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
2913 static bool test_DeleteGroup_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2914 struct policy_handle *handle, const char *name)
2917 struct samr_OpenGroup r;
2918 struct samr_DeleteDomainGroup d;
2919 struct policy_handle group_handle;
2922 status = test_LookupName(p, mem_ctx, handle, name, &rid);
2923 if (!NT_STATUS_IS_OK(status)) {
2927 r.in.domain_handle = handle;
2928 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2930 r.out.group_handle = &group_handle;
2931 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
2932 if (!NT_STATUS_IS_OK(status)) {
2936 d.in.group_handle = &group_handle;
2937 d.out.group_handle = &group_handle;
2938 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
2939 if (!NT_STATUS_IS_OK(status)) {
2946 printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
2951 static bool test_DeleteAlias_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2952 struct policy_handle *domain_handle, const char *name)
2955 struct samr_OpenAlias r;
2956 struct samr_DeleteDomAlias d;
2957 struct policy_handle alias_handle;
2960 printf("testing DeleteAlias_byname\n");
2962 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
2963 if (!NT_STATUS_IS_OK(status)) {
2967 r.in.domain_handle = domain_handle;
2968 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2970 r.out.alias_handle = &alias_handle;
2971 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
2972 if (!NT_STATUS_IS_OK(status)) {
2976 d.in.alias_handle = &alias_handle;
2977 d.out.alias_handle = &alias_handle;
2978 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
2979 if (!NT_STATUS_IS_OK(status)) {
2986 printf("DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
2990 static bool test_DeleteAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2991 struct policy_handle *alias_handle)
2993 struct samr_DeleteDomAlias d;
2996 printf("Testing DeleteAlias\n");
2998 d.in.alias_handle = alias_handle;
2999 d.out.alias_handle = alias_handle;
3001 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
3002 if (!NT_STATUS_IS_OK(status)) {
3003 printf("DeleteAlias failed - %s\n", nt_errstr(status));
3010 static bool test_CreateAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
3011 struct policy_handle *domain_handle,
3012 struct policy_handle *alias_handle,
3013 const struct dom_sid *domain_sid)
3016 struct samr_CreateDomAlias r;
3017 struct lsa_String name;
3021 init_lsa_String(&name, TEST_ALIASNAME);
3022 r.in.domain_handle = domain_handle;
3023 r.in.alias_name = &name;
3024 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3025 r.out.alias_handle = alias_handle;
3028 printf("Testing CreateAlias (%s)\n", r.in.alias_name->string);
3030 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
3032 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
3033 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
3034 printf("Server correctly refused create of '%s'\n", r.in.alias_name->string);
3037 printf("Server should have refused create of '%s', got %s instead\n", r.in.alias_name->string,
3043 if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
3044 if (!test_DeleteAlias_byname(p, tctx, domain_handle, r.in.alias_name->string)) {
3047 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
3050 if (!NT_STATUS_IS_OK(status)) {
3051 printf("CreateAlias failed - %s\n", nt_errstr(status));
3055 if (!test_alias_ops(p, tctx, alias_handle, domain_sid)) {
3062 static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3063 const char *acct_name,
3064 struct policy_handle *domain_handle, char **password)
3072 if (!test_ChangePasswordUser(p, mem_ctx, acct_name, domain_handle, password)) {
3076 if (!test_ChangePasswordUser2(p, mem_ctx, acct_name, password, 0, true)) {
3080 if (!test_OemChangePasswordUser2(p, mem_ctx, acct_name, domain_handle, password)) {
3084 /* test what happens when setting the old password again */
3085 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, *password, 0, true)) {
3090 char simple_pass[9];
3091 char *v = generate_random_str(mem_ctx, 1);
3093 ZERO_STRUCT(simple_pass);
3094 memset(simple_pass, *v, sizeof(simple_pass) - 1);
3096 /* test what happens when picking a simple password */
3097 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, simple_pass, 0, true)) {
3102 /* set samr_SetDomainInfo level 1 with min_length 5 */
3104 struct samr_QueryDomainInfo r;
3105 union samr_DomainInfo *info = NULL;
3106 struct samr_SetDomainInfo s;
3107 uint16_t len_old, len;
3108 uint32_t pwd_prop_old;
3109 int64_t min_pwd_age_old;
3114 r.in.domain_handle = domain_handle;
3118 printf("testing samr_QueryDomainInfo level 1\n");
3119 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
3120 if (!NT_STATUS_IS_OK(status)) {
3124 s.in.domain_handle = domain_handle;
3128 /* remember the old min length, so we can reset it */
3129 len_old = s.in.info->info1.min_password_length;
3130 s.in.info->info1.min_password_length = len;
3131 pwd_prop_old = s.in.info->info1.password_properties;
3132 /* turn off password complexity checks for this test */
3133 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
3135 min_pwd_age_old = s.in.info->info1.min_password_age;
3136 s.in.info->info1.min_password_age = 0;
3138 printf("testing samr_SetDomainInfo level 1\n");
3139 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
3140 if (!NT_STATUS_IS_OK(status)) {