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_PASSWORDS_PWDLASTSET,
43 TORTURE_SAMR_USER_ATTRIBUTES,
47 static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
48 struct policy_handle *handle);
50 static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
51 struct policy_handle *handle);
53 static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
54 struct policy_handle *handle);
56 static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
57 const char *acct_name,
58 struct policy_handle *domain_handle, char **password);
60 static void init_lsa_String(struct lsa_String *string, const char *s)
65 static void init_lsa_BinaryString(struct lsa_BinaryString *string, const char *s, uint32_t length)
67 string->length = length;
68 string->size = length;
69 string->array = (uint16_t *)discard_const(s);
72 bool test_samr_handle_Close(struct dcerpc_pipe *p, struct torture_context *tctx,
73 struct policy_handle *handle)
79 r.out.handle = handle;
81 status = dcerpc_samr_Close(p, tctx, &r);
82 torture_assert_ntstatus_ok(tctx, status, "Close");
87 static bool test_Shutdown(struct dcerpc_pipe *p, struct torture_context *tctx,
88 struct policy_handle *handle)
91 struct samr_Shutdown r;
93 if (!torture_setting_bool(tctx, "dangerous", false)) {
94 torture_skip(tctx, "samr_Shutdown disabled - enable dangerous tests to use\n");
98 r.in.connect_handle = handle;
100 torture_comment(tctx, "testing samr_Shutdown\n");
102 status = dcerpc_samr_Shutdown(p, tctx, &r);
103 torture_assert_ntstatus_ok(tctx, status, "samr_Shutdown");
108 static bool test_SetDsrmPassword(struct dcerpc_pipe *p, struct torture_context *tctx,
109 struct policy_handle *handle)
112 struct samr_SetDsrmPassword r;
113 struct lsa_String string;
114 struct samr_Password hash;
116 if (!torture_setting_bool(tctx, "dangerous", false)) {
117 torture_skip(tctx, "samr_SetDsrmPassword disabled - enable dangerous tests to use");
120 E_md4hash("TeSTDSRM123", hash.hash);
122 init_lsa_String(&string, "Administrator");
128 torture_comment(tctx, "testing samr_SetDsrmPassword\n");
130 status = dcerpc_samr_SetDsrmPassword(p, tctx, &r);
131 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_SUPPORTED, "samr_SetDsrmPassword");
137 static bool test_QuerySecurity(struct dcerpc_pipe *p,
138 struct torture_context *tctx,
139 struct policy_handle *handle)
142 struct samr_QuerySecurity r;
143 struct samr_SetSecurity s;
144 struct sec_desc_buf *sdbuf = NULL;
146 r.in.handle = handle;
148 r.out.sdbuf = &sdbuf;
150 status = dcerpc_samr_QuerySecurity(p, tctx, &r);
151 torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
153 torture_assert(tctx, sdbuf != NULL, "sdbuf is NULL");
155 s.in.handle = handle;
159 if (torture_setting_bool(tctx, "samba4", false)) {
160 torture_skip(tctx, "skipping SetSecurity test against Samba4\n");
163 status = dcerpc_samr_SetSecurity(p, tctx, &s);
164 torture_assert_ntstatus_ok(tctx, status, "SetSecurity");
166 status = dcerpc_samr_QuerySecurity(p, tctx, &r);
167 torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
173 static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
174 struct policy_handle *handle, uint32_t base_acct_flags,
175 const char *base_account_name)
178 struct samr_SetUserInfo s;
179 struct samr_SetUserInfo2 s2;
180 struct samr_QueryUserInfo q;
181 struct samr_QueryUserInfo q0;
182 union samr_UserInfo u;
183 union samr_UserInfo *info;
185 const char *test_account_name;
187 uint32_t user_extra_flags = 0;
188 if (base_acct_flags == ACB_NORMAL) {
189 /* When created, accounts are expired by default */
190 user_extra_flags = ACB_PW_EXPIRED;
193 s.in.user_handle = handle;
196 s2.in.user_handle = handle;
199 q.in.user_handle = handle;
203 #define TESTCALL(call, r) \
204 status = dcerpc_samr_ ##call(p, tctx, &r); \
205 if (!NT_STATUS_IS_OK(status)) { \
206 torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
207 r.in.level, nt_errstr(status), __location__); \
212 #define STRING_EQUAL(s1, s2, field) \
213 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
214 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
215 #field, s2, __location__); \
220 #define MEM_EQUAL(s1, s2, length, field) \
221 if ((s1 && !s2) || (s2 && !s1) || memcmp(s1, s2, length)) { \
222 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
223 #field, (const char *)s2, __location__); \
228 #define INT_EQUAL(i1, i2, field) \
230 torture_comment(tctx, "Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \
231 #field, (unsigned long long)i2, (unsigned long long)i1, __location__); \
236 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
237 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
239 TESTCALL(QueryUserInfo, q) \
241 s2.in.level = lvl1; \
244 ZERO_STRUCT(u.info21); \
245 u.info21.fields_present = fpval; \
247 init_lsa_String(&u.info ## lvl1.field1, value); \
248 TESTCALL(SetUserInfo, s) \
249 TESTCALL(SetUserInfo2, s2) \
250 init_lsa_String(&u.info ## lvl1.field1, ""); \
251 TESTCALL(QueryUserInfo, q); \
253 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
255 TESTCALL(QueryUserInfo, q) \
257 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
260 #define TEST_USERINFO_BINARYSTRING(lvl1, field1, lvl2, field2, value, fpval) do { \
261 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
263 TESTCALL(QueryUserInfo, q) \
265 s2.in.level = lvl1; \
268 ZERO_STRUCT(u.info21); \
269 u.info21.fields_present = fpval; \
271 init_lsa_BinaryString(&u.info ## lvl1.field1, value, strlen(value)); \
272 TESTCALL(SetUserInfo, s) \
273 TESTCALL(SetUserInfo2, s2) \
274 init_lsa_BinaryString(&u.info ## lvl1.field1, "", 1); \
275 TESTCALL(QueryUserInfo, q); \
277 MEM_EQUAL(u.info ## lvl1.field1.array, value, strlen(value), field1); \
279 TESTCALL(QueryUserInfo, q) \
281 MEM_EQUAL(u.info ## lvl2.field2.array, value, strlen(value), field2); \
284 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
285 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
287 TESTCALL(QueryUserInfo, q) \
289 s2.in.level = lvl1; \
292 uint8_t *bits = u.info21.logon_hours.bits; \
293 ZERO_STRUCT(u.info21); \
294 if (fpval == SAMR_FIELD_LOGON_HOURS) { \
295 u.info21.logon_hours.units_per_week = 168; \
296 u.info21.logon_hours.bits = bits; \
298 u.info21.fields_present = fpval; \
300 u.info ## lvl1.field1 = value; \
301 TESTCALL(SetUserInfo, s) \
302 TESTCALL(SetUserInfo2, s2) \
303 u.info ## lvl1.field1 = 0; \
304 TESTCALL(QueryUserInfo, q); \
306 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
308 TESTCALL(QueryUserInfo, q) \
310 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
313 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
314 TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
318 do { TESTCALL(QueryUserInfo, q0) } while (0);
320 TEST_USERINFO_STRING(2, comment, 1, comment, "xx2-1 comment", 0);
321 TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
322 TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment",
325 test_account_name = talloc_asprintf(tctx, "%sxx7-1", base_account_name);
326 TEST_USERINFO_STRING(7, account_name, 1, account_name, base_account_name, 0);
327 test_account_name = talloc_asprintf(tctx, "%sxx7-3", base_account_name);
328 TEST_USERINFO_STRING(7, account_name, 3, account_name, base_account_name, 0);
329 test_account_name = talloc_asprintf(tctx, "%sxx7-5", base_account_name);
330 TEST_USERINFO_STRING(7, account_name, 5, account_name, base_account_name, 0);
331 test_account_name = talloc_asprintf(tctx, "%sxx7-6", base_account_name);
332 TEST_USERINFO_STRING(7, account_name, 6, account_name, base_account_name, 0);
333 test_account_name = talloc_asprintf(tctx, "%sxx7-7", base_account_name);
334 TEST_USERINFO_STRING(7, account_name, 7, account_name, base_account_name, 0);
335 test_account_name = talloc_asprintf(tctx, "%sxx7-21", base_account_name);
336 TEST_USERINFO_STRING(7, account_name, 21, account_name, base_account_name, 0);
337 test_account_name = base_account_name;
338 TEST_USERINFO_STRING(21, account_name, 21, account_name, base_account_name,
339 SAMR_FIELD_ACCOUNT_NAME);
341 TEST_USERINFO_STRING(6, full_name, 1, full_name, "xx6-1 full_name", 0);
342 TEST_USERINFO_STRING(6, full_name, 3, full_name, "xx6-3 full_name", 0);
343 TEST_USERINFO_STRING(6, full_name, 5, full_name, "xx6-5 full_name", 0);
344 TEST_USERINFO_STRING(6, full_name, 6, full_name, "xx6-6 full_name", 0);
345 TEST_USERINFO_STRING(6, full_name, 8, full_name, "xx6-8 full_name", 0);
346 TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
347 TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
348 TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name",
349 SAMR_FIELD_FULL_NAME);
351 TEST_USERINFO_STRING(6, full_name, 1, full_name, "", 0);
352 TEST_USERINFO_STRING(6, full_name, 3, full_name, "", 0);
353 TEST_USERINFO_STRING(6, full_name, 5, full_name, "", 0);
354 TEST_USERINFO_STRING(6, full_name, 6, full_name, "", 0);
355 TEST_USERINFO_STRING(6, full_name, 8, full_name, "", 0);
356 TEST_USERINFO_STRING(6, full_name, 21, full_name, "", 0);
357 TEST_USERINFO_STRING(8, full_name, 21, full_name, "", 0);
358 TEST_USERINFO_STRING(21, full_name, 21, full_name, "",
359 SAMR_FIELD_FULL_NAME);
361 TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
362 TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
363 TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
364 TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script",
365 SAMR_FIELD_LOGON_SCRIPT);
367 TEST_USERINFO_STRING(12, profile_path, 3, profile_path, "xx12-3 profile_path", 0);
368 TEST_USERINFO_STRING(12, profile_path, 5, profile_path, "xx12-5 profile_path", 0);
369 TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
370 TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path",
371 SAMR_FIELD_PROFILE_PATH);
373 TEST_USERINFO_STRING(10, home_directory, 3, home_directory, "xx10-3 home_directory", 0);
374 TEST_USERINFO_STRING(10, home_directory, 5, home_directory, "xx10-5 home_directory", 0);
375 TEST_USERINFO_STRING(10, home_directory, 21, home_directory, "xx10-21 home_directory", 0);
376 TEST_USERINFO_STRING(21, home_directory, 21, home_directory, "xx21-21 home_directory",
377 SAMR_FIELD_HOME_DIRECTORY);
378 TEST_USERINFO_STRING(21, home_directory, 10, home_directory, "xx21-10 home_directory",
379 SAMR_FIELD_HOME_DIRECTORY);
381 TEST_USERINFO_STRING(10, home_drive, 3, home_drive, "xx10-3 home_drive", 0);
382 TEST_USERINFO_STRING(10, home_drive, 5, home_drive, "xx10-5 home_drive", 0);
383 TEST_USERINFO_STRING(10, home_drive, 21, home_drive, "xx10-21 home_drive", 0);
384 TEST_USERINFO_STRING(21, home_drive, 21, home_drive, "xx21-21 home_drive",
385 SAMR_FIELD_HOME_DRIVE);
386 TEST_USERINFO_STRING(21, home_drive, 10, home_drive, "xx21-10 home_drive",
387 SAMR_FIELD_HOME_DRIVE);
389 TEST_USERINFO_STRING(13, description, 1, description, "xx13-1 description", 0);
390 TEST_USERINFO_STRING(13, description, 5, description, "xx13-5 description", 0);
391 TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
392 TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description",
393 SAMR_FIELD_DESCRIPTION);
395 TEST_USERINFO_STRING(14, workstations, 3, workstations, "14workstation3", 0);
396 TEST_USERINFO_STRING(14, workstations, 5, workstations, "14workstation4", 0);
397 TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
398 TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21",
399 SAMR_FIELD_WORKSTATIONS);
400 TEST_USERINFO_STRING(21, workstations, 3, workstations, "21workstation3",
401 SAMR_FIELD_WORKSTATIONS);
402 TEST_USERINFO_STRING(21, workstations, 5, workstations, "21workstation5",
403 SAMR_FIELD_WORKSTATIONS);
404 TEST_USERINFO_STRING(21, workstations, 14, workstations, "21workstation14",
405 SAMR_FIELD_WORKSTATIONS);
407 TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
408 TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "xx21-21 parameters",
409 SAMR_FIELD_PARAMETERS);
410 TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "xx21-20 parameters",
411 SAMR_FIELD_PARAMETERS);
413 TEST_USERINFO_INT(2, country_code, 2, country_code, __LINE__, 0);
414 TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
415 TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__,
416 SAMR_FIELD_COUNTRY_CODE);
417 TEST_USERINFO_INT(21, country_code, 2, country_code, __LINE__,
418 SAMR_FIELD_COUNTRY_CODE);
420 TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
421 TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__,
422 SAMR_FIELD_CODE_PAGE);
423 TEST_USERINFO_INT(21, code_page, 2, code_page, __LINE__,
424 SAMR_FIELD_CODE_PAGE);
426 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, __LINE__, 0);
427 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, __LINE__, 0);
428 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, __LINE__,
429 SAMR_FIELD_ACCT_EXPIRY);
430 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, __LINE__,
431 SAMR_FIELD_ACCT_EXPIRY);
432 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, __LINE__,
433 SAMR_FIELD_ACCT_EXPIRY);
435 TEST_USERINFO_INT(4, logon_hours.bits[3], 3, logon_hours.bits[3], 1, 0);
436 TEST_USERINFO_INT(4, logon_hours.bits[3], 5, logon_hours.bits[3], 2, 0);
437 TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
438 TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4,
439 SAMR_FIELD_LOGON_HOURS);
441 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
442 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
443 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
445 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
446 (base_acct_flags | ACB_DISABLED),
447 (base_acct_flags | ACB_DISABLED | user_extra_flags),
450 /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
451 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
452 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
453 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
455 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
456 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
457 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
461 /* The 'autolock' flag doesn't stick - check this */
462 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
463 (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK),
464 (base_acct_flags | ACB_DISABLED | user_extra_flags),
467 /* Removing the 'disabled' flag doesn't stick - check this */
468 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
470 (base_acct_flags | ACB_DISABLED | user_extra_flags),
473 /* The 'store plaintext' flag does stick */
474 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
475 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED),
476 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags),
478 /* The 'use DES' flag does stick */
479 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
480 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY),
481 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags),
483 /* The 'don't require kerberos pre-authentication flag does stick */
484 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
485 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH),
486 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags),
488 /* The 'no kerberos PAC required' flag sticks */
489 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
490 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD),
491 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags),
494 TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags,
495 (base_acct_flags | ACB_DISABLED),
496 (base_acct_flags | ACB_DISABLED | user_extra_flags),
497 SAMR_FIELD_ACCT_FLAGS);
500 /* these fail with win2003 - it appears you can't set the primary gid?
501 the set succeeds, but the gid isn't changed. Very weird! */
502 TEST_USERINFO_INT(9, primary_gid, 1, primary_gid, 513);
503 TEST_USERINFO_INT(9, primary_gid, 3, primary_gid, 513);
504 TEST_USERINFO_INT(9, primary_gid, 5, primary_gid, 513);
505 TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
512 generate a random password for password change tests
514 static char *samr_rand_pass_silent(TALLOC_CTX *mem_ctx, int min_len)
516 size_t len = MAX(8, min_len) + (random() % 6);
517 char *s = generate_random_str(mem_ctx, len);
521 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
523 char *s = samr_rand_pass_silent(mem_ctx, min_len);
524 printf("Generated password '%s'\n", s);
530 generate a random password for password change tests
532 static DATA_BLOB samr_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
535 DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
536 generate_random_buffer(password.data, password.length);
538 for (i=0; i < len; i++) {
539 if (((uint16_t *)password.data)[i] == 0) {
540 ((uint16_t *)password.data)[i] = 1;
548 generate a random password for password change tests (fixed length)
550 static char *samr_rand_pass_fixed_len(TALLOC_CTX *mem_ctx, int len)
552 char *s = generate_random_str(mem_ctx, len);
553 printf("Generated password '%s'\n", s);
557 static bool test_SetUserPass(struct dcerpc_pipe *p, struct torture_context *tctx,
558 struct policy_handle *handle, char **password)
561 struct samr_SetUserInfo s;
562 union samr_UserInfo u;
564 DATA_BLOB session_key;
566 struct samr_GetUserPwInfo pwp;
567 struct samr_PwInfo info;
568 int policy_min_pw_len = 0;
569 pwp.in.user_handle = handle;
570 pwp.out.info = &info;
572 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
573 if (NT_STATUS_IS_OK(status)) {
574 policy_min_pw_len = pwp.out.info->min_password_length;
576 newpass = samr_rand_pass(tctx, policy_min_pw_len);
578 s.in.user_handle = handle;
582 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
583 u.info24.password_expired = 0;
585 status = dcerpc_fetch_session_key(p, &session_key);
586 if (!NT_STATUS_IS_OK(status)) {
587 printf("SetUserInfo level %u - no session key - %s\n",
588 s.in.level, nt_errstr(status));
592 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
594 torture_comment(tctx, "Testing SetUserInfo level 24 (set password)\n");
596 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
597 if (!NT_STATUS_IS_OK(status)) {
598 printf("SetUserInfo level %u failed - %s\n",
599 s.in.level, nt_errstr(status));
609 static bool test_SetUserPass_23(struct dcerpc_pipe *p, struct torture_context *tctx,
610 struct policy_handle *handle, uint32_t fields_present,
614 struct samr_SetUserInfo s;
615 union samr_UserInfo u;
617 DATA_BLOB session_key;
619 struct samr_GetUserPwInfo pwp;
620 struct samr_PwInfo info;
621 int policy_min_pw_len = 0;
622 pwp.in.user_handle = handle;
623 pwp.out.info = &info;
625 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
626 if (NT_STATUS_IS_OK(status)) {
627 policy_min_pw_len = pwp.out.info->min_password_length;
629 newpass = samr_rand_pass(tctx, policy_min_pw_len);
631 s.in.user_handle = handle;
637 u.info23.info.fields_present = fields_present;
639 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
641 status = dcerpc_fetch_session_key(p, &session_key);
642 if (!NT_STATUS_IS_OK(status)) {
643 printf("SetUserInfo level %u - no session key - %s\n",
644 s.in.level, nt_errstr(status));
648 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
650 torture_comment(tctx, "Testing SetUserInfo level 23 (set password)\n");
652 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
653 if (!NT_STATUS_IS_OK(status)) {
654 printf("SetUserInfo level %u failed - %s\n",
655 s.in.level, nt_errstr(status));
661 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
663 status = dcerpc_fetch_session_key(p, &session_key);
664 if (!NT_STATUS_IS_OK(status)) {
665 printf("SetUserInfo level %u - no session key - %s\n",
666 s.in.level, nt_errstr(status));
670 /* This should break the key nicely */
671 session_key.length--;
672 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
674 torture_comment(tctx, "Testing SetUserInfo level 23 (set password) with wrong password\n");
676 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
677 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
678 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
679 s.in.level, nt_errstr(status));
687 static bool test_SetUserPassEx(struct dcerpc_pipe *p, struct torture_context *tctx,
688 struct policy_handle *handle, bool makeshort,
692 struct samr_SetUserInfo s;
693 union samr_UserInfo u;
695 DATA_BLOB session_key;
696 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
697 uint8_t confounder[16];
699 struct MD5Context ctx;
700 struct samr_GetUserPwInfo pwp;
701 struct samr_PwInfo info;
702 int policy_min_pw_len = 0;
703 pwp.in.user_handle = handle;
704 pwp.out.info = &info;
706 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
707 if (NT_STATUS_IS_OK(status)) {
708 policy_min_pw_len = pwp.out.info->min_password_length;
710 if (makeshort && policy_min_pw_len) {
711 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len - 1);
713 newpass = samr_rand_pass(tctx, policy_min_pw_len);
716 s.in.user_handle = handle;
720 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
721 u.info26.password_expired = 0;
723 status = dcerpc_fetch_session_key(p, &session_key);
724 if (!NT_STATUS_IS_OK(status)) {
725 printf("SetUserInfo level %u - no session key - %s\n",
726 s.in.level, nt_errstr(status));
730 generate_random_buffer((uint8_t *)confounder, 16);
733 MD5Update(&ctx, confounder, 16);
734 MD5Update(&ctx, session_key.data, session_key.length);
735 MD5Final(confounded_session_key.data, &ctx);
737 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
738 memcpy(&u.info26.password.data[516], confounder, 16);
740 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex)\n");
742 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
743 if (!NT_STATUS_IS_OK(status)) {
744 printf("SetUserInfo level %u failed - %s\n",
745 s.in.level, nt_errstr(status));
751 /* This should break the key nicely */
752 confounded_session_key.data[0]++;
754 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
755 memcpy(&u.info26.password.data[516], confounder, 16);
757 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
759 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
760 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
761 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
762 s.in.level, nt_errstr(status));
771 static bool test_SetUserPass_25(struct dcerpc_pipe *p, struct torture_context *tctx,
772 struct policy_handle *handle, uint32_t fields_present,
776 struct samr_SetUserInfo s;
777 union samr_UserInfo u;
779 DATA_BLOB session_key;
780 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
781 struct MD5Context ctx;
782 uint8_t confounder[16];
784 struct samr_GetUserPwInfo pwp;
785 struct samr_PwInfo info;
786 int policy_min_pw_len = 0;
787 pwp.in.user_handle = handle;
788 pwp.out.info = &info;
790 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
791 if (NT_STATUS_IS_OK(status)) {
792 policy_min_pw_len = pwp.out.info->min_password_length;
794 newpass = samr_rand_pass(tctx, policy_min_pw_len);
796 s.in.user_handle = handle;
802 u.info25.info.fields_present = fields_present;
804 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
806 status = dcerpc_fetch_session_key(p, &session_key);
807 if (!NT_STATUS_IS_OK(status)) {
808 printf("SetUserInfo level %u - no session key - %s\n",
809 s.in.level, nt_errstr(status));
813 generate_random_buffer((uint8_t *)confounder, 16);
816 MD5Update(&ctx, confounder, 16);
817 MD5Update(&ctx, session_key.data, session_key.length);
818 MD5Final(confounded_session_key.data, &ctx);
820 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
821 memcpy(&u.info25.password.data[516], confounder, 16);
823 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex)\n");
825 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
826 if (!NT_STATUS_IS_OK(status)) {
827 printf("SetUserInfo level %u failed - %s\n",
828 s.in.level, nt_errstr(status));
834 /* This should break the key nicely */
835 confounded_session_key.data[0]++;
837 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
838 memcpy(&u.info25.password.data[516], confounder, 16);
840 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
842 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
843 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
844 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
845 s.in.level, nt_errstr(status));
852 static bool test_SetUserPass_level_ex(struct dcerpc_pipe *p,
853 struct torture_context *tctx,
854 struct policy_handle *handle,
856 uint32_t fields_present,
857 char **password, uint8_t password_expired,
858 bool use_setinfo2, NTSTATUS expected_error)
861 struct samr_SetUserInfo s;
862 struct samr_SetUserInfo2 s2;
863 union samr_UserInfo u;
865 DATA_BLOB session_key;
866 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
867 struct MD5Context ctx;
868 uint8_t confounder[16];
870 struct samr_GetUserPwInfo pwp;
871 struct samr_PwInfo info;
872 int policy_min_pw_len = 0;
873 const char *comment = NULL;
875 pwp.in.user_handle = handle;
876 pwp.out.info = &info;
878 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
879 if (NT_STATUS_IS_OK(status)) {
880 policy_min_pw_len = pwp.out.info->min_password_length;
882 newpass = samr_rand_pass_silent(tctx, policy_min_pw_len);
885 s2.in.user_handle = handle;
889 s.in.user_handle = handle;
894 if (fields_present & SAMR_FIELD_COMMENT) {
895 comment = talloc_asprintf(tctx, "comment: %d\n", time(NULL));
902 u.info21.fields_present = fields_present;
903 u.info21.password_expired = password_expired;
904 u.info21.comment.string = comment;
908 u.info23.info.fields_present = fields_present;
909 u.info23.info.password_expired = password_expired;
910 u.info23.info.comment.string = comment;
912 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
916 u.info24.password_expired = password_expired;
918 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
922 u.info25.info.fields_present = fields_present;
923 u.info25.info.password_expired = password_expired;
924 u.info25.info.comment.string = comment;
926 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
930 u.info26.password_expired = password_expired;
932 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
937 status = dcerpc_fetch_session_key(p, &session_key);
938 if (!NT_STATUS_IS_OK(status)) {
939 printf("SetUserInfo level %u - no session key - %s\n",
940 s.in.level, nt_errstr(status));
944 generate_random_buffer((uint8_t *)confounder, 16);
947 MD5Update(&ctx, confounder, 16);
948 MD5Update(&ctx, session_key.data, session_key.length);
949 MD5Final(confounded_session_key.data, &ctx);
953 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
956 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
959 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
960 memcpy(&u.info25.password.data[516], confounder, 16);
963 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
964 memcpy(&u.info26.password.data[516], confounder, 16);
969 status = dcerpc_samr_SetUserInfo2(p, tctx, &s2);
971 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
974 if (!NT_STATUS_IS_OK(expected_error)) {
976 torture_assert_ntstatus_equal(tctx,
978 expected_error, "SetUserInfo2 failed");
980 torture_assert_ntstatus_equal(tctx,
982 expected_error, "SetUserInfo failed");
987 if (!NT_STATUS_IS_OK(status)) {
988 printf("SetUserInfo%s level %u failed - %s\n",
989 use_setinfo2 ? "2":"", level, nt_errstr(status));
1000 static bool test_SetAliasInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1001 struct policy_handle *handle)
1004 struct samr_SetAliasInfo r;
1005 struct samr_QueryAliasInfo q;
1006 union samr_AliasInfo *info;
1007 uint16_t levels[] = {2, 3};
1011 /* Ignoring switch level 1, as that includes the number of members for the alias
1012 * and setting this to a wrong value might have negative consequences
1015 for (i=0;i<ARRAY_SIZE(levels);i++) {
1016 torture_comment(tctx, "Testing SetAliasInfo level %u\n", levels[i]);
1018 r.in.alias_handle = handle;
1019 r.in.level = levels[i];
1020 r.in.info = talloc(tctx, union samr_AliasInfo);
1021 switch (r.in.level) {
1022 case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
1023 case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
1024 "Test Description, should test I18N as well"); break;
1025 case ALIASINFOALL: printf("ALIASINFOALL ignored\n"); break;
1028 status = dcerpc_samr_SetAliasInfo(p, tctx, &r);
1029 if (!NT_STATUS_IS_OK(status)) {
1030 printf("SetAliasInfo level %u failed - %s\n",
1031 levels[i], nt_errstr(status));
1035 q.in.alias_handle = handle;
1036 q.in.level = levels[i];
1039 status = dcerpc_samr_QueryAliasInfo(p, tctx, &q);
1040 if (!NT_STATUS_IS_OK(status)) {
1041 printf("QueryAliasInfo level %u failed - %s\n",
1042 levels[i], nt_errstr(status));
1050 static bool test_GetGroupsForUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1051 struct policy_handle *user_handle)
1053 struct samr_GetGroupsForUser r;
1054 struct samr_RidWithAttributeArray *rids = NULL;
1057 torture_comment(tctx, "testing GetGroupsForUser\n");
1059 r.in.user_handle = user_handle;
1062 status = dcerpc_samr_GetGroupsForUser(p, tctx, &r);
1063 torture_assert_ntstatus_ok(tctx, status, "GetGroupsForUser");
1069 static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1070 struct lsa_String *domain_name)
1073 struct samr_GetDomPwInfo r;
1074 struct samr_PwInfo info;
1076 r.in.domain_name = domain_name;
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");
1084 r.in.domain_name->string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1085 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1087 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1088 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1090 r.in.domain_name->string = "\\\\__NONAME__";
1091 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1093 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1094 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1096 r.in.domain_name->string = "\\\\Builtin";
1097 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1099 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1100 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1105 static bool test_GetUserPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1106 struct policy_handle *handle)
1109 struct samr_GetUserPwInfo r;
1110 struct samr_PwInfo info;
1112 torture_comment(tctx, "Testing GetUserPwInfo\n");
1114 r.in.user_handle = handle;
1117 status = dcerpc_samr_GetUserPwInfo(p, tctx, &r);
1118 torture_assert_ntstatus_ok(tctx, status, "GetUserPwInfo");
1123 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, struct torture_context *tctx,
1124 struct policy_handle *domain_handle, const char *name,
1128 struct samr_LookupNames n;
1129 struct lsa_String sname[2];
1130 struct samr_Ids rids, types;
1132 init_lsa_String(&sname[0], name);
1134 n.in.domain_handle = domain_handle;
1138 n.out.types = &types;
1139 status = dcerpc_samr_LookupNames(p, tctx, &n);
1140 if (NT_STATUS_IS_OK(status)) {
1141 *rid = n.out.rids->ids[0];
1146 init_lsa_String(&sname[1], "xxNONAMExx");
1148 status = dcerpc_samr_LookupNames(p, tctx, &n);
1149 if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
1150 printf("LookupNames[2] failed - %s\n", nt_errstr(status));
1151 if (NT_STATUS_IS_OK(status)) {
1152 return NT_STATUS_UNSUCCESSFUL;
1158 status = dcerpc_samr_LookupNames(p, tctx, &n);
1159 if (!NT_STATUS_IS_OK(status)) {
1160 printf("LookupNames[0] failed - %s\n", nt_errstr(status));
1164 init_lsa_String(&sname[0], "xxNONAMExx");
1166 status = dcerpc_samr_LookupNames(p, tctx, &n);
1167 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1168 printf("LookupNames[1 bad name] failed - %s\n", nt_errstr(status));
1169 if (NT_STATUS_IS_OK(status)) {
1170 return NT_STATUS_UNSUCCESSFUL;
1175 init_lsa_String(&sname[0], "xxNONAMExx");
1176 init_lsa_String(&sname[1], "xxNONAME2xx");
1178 status = dcerpc_samr_LookupNames(p, tctx, &n);
1179 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1180 printf("LookupNames[2 bad names] failed - %s\n", nt_errstr(status));
1181 if (NT_STATUS_IS_OK(status)) {
1182 return NT_STATUS_UNSUCCESSFUL;
1187 return NT_STATUS_OK;
1190 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1191 struct policy_handle *domain_handle,
1192 const char *name, struct policy_handle *user_handle)
1195 struct samr_OpenUser r;
1198 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
1199 if (!NT_STATUS_IS_OK(status)) {
1203 r.in.domain_handle = domain_handle;
1204 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1206 r.out.user_handle = user_handle;
1207 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
1208 if (!NT_STATUS_IS_OK(status)) {
1209 printf("OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(status));
1216 static bool test_ChangePasswordNT3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1217 struct policy_handle *handle)
1220 struct samr_ChangePasswordUser r;
1222 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1223 struct policy_handle user_handle;
1224 char *oldpass = "test";
1225 char *newpass = "test2";
1226 uint8_t old_nt_hash[16], new_nt_hash[16];
1227 uint8_t old_lm_hash[16], new_lm_hash[16];
1229 status = test_OpenUser_byname(p, mem_ctx, handle, "testuser", &user_handle);
1230 if (!NT_STATUS_IS_OK(status)) {
1234 printf("Testing ChangePasswordUser for user 'testuser'\n");
1236 printf("old password: %s\n", oldpass);
1237 printf("new password: %s\n", newpass);
1239 E_md4hash(oldpass, old_nt_hash);
1240 E_md4hash(newpass, new_nt_hash);
1241 E_deshash(oldpass, old_lm_hash);
1242 E_deshash(newpass, new_lm_hash);
1244 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1245 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1246 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1247 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1248 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1249 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1251 r.in.handle = &user_handle;
1252 r.in.lm_present = 1;
1253 r.in.old_lm_crypted = &hash1;
1254 r.in.new_lm_crypted = &hash2;
1255 r.in.nt_present = 1;
1256 r.in.old_nt_crypted = &hash3;
1257 r.in.new_nt_crypted = &hash4;
1258 r.in.cross1_present = 1;
1259 r.in.nt_cross = &hash5;
1260 r.in.cross2_present = 1;
1261 r.in.lm_cross = &hash6;
1263 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1264 if (!NT_STATUS_IS_OK(status)) {
1265 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1269 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1277 static bool test_ChangePasswordUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1278 const char *acct_name,
1279 struct policy_handle *handle, char **password)
1282 struct samr_ChangePasswordUser r;
1284 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1285 struct policy_handle user_handle;
1287 uint8_t old_nt_hash[16], new_nt_hash[16];
1288 uint8_t old_lm_hash[16], new_lm_hash[16];
1289 bool changed = true;
1292 struct samr_GetUserPwInfo pwp;
1293 struct samr_PwInfo info;
1294 int policy_min_pw_len = 0;
1296 status = test_OpenUser_byname(p, tctx, handle, acct_name, &user_handle);
1297 if (!NT_STATUS_IS_OK(status)) {
1300 pwp.in.user_handle = &user_handle;
1301 pwp.out.info = &info;
1303 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1304 if (NT_STATUS_IS_OK(status)) {
1305 policy_min_pw_len = pwp.out.info->min_password_length;
1307 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1309 torture_comment(tctx, "Testing ChangePasswordUser\n");
1311 torture_assert(tctx, *password != NULL,
1312 "Failing ChangePasswordUser as old password was NULL. Previous test failed?");
1314 oldpass = *password;
1316 E_md4hash(oldpass, old_nt_hash);
1317 E_md4hash(newpass, new_nt_hash);
1318 E_deshash(oldpass, old_lm_hash);
1319 E_deshash(newpass, new_lm_hash);
1321 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1322 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1323 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1324 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1325 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1326 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1328 r.in.user_handle = &user_handle;
1329 r.in.lm_present = 1;
1330 /* Break the LM hash */
1332 r.in.old_lm_crypted = &hash1;
1333 r.in.new_lm_crypted = &hash2;
1334 r.in.nt_present = 1;
1335 r.in.old_nt_crypted = &hash3;
1336 r.in.new_nt_crypted = &hash4;
1337 r.in.cross1_present = 1;
1338 r.in.nt_cross = &hash5;
1339 r.in.cross2_present = 1;
1340 r.in.lm_cross = &hash6;
1342 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1343 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1344 "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash");
1346 /* Unbreak the LM hash */
1349 r.in.user_handle = &user_handle;
1350 r.in.lm_present = 1;
1351 r.in.old_lm_crypted = &hash1;
1352 r.in.new_lm_crypted = &hash2;
1353 /* Break the NT hash */
1355 r.in.nt_present = 1;
1356 r.in.old_nt_crypted = &hash3;
1357 r.in.new_nt_crypted = &hash4;
1358 r.in.cross1_present = 1;
1359 r.in.nt_cross = &hash5;
1360 r.in.cross2_present = 1;
1361 r.in.lm_cross = &hash6;
1363 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1364 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1365 "expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash");
1367 /* Unbreak the NT hash */
1370 r.in.user_handle = &user_handle;
1371 r.in.lm_present = 1;
1372 r.in.old_lm_crypted = &hash1;
1373 r.in.new_lm_crypted = &hash2;
1374 r.in.nt_present = 1;
1375 r.in.old_nt_crypted = &hash3;
1376 r.in.new_nt_crypted = &hash4;
1377 r.in.cross1_present = 1;
1378 r.in.nt_cross = &hash5;
1379 r.in.cross2_present = 1;
1380 /* Break the LM cross */
1382 r.in.lm_cross = &hash6;
1384 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1385 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1386 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status));
1390 /* Unbreak the LM cross */
1393 r.in.user_handle = &user_handle;
1394 r.in.lm_present = 1;
1395 r.in.old_lm_crypted = &hash1;
1396 r.in.new_lm_crypted = &hash2;
1397 r.in.nt_present = 1;
1398 r.in.old_nt_crypted = &hash3;
1399 r.in.new_nt_crypted = &hash4;
1400 r.in.cross1_present = 1;
1401 /* Break the NT cross */
1403 r.in.nt_cross = &hash5;
1404 r.in.cross2_present = 1;
1405 r.in.lm_cross = &hash6;
1407 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1408 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1409 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status));
1413 /* Unbreak the NT cross */
1417 /* Reset the hashes to not broken values */
1418 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1419 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1420 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1421 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1422 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1423 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1425 r.in.user_handle = &user_handle;
1426 r.in.lm_present = 1;
1427 r.in.old_lm_crypted = &hash1;
1428 r.in.new_lm_crypted = &hash2;
1429 r.in.nt_present = 1;
1430 r.in.old_nt_crypted = &hash3;
1431 r.in.new_nt_crypted = &hash4;
1432 r.in.cross1_present = 1;
1433 r.in.nt_cross = &hash5;
1434 r.in.cross2_present = 0;
1435 r.in.lm_cross = NULL;
1437 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1438 if (NT_STATUS_IS_OK(status)) {
1440 *password = newpass;
1441 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1442 printf("ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(status));
1447 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1449 E_md4hash(oldpass, old_nt_hash);
1450 E_md4hash(newpass, new_nt_hash);
1451 E_deshash(oldpass, old_lm_hash);
1452 E_deshash(newpass, new_lm_hash);
1455 /* Reset the hashes to not broken values */
1456 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1457 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1458 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1459 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1460 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1461 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1463 r.in.user_handle = &user_handle;
1464 r.in.lm_present = 1;
1465 r.in.old_lm_crypted = &hash1;
1466 r.in.new_lm_crypted = &hash2;
1467 r.in.nt_present = 1;
1468 r.in.old_nt_crypted = &hash3;
1469 r.in.new_nt_crypted = &hash4;
1470 r.in.cross1_present = 0;
1471 r.in.nt_cross = NULL;
1472 r.in.cross2_present = 1;
1473 r.in.lm_cross = &hash6;
1475 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1476 if (NT_STATUS_IS_OK(status)) {
1478 *password = newpass;
1479 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1480 printf("ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status));
1485 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1487 E_md4hash(oldpass, old_nt_hash);
1488 E_md4hash(newpass, new_nt_hash);
1489 E_deshash(oldpass, old_lm_hash);
1490 E_deshash(newpass, new_lm_hash);
1493 /* Reset the hashes to not broken values */
1494 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1495 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1496 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1497 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1498 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1499 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1501 r.in.user_handle = &user_handle;
1502 r.in.lm_present = 1;
1503 r.in.old_lm_crypted = &hash1;
1504 r.in.new_lm_crypted = &hash2;
1505 r.in.nt_present = 1;
1506 r.in.old_nt_crypted = &hash3;
1507 r.in.new_nt_crypted = &hash4;
1508 r.in.cross1_present = 1;
1509 r.in.nt_cross = &hash5;
1510 r.in.cross2_present = 1;
1511 r.in.lm_cross = &hash6;
1513 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1514 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1515 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1516 } else if (!NT_STATUS_IS_OK(status)) {
1517 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1521 *password = newpass;
1524 r.in.user_handle = &user_handle;
1525 r.in.lm_present = 1;
1526 r.in.old_lm_crypted = &hash1;
1527 r.in.new_lm_crypted = &hash2;
1528 r.in.nt_present = 1;
1529 r.in.old_nt_crypted = &hash3;
1530 r.in.new_nt_crypted = &hash4;
1531 r.in.cross1_present = 1;
1532 r.in.nt_cross = &hash5;
1533 r.in.cross2_present = 1;
1534 r.in.lm_cross = &hash6;
1537 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1538 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1539 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1540 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1541 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status));
1547 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
1555 static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
1556 const char *acct_name,
1557 struct policy_handle *handle, char **password)
1560 struct samr_OemChangePasswordUser2 r;
1562 struct samr_Password lm_verifier;
1563 struct samr_CryptPassword lm_pass;
1564 struct lsa_AsciiString server, account, account_bad;
1567 uint8_t old_lm_hash[16], new_lm_hash[16];
1569 struct samr_GetDomPwInfo dom_pw_info;
1570 struct samr_PwInfo info;
1571 int policy_min_pw_len = 0;
1573 struct lsa_String domain_name;
1575 domain_name.string = "";
1576 dom_pw_info.in.domain_name = &domain_name;
1577 dom_pw_info.out.info = &info;
1579 torture_comment(tctx, "Testing OemChangePasswordUser2\n");
1581 torture_assert(tctx, *password != NULL,
1582 "Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?");
1584 oldpass = *password;
1586 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
1587 if (NT_STATUS_IS_OK(status)) {
1588 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
1591 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1593 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1594 account.string = acct_name;
1596 E_deshash(oldpass, old_lm_hash);
1597 E_deshash(newpass, new_lm_hash);
1599 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1600 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1601 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1603 r.in.server = &server;
1604 r.in.account = &account;
1605 r.in.password = &lm_pass;
1606 r.in.hash = &lm_verifier;
1608 /* Break the verification */
1609 lm_verifier.hash[0]++;
1611 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1613 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1614 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1615 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1620 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1621 /* Break the old password */
1623 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1624 /* unbreak it for the next operation */
1626 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1628 r.in.server = &server;
1629 r.in.account = &account;
1630 r.in.password = &lm_pass;
1631 r.in.hash = &lm_verifier;
1633 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1635 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1636 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1637 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1642 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1643 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1645 r.in.server = &server;
1646 r.in.account = &account;
1647 r.in.password = &lm_pass;
1650 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1652 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1653 && !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1654 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
1659 /* This shouldn't be a valid name */
1660 account_bad.string = TEST_ACCOUNT_NAME "XX";
1661 r.in.account = &account_bad;
1663 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1665 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1666 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
1671 /* This shouldn't be a valid name */
1672 account_bad.string = TEST_ACCOUNT_NAME "XX";
1673 r.in.account = &account_bad;
1674 r.in.password = &lm_pass;
1675 r.in.hash = &lm_verifier;
1677 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1679 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1680 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1685 /* This shouldn't be a valid name */
1686 account_bad.string = TEST_ACCOUNT_NAME "XX";
1687 r.in.account = &account_bad;
1688 r.in.password = NULL;
1689 r.in.hash = &lm_verifier;
1691 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1693 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1694 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
1699 E_deshash(oldpass, old_lm_hash);
1700 E_deshash(newpass, new_lm_hash);
1702 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1703 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1704 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1706 r.in.server = &server;
1707 r.in.account = &account;
1708 r.in.password = &lm_pass;
1709 r.in.hash = &lm_verifier;
1711 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1712 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1713 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1714 } else if (!NT_STATUS_IS_OK(status)) {
1715 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
1718 *password = newpass;
1725 static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
1726 const char *acct_name,
1728 char *newpass, bool allow_password_restriction)
1731 struct samr_ChangePasswordUser2 r;
1733 struct lsa_String server, account;
1734 struct samr_CryptPassword nt_pass, lm_pass;
1735 struct samr_Password nt_verifier, lm_verifier;
1737 uint8_t old_nt_hash[16], new_nt_hash[16];
1738 uint8_t old_lm_hash[16], new_lm_hash[16];
1740 struct samr_GetDomPwInfo dom_pw_info;
1741 struct samr_PwInfo info;
1743 struct lsa_String domain_name;
1745 domain_name.string = "";
1746 dom_pw_info.in.domain_name = &domain_name;
1747 dom_pw_info.out.info = &info;
1749 torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name);
1751 torture_assert(tctx, *password != NULL,
1752 "Failing ChangePasswordUser2 as old password was NULL. Previous test failed?");
1753 oldpass = *password;
1756 int policy_min_pw_len = 0;
1757 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
1758 if (NT_STATUS_IS_OK(status)) {
1759 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
1762 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1765 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1766 init_lsa_String(&account, acct_name);
1768 E_md4hash(oldpass, old_nt_hash);
1769 E_md4hash(newpass, new_nt_hash);
1771 E_deshash(oldpass, old_lm_hash);
1772 E_deshash(newpass, new_lm_hash);
1774 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
1775 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1776 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1778 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1779 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1780 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1782 r.in.server = &server;
1783 r.in.account = &account;
1784 r.in.nt_password = &nt_pass;
1785 r.in.nt_verifier = &nt_verifier;
1787 r.in.lm_password = &lm_pass;
1788 r.in.lm_verifier = &lm_verifier;
1790 status = dcerpc_samr_ChangePasswordUser2(p, tctx, &r);
1791 if (allow_password_restriction && NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1792 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1793 } else if (!NT_STATUS_IS_OK(status)) {
1794 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
1797 *password = newpass;
1804 bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tctx,
1805 const char *account_string,
1806 int policy_min_pw_len,
1808 const char *newpass,
1809 NTTIME last_password_change,
1810 bool handle_reject_reason)
1813 struct samr_ChangePasswordUser3 r;
1815 struct lsa_String server, account, account_bad;
1816 struct samr_CryptPassword nt_pass, lm_pass;
1817 struct samr_Password nt_verifier, lm_verifier;
1819 uint8_t old_nt_hash[16], new_nt_hash[16];
1820 uint8_t old_lm_hash[16], new_lm_hash[16];
1822 struct samr_DomInfo1 *dominfo = NULL;
1823 struct samr_ChangeReject *reject = NULL;
1825 torture_comment(tctx, "Testing ChangePasswordUser3\n");
1827 if (newpass == NULL) {
1829 if (policy_min_pw_len == 0) {
1830 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1832 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len);
1834 } while (check_password_quality(newpass) == false);
1836 torture_comment(tctx, "Using password '%s'\n", newpass);
1839 torture_assert(tctx, *password != NULL,
1840 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
1842 oldpass = *password;
1843 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1844 init_lsa_String(&account, account_string);
1846 E_md4hash(oldpass, old_nt_hash);
1847 E_md4hash(newpass, new_nt_hash);
1849 E_deshash(oldpass, old_lm_hash);
1850 E_deshash(newpass, new_lm_hash);
1852 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1853 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1854 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1856 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1857 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1858 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1860 /* Break the verification */
1861 nt_verifier.hash[0]++;
1863 r.in.server = &server;
1864 r.in.account = &account;
1865 r.in.nt_password = &nt_pass;
1866 r.in.nt_verifier = &nt_verifier;
1868 r.in.lm_password = &lm_pass;
1869 r.in.lm_verifier = &lm_verifier;
1870 r.in.password3 = NULL;
1871 r.out.dominfo = &dominfo;
1872 r.out.reject = &reject;
1874 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1875 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1876 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1877 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1882 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1883 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1884 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1886 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1887 /* Break the NT hash */
1889 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1890 /* Unbreak it again */
1892 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1894 r.in.server = &server;
1895 r.in.account = &account;
1896 r.in.nt_password = &nt_pass;
1897 r.in.nt_verifier = &nt_verifier;
1899 r.in.lm_password = &lm_pass;
1900 r.in.lm_verifier = &lm_verifier;
1901 r.in.password3 = NULL;
1902 r.out.dominfo = &dominfo;
1903 r.out.reject = &reject;
1905 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1906 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1907 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1908 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1913 /* This shouldn't be a valid name */
1914 init_lsa_String(&account_bad, talloc_asprintf(tctx, "%sXX", account_string));
1916 r.in.account = &account_bad;
1917 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1918 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1919 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
1924 E_md4hash(oldpass, old_nt_hash);
1925 E_md4hash(newpass, new_nt_hash);
1927 E_deshash(oldpass, old_lm_hash);
1928 E_deshash(newpass, new_lm_hash);
1930 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1931 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1932 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1934 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1935 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1936 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1938 r.in.server = &server;
1939 r.in.account = &account;
1940 r.in.nt_password = &nt_pass;
1941 r.in.nt_verifier = &nt_verifier;
1943 r.in.lm_password = &lm_pass;
1944 r.in.lm_verifier = &lm_verifier;
1945 r.in.password3 = NULL;
1946 r.out.dominfo = &dominfo;
1947 r.out.reject = &reject;
1949 unix_to_nt_time(&t, time(NULL));
1951 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1953 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1956 && handle_reject_reason
1957 && (!null_nttime(last_password_change) || !dominfo->min_password_age)) {
1958 if (dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
1960 if (reject && (reject->reason != SAMR_REJECT_OTHER)) {
1961 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1962 SAMR_REJECT_OTHER, reject->reason);
1967 /* We tested the order of precendence which is as follows:
1976 if ((dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
1977 (last_password_change + dominfo->min_password_age > t)) {
1979 if (reject->reason != SAMR_REJECT_OTHER) {
1980 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1981 SAMR_REJECT_OTHER, reject->reason);
1985 } else if ((dominfo->min_password_length > 0) &&
1986 (strlen(newpass) < dominfo->min_password_length)) {
1988 if (reject->reason != SAMR_REJECT_TOO_SHORT) {
1989 printf("expected SAMR_REJECT_TOO_SHORT (%d), got %d\n",
1990 SAMR_REJECT_TOO_SHORT, reject->reason);
1994 } else if ((dominfo->password_history_length > 0) &&
1995 strequal(oldpass, newpass)) {
1997 if (reject->reason != SAMR_REJECT_IN_HISTORY) {
1998 printf("expected SAMR_REJECT_IN_HISTORY (%d), got %d\n",
1999 SAMR_REJECT_IN_HISTORY, reject->reason);
2002 } else if (dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
2004 if (reject->reason != SAMR_REJECT_COMPLEXITY) {
2005 printf("expected SAMR_REJECT_COMPLEXITY (%d), got %d\n",
2006 SAMR_REJECT_COMPLEXITY, reject->reason);
2012 if (reject->reason == SAMR_REJECT_TOO_SHORT) {
2013 /* retry with adjusted size */
2014 return test_ChangePasswordUser3(p, tctx, account_string,
2015 dominfo->min_password_length,
2016 password, NULL, 0, false);
2020 } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2021 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2022 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2023 SAMR_REJECT_OTHER, reject->reason);
2026 /* Perhaps the server has a 'min password age' set? */
2029 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3");
2030 *password = talloc_strdup(tctx, newpass);
2036 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_context *tctx,
2037 const char *account_string,
2038 struct policy_handle *handle,
2042 struct samr_ChangePasswordUser3 r;
2043 struct samr_SetUserInfo s;
2044 union samr_UserInfo u;
2045 DATA_BLOB session_key;
2046 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
2047 uint8_t confounder[16];
2048 struct MD5Context ctx;
2051 struct lsa_String server, account;
2052 struct samr_CryptPassword nt_pass;
2053 struct samr_Password nt_verifier;
2054 DATA_BLOB new_random_pass;
2057 uint8_t old_nt_hash[16], new_nt_hash[16];
2059 struct samr_DomInfo1 *dominfo = NULL;
2060 struct samr_ChangeReject *reject = NULL;
2062 new_random_pass = samr_very_rand_pass(tctx, 128);
2064 torture_assert(tctx, *password != NULL,
2065 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2067 oldpass = *password;
2068 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2069 init_lsa_String(&account, account_string);
2071 s.in.user_handle = handle;
2077 u.info25.info.fields_present = SAMR_FIELD_PASSWORD;
2079 set_pw_in_buffer(u.info25.password.data, &new_random_pass);
2081 status = dcerpc_fetch_session_key(p, &session_key);
2082 if (!NT_STATUS_IS_OK(status)) {
2083 printf("SetUserInfo level %u - no session key - %s\n",
2084 s.in.level, nt_errstr(status));
2088 generate_random_buffer((uint8_t *)confounder, 16);
2091 MD5Update(&ctx, confounder, 16);
2092 MD5Update(&ctx, session_key.data, session_key.length);
2093 MD5Final(confounded_session_key.data, &ctx);
2095 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
2096 memcpy(&u.info25.password.data[516], confounder, 16);
2098 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
2100 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
2101 if (!NT_STATUS_IS_OK(status)) {
2102 printf("SetUserInfo level %u failed - %s\n",
2103 s.in.level, nt_errstr(status));
2107 torture_comment(tctx, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
2109 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2111 new_random_pass = samr_very_rand_pass(tctx, 128);
2113 mdfour(new_nt_hash, new_random_pass.data, new_random_pass.length);
2115 set_pw_in_buffer(nt_pass.data, &new_random_pass);
2116 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2117 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2119 r.in.server = &server;
2120 r.in.account = &account;
2121 r.in.nt_password = &nt_pass;
2122 r.in.nt_verifier = &nt_verifier;
2124 r.in.lm_password = NULL;
2125 r.in.lm_verifier = NULL;
2126 r.in.password3 = NULL;
2127 r.out.dominfo = &dominfo;
2128 r.out.reject = &reject;
2130 unix_to_nt_time(&t, time(NULL));
2132 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2134 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2135 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2136 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2137 SAMR_REJECT_OTHER, reject->reason);
2140 /* Perhaps the server has a 'min password age' set? */
2142 } else if (!NT_STATUS_IS_OK(status)) {
2143 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
2147 newpass = samr_rand_pass(tctx, 128);
2149 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2151 E_md4hash(newpass, new_nt_hash);
2153 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2154 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2155 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2157 r.in.server = &server;
2158 r.in.account = &account;
2159 r.in.nt_password = &nt_pass;
2160 r.in.nt_verifier = &nt_verifier;
2162 r.in.lm_password = NULL;
2163 r.in.lm_verifier = NULL;
2164 r.in.password3 = NULL;
2165 r.out.dominfo = &dominfo;
2166 r.out.reject = &reject;
2168 unix_to_nt_time(&t, time(NULL));
2170 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2172 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2173 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2174 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2175 SAMR_REJECT_OTHER, reject->reason);
2178 /* Perhaps the server has a 'min password age' set? */
2181 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3 (on second random password)");
2182 *password = talloc_strdup(tctx, newpass);
2189 static bool test_GetMembersInAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2190 struct policy_handle *alias_handle)
2192 struct samr_GetMembersInAlias r;
2193 struct lsa_SidArray sids;
2196 torture_comment(tctx, "Testing GetMembersInAlias\n");
2198 r.in.alias_handle = alias_handle;
2201 status = dcerpc_samr_GetMembersInAlias(p, tctx, &r);
2202 torture_assert_ntstatus_ok(tctx, status, "GetMembersInAlias");
2207 static bool test_AddMemberToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2208 struct policy_handle *alias_handle,
2209 const struct dom_sid *domain_sid)
2211 struct samr_AddAliasMember r;
2212 struct samr_DeleteAliasMember d;
2214 struct dom_sid *sid;
2216 sid = dom_sid_add_rid(tctx, domain_sid, 512);
2218 torture_comment(tctx, "testing AddAliasMember\n");
2219 r.in.alias_handle = alias_handle;
2222 status = dcerpc_samr_AddAliasMember(p, tctx, &r);
2223 torture_assert_ntstatus_ok(tctx, status, "AddAliasMember");
2225 d.in.alias_handle = alias_handle;
2228 status = dcerpc_samr_DeleteAliasMember(p, tctx, &d);
2229 torture_assert_ntstatus_ok(tctx, status, "DelAliasMember");
2234 static bool test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2235 struct policy_handle *alias_handle)
2237 struct samr_AddMultipleMembersToAlias a;
2238 struct samr_RemoveMultipleMembersFromAlias r;
2240 struct lsa_SidArray sids;
2242 torture_comment(tctx, "testing AddMultipleMembersToAlias\n");
2243 a.in.alias_handle = alias_handle;
2247 sids.sids = talloc_array(tctx, struct lsa_SidPtr, 3);
2249 sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2250 sids.sids[1].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-2");
2251 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-3");
2253 status = dcerpc_samr_AddMultipleMembersToAlias(p, tctx, &a);
2254 torture_assert_ntstatus_ok(tctx, status, "AddMultipleMembersToAlias");
2257 torture_comment(tctx, "testing RemoveMultipleMembersFromAlias\n");
2258 r.in.alias_handle = alias_handle;
2261 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2262 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2264 /* strange! removing twice doesn't give any error */
2265 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2266 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2268 /* but removing an alias that isn't there does */
2269 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-4");
2271 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2272 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, "RemoveMultipleMembersFromAlias");
2277 static bool test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2278 struct policy_handle *user_handle)
2280 struct samr_TestPrivateFunctionsUser r;
2283 torture_comment(tctx, "Testing TestPrivateFunctionsUser\n");
2285 r.in.user_handle = user_handle;
2287 status = dcerpc_samr_TestPrivateFunctionsUser(p, tctx, &r);
2288 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsUser");
2293 static bool test_QueryUserInfo_pwdlastset(struct dcerpc_pipe *p,
2294 struct torture_context *tctx,
2295 struct policy_handle *handle,
2300 uint16_t levels[] = { /* 3, */ 5, 21 };
2302 NTTIME pwdlastset3 = 0;
2303 NTTIME pwdlastset5 = 0;
2304 NTTIME pwdlastset21 = 0;
2306 torture_comment(tctx, "Testing QueryUserInfo%s level 5 and 21 call ",
2307 use_info2 ? "2":"");
2309 for (i=0; i<ARRAY_SIZE(levels); i++) {
2311 struct samr_QueryUserInfo r;
2312 struct samr_QueryUserInfo2 r2;
2313 union samr_UserInfo *info;
2316 r2.in.user_handle = handle;
2317 r2.in.level = levels[i];
2318 r2.out.info = &info;
2319 status = dcerpc_samr_QueryUserInfo2(p, tctx, &r2);
2322 r.in.user_handle = handle;
2323 r.in.level = levels[i];
2325 status = dcerpc_samr_QueryUserInfo(p, tctx, &r);
2328 if (!NT_STATUS_IS_OK(status) &&
2329 !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
2330 printf("QueryUserInfo%s level %u failed - %s\n",
2331 use_info2 ? "2":"", levels[i], nt_errstr(status));
2335 switch (levels[i]) {
2337 pwdlastset3 = info->info3.last_password_change;
2340 pwdlastset5 = info->info5.last_password_change;
2343 pwdlastset21 = info->info21.last_password_change;
2349 /* torture_assert_int_equal(tctx, pwdlastset3, pwdlastset5,
2350 "pwdlastset mixup"); */
2351 torture_assert_int_equal(tctx, pwdlastset5, pwdlastset21,
2352 "pwdlastset mixup");
2354 *pwdlastset = pwdlastset21;
2356 torture_comment(tctx, "(pwdlastset: %lld)\n", *pwdlastset);
2361 static bool test_SetPassword_level(struct dcerpc_pipe *p,
2362 struct torture_context *tctx,
2363 struct policy_handle *handle,
2365 uint32_t fields_present,
2366 uint8_t password_expired,
2367 NTSTATUS expected_error,
2370 bool use_queryinfo2,
2373 const char *fields = NULL;
2380 fields = talloc_asprintf(tctx, "(fields_present: 0x%08x)",
2387 torture_comment(tctx, "Testing SetUserInfo%s level %d call "
2388 "(password_expired: %d) %s\n",
2389 use_setinfo2 ? "2":"", level, password_expired,
2390 fields ? fields : "");
2398 if (!test_SetUserPass_level_ex(p, tctx, handle, level,
2411 if (!test_QueryUserInfo_pwdlastset(p, tctx, handle,
2420 static bool test_SetPassword_pwdlastset(struct dcerpc_pipe *p,
2421 struct torture_context *tctx,
2422 uint32_t acct_flags,
2423 struct policy_handle *handle,
2426 int i, s = 0, q = 0;
2429 bool set_levels[] = { false, true };
2430 bool query_levels[] = { false, true };
2434 uint8_t password_expired_nonzero;
2435 uint32_t fields_present;
2444 .password_expired_nonzero = 1,
2445 .fields_present = SAMR_FIELD_EXPIRED_FLAG
2448 .password_expired_nonzero = 1,
2449 .fields_present = SAMR_FIELD_LAST_PWD_CHANGE,
2450 .set_error = NT_STATUS_ACCESS_DENIED
2453 .password_expired_nonzero = 1,
2454 .fields_present = 0,
2455 .set_error = NT_STATUS_INVALID_PARAMETER
2458 .password_expired_nonzero = 1,
2459 .fields_present = SAMR_FIELD_COMMENT,
2465 .password_expired_nonzero = 1,
2466 .fields_present = SAMR_FIELD_PASSWORD |
2467 SAMR_FIELD_PASSWORD2 |
2468 SAMR_FIELD_LAST_PWD_CHANGE,
2469 .query_info2 = false,
2470 .set_error = NT_STATUS_ACCESS_DENIED
2476 .password_expired_nonzero = 1,
2477 .fields_present = SAMR_FIELD_EXPIRED_FLAG
2480 .password_expired_nonzero = 1,
2481 .fields_present = SAMR_FIELD_LAST_PWD_CHANGE,
2482 .set_error = NT_STATUS_ACCESS_DENIED
2485 .password_expired_nonzero = 1,
2486 .fields_present = SAMR_FIELD_LAST_PWD_CHANGE |
2487 SAMR_FIELD_PASSWORD |
2488 SAMR_FIELD_PASSWORD2,
2489 .set_error = NT_STATUS_ACCESS_DENIED
2492 .password_expired_nonzero = 1,
2493 .fields_present = SAMR_FIELD_LAST_PWD_CHANGE |
2494 SAMR_FIELD_PASSWORD |
2495 SAMR_FIELD_PASSWORD2 |
2496 SAMR_FIELD_EXPIRED_FLAG,
2497 .set_error = NT_STATUS_ACCESS_DENIED
2500 .password_expired_nonzero = 1,
2501 .fields_present = SAMR_FIELD_PASSWORD |
2502 SAMR_FIELD_PASSWORD2 |
2503 SAMR_FIELD_EXPIRED_FLAG
2506 .password_expired_nonzero = 1,
2507 .fields_present = SAMR_FIELD_PASSWORD |
2508 SAMR_FIELD_PASSWORD2,
2511 .password_expired_nonzero = 1,
2512 .fields_present = SAMR_FIELD_COMMENT,
2515 .password_expired_nonzero = 1,
2516 .fields_present = 0,
2517 .set_error = NT_STATUS_INVALID_PARAMETER
2523 .password_expired_nonzero = 1
2526 .password_expired_nonzero = 24
2532 .password_expired_nonzero = 1,
2533 .fields_present = SAMR_FIELD_LAST_PWD_CHANGE,
2534 .set_error = NT_STATUS_ACCESS_DENIED
2537 .password_expired_nonzero = 1,
2538 .fields_present = SAMR_FIELD_EXPIRED_FLAG,
2541 .password_expired_nonzero = 1,
2542 .fields_present = SAMR_FIELD_PASSWORD |
2543 SAMR_FIELD_PASSWORD2 |
2544 SAMR_FIELD_EXPIRED_FLAG
2547 .password_expired_nonzero = 1,
2548 .fields_present = SAMR_FIELD_PASSWORD |
2549 SAMR_FIELD_PASSWORD2,
2552 .password_expired_nonzero = 1,
2553 .fields_present = SAMR_FIELD_COMMENT,
2559 .password_expired_nonzero = 1
2562 .password_expired_nonzero = 24
2566 if (torture_setting_bool(tctx, "samba3", false)) {
2568 printf("Samba3 has second granularity, setting delay to: %d\n",
2572 /* set to 1 to enable testing for all possible opcode
2573 (SetUserInfo, SetUserInfo2, QueryUserInfo, QueryUserInfo2)
2576 #define TEST_SET_LEVELS 1
2577 #define TEST_QUERY_LEVELS 1
2579 for (i=0; i<ARRAY_SIZE(pwd_tests); i++) {
2580 #ifdef TEST_SET_LEVELS
2581 for (s=0; s<ARRAY_SIZE(set_levels); s++) {
2583 #ifdef TEST_QUERY_LEVELS
2584 for (q=0; q<ARRAY_SIZE(query_levels); q++) {
2586 NTTIME pwdlastset_old = 0;
2587 NTTIME pwdlastset_new = 0;
2589 torture_comment(tctx, "------------------------------\n"
2590 "Testing pwdLastSet attribute for flags: 0x%08x "
2591 "(s: %d (l: %d), q: %d)\n",
2592 acct_flags, s, pwd_tests[i].level, q);
2596 /* set a password and force password change (pwdlastset 0) by
2597 * setting the password expired flag to a non-0 value */
2599 if (!test_SetPassword_level(p, tctx, handle,
2601 pwd_tests[i].fields_present,
2602 pwd_tests[i].password_expired_nonzero,
2603 pwd_tests[i].set_error,
2611 if (!NT_STATUS_IS_OK(pwd_tests[i].set_error)) {
2612 /* skipping on expected failure */
2616 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
2617 * set without the SAMR_FIELD_EXPIRED_FLAG */
2619 switch (pwd_tests[i].level) {
2623 if ((pwdlastset_new != 0) &&
2624 !(pwd_tests[i].fields_present & SAMR_FIELD_EXPIRED_FLAG)) {
2625 torture_comment(tctx, "not considering a non-0 "
2626 "pwdLastSet as a an error as the "
2627 "SAMR_FIELD_EXPIRED_FLAG has not "
2632 if (pwdlastset_new != 0) {
2633 torture_warning(tctx, "pwdLastSet test failed: "
2634 "expected pwdLastSet 0 but got %lld\n",
2645 /* set a password, pwdlastset needs to get updated (increased
2646 * value), password_expired value used here is 0 */
2648 if (!test_SetPassword_level(p, tctx, handle, pwd_tests[i].level,
2649 pwd_tests[i].fields_present,
2651 pwd_tests[i].set_error,
2660 /* when a password has been changed, pwdlastset must not be 0 afterwards
2661 * and must be larger then the old value */
2663 switch (pwd_tests[i].level) {
2668 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
2669 * password has been changed, old and new pwdlastset
2670 * need to be the same value */
2672 if (!(pwd_tests[i].fields_present & SAMR_FIELD_EXPIRED_FLAG) &&
2673 !((pwd_tests[i].fields_present & SAMR_FIELD_PASSWORD) ||
2674 (pwd_tests[i].fields_present & SAMR_FIELD_PASSWORD2)))
2676 torture_assert_int_equal(tctx, pwdlastset_old,
2677 pwdlastset_new, "pwdlastset must be equal");
2681 if (pwdlastset_old >= pwdlastset_new) {
2682 torture_warning(tctx, "pwdLastSet test failed: "
2683 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
2684 pwdlastset_old, pwdlastset_new);
2687 if (pwdlastset_new == 0) {
2688 torture_warning(tctx, "pwdLastSet test failed: "
2689 "expected non-0 pwdlastset, got: %lld\n",
2695 pwdlastset_old = pwdlastset_new;
2701 /* set a password and force password change (pwdlastset 0) by
2702 * setting the password expired flag to a non-0 value */
2704 if (!test_SetPassword_level(p, tctx, handle, pwd_tests[i].level,
2705 pwd_tests[i].fields_present,
2706 pwd_tests[i].password_expired_nonzero,
2707 pwd_tests[i].set_error,
2715 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
2716 * set without the SAMR_FIELD_EXPIRED_FLAG */
2718 switch (pwd_tests[i].level) {
2722 if ((pwdlastset_new != 0) &&
2723 !(pwd_tests[i].fields_present & SAMR_FIELD_EXPIRED_FLAG)) {
2724 torture_comment(tctx, "not considering a non-0 "
2725 "pwdLastSet as a an error as the "
2726 "SAMR_FIELD_EXPIRED_FLAG has not "
2731 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
2732 * password has been changed, old and new pwdlastset
2733 * need to be the same value */
2735 if (!(pwd_tests[i].fields_present & SAMR_FIELD_EXPIRED_FLAG) &&
2736 !((pwd_tests[i].fields_present & SAMR_FIELD_PASSWORD) ||
2737 (pwd_tests[i].fields_present & SAMR_FIELD_PASSWORD2)))
2739 torture_assert_int_equal(tctx, pwdlastset_old,
2740 pwdlastset_new, "pwdlastset must be equal");
2745 if (pwdlastset_old == pwdlastset_new) {
2746 torture_warning(tctx, "pwdLastSet test failed: "
2747 "expected last pwdlastset (%lld) != new pwdlastset (%lld)\n",
2748 pwdlastset_old, pwdlastset_new);
2752 if (pwdlastset_new != 0) {
2753 torture_warning(tctx, "pwdLastSet test failed: "
2754 "expected pwdLastSet 0, got %lld\n",
2760 #ifdef TEST_QUERY_LEVELS
2763 #ifdef TEST_SET_LEVELS
2768 #undef TEST_SET_LEVELS
2769 #undef TEST_QUERY_LEVELS
2774 static bool test_user_ops(struct dcerpc_pipe *p,
2775 struct torture_context *tctx,
2776 struct policy_handle *user_handle,
2777 struct policy_handle *domain_handle,
2778 uint32_t base_acct_flags,
2779 const char *base_acct_name, enum torture_samr_choice which_ops)
2781 char *password = NULL;
2782 struct samr_QueryUserInfo q;
2783 union samr_UserInfo *info;
2789 const uint32_t password_fields[] = {
2790 SAMR_FIELD_PASSWORD,
2791 SAMR_FIELD_PASSWORD2,
2792 SAMR_FIELD_PASSWORD | SAMR_FIELD_PASSWORD2,
2796 status = test_LookupName(p, tctx, domain_handle, base_acct_name, &rid);
2797 if (!NT_STATUS_IS_OK(status)) {
2801 switch (which_ops) {
2802 case TORTURE_SAMR_USER_ATTRIBUTES:
2803 if (!test_QuerySecurity(p, tctx, user_handle)) {
2807 if (!test_QueryUserInfo(p, tctx, user_handle)) {
2811 if (!test_QueryUserInfo2(p, tctx, user_handle)) {
2815 if (!test_SetUserInfo(p, tctx, user_handle, base_acct_flags,
2820 if (!test_GetUserPwInfo(p, tctx, user_handle)) {
2824 if (!test_TestPrivateFunctionsUser(p, tctx, user_handle)) {
2828 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
2832 case TORTURE_SAMR_PASSWORDS:
2833 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
2834 char simple_pass[9];
2835 char *v = generate_random_str(tctx, 1);
2837 ZERO_STRUCT(simple_pass);
2838 memset(simple_pass, *v, sizeof(simple_pass) - 1);
2840 printf("Testing machine account password policy rules\n");
2842 /* Workstation trust accounts don't seem to need to honour password quality policy */
2843 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
2847 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
2851 /* reset again, to allow another 'user' password change */
2852 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
2856 /* Try a 'short' password */
2857 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
2861 /* Try a compleatly random password */
2862 if (!test_ChangePasswordRandomBytes(p, tctx, base_acct_name, user_handle, &password)) {
2867 for (i = 0; password_fields[i]; i++) {
2868 if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
2872 /* check it was set right */
2873 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
2878 for (i = 0; password_fields[i]; i++) {
2879 if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
2883 /* check it was set right */
2884 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
2889 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
2893 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
2897 q.in.user_handle = user_handle;
2901 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
2902 if (!NT_STATUS_IS_OK(status)) {
2903 printf("QueryUserInfo level %u failed - %s\n",
2904 q.in.level, nt_errstr(status));
2907 uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
2908 if ((info->info5.acct_flags) != expected_flags) {
2909 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2910 info->info5.acct_flags,
2914 if (info->info5.rid != rid) {
2915 printf("QuerUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
2916 info->info5.rid, rid);
2923 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
2925 /* test last password change timestamp behaviour */
2926 if (!test_SetPassword_pwdlastset(p, tctx, base_acct_flags,
2927 user_handle, &password)) {
2932 torture_comment(tctx, "pwdLastSet test succeeded\n");
2934 torture_warning(tctx, "pwdLastSet test failed\n");
2939 case TORTURE_SAMR_OTHER:
2940 /* We just need the account to exist */
2946 static bool test_alias_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
2947 struct policy_handle *alias_handle,
2948 const struct dom_sid *domain_sid)
2952 if (!test_QuerySecurity(p, tctx, alias_handle)) {
2956 if (!test_QueryAliasInfo(p, tctx, alias_handle)) {
2960 if (!test_SetAliasInfo(p, tctx, alias_handle)) {
2964 if (!test_AddMemberToAlias(p, tctx, alias_handle, domain_sid)) {
2968 if (torture_setting_bool(tctx, "samba4", false)) {
2969 printf("skipping MultipleMembers Alias tests against Samba4\n");
2973 if (!test_AddMultipleMembersToAlias(p, tctx, alias_handle)) {
2981 static bool test_DeleteUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2982 struct policy_handle *user_handle)
2984 struct samr_DeleteUser d;
2986 torture_comment(tctx, "Testing DeleteUser\n");
2988 d.in.user_handle = user_handle;
2989 d.out.user_handle = user_handle;
2991 status = dcerpc_samr_DeleteUser(p, tctx, &d);
2992 torture_assert_ntstatus_ok(tctx, status, "DeleteUser");
2997 bool test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2998 struct policy_handle *handle, const char *name)
3001 struct samr_DeleteUser d;
3002 struct policy_handle user_handle;
3005 status = test_LookupName(p, mem_ctx, handle, name, &rid);
3006 if (!NT_STATUS_IS_OK(status)) {
3010 status = test_OpenUser_byname(p, mem_ctx, handle, name, &user_handle);
3011 if (!NT_STATUS_IS_OK(status)) {
3015 d.in.user_handle = &user_handle;
3016 d.out.user_handle = &user_handle;
3017 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
3018 if (!NT_STATUS_IS_OK(status)) {
3025 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
3030 static bool test_DeleteGroup_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3031 struct policy_handle *handle, const char *name)
3034 struct samr_OpenGroup r;
3035 struct samr_DeleteDomainGroup d;
3036 struct policy_handle group_handle;
3039 status = test_LookupName(p, mem_ctx, handle, name, &rid);
3040 if (!NT_STATUS_IS_OK(status)) {
3044 r.in.domain_handle = handle;
3045 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3047 r.out.group_handle = &group_handle;
3048 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
3049 if (!NT_STATUS_IS_OK(status)) {
3053 d.in.group_handle = &group_handle;
3054 d.out.group_handle = &group_handle;
3055 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
3056 if (!NT_STATUS_IS_OK(status)) {
3063 printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
3068 static bool test_DeleteAlias_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3069 struct policy_handle *domain_handle, const char *name)
3072 struct samr_OpenAlias r;
3073 struct samr_DeleteDomAlias d;
3074 struct policy_handle alias_handle;
3077 printf("testing DeleteAlias_byname\n");
3079 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
3080 if (!NT_STATUS_IS_OK(status)) {
3084 r.in.domain_handle = domain_handle;
3085 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3087 r.out.alias_handle = &alias_handle;
3088 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
3089 if (!NT_STATUS_IS_OK(status)) {
3093 d.in.alias_handle = &alias_handle;
3094 d.out.alias_handle = &alias_handle;
3095 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
3096 if (!NT_STATUS_IS_OK(status)) {
3103 printf("DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
3107 static bool test_DeleteAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3108 struct policy_handle *alias_handle)
3110 struct samr_DeleteDomAlias d;
3113 printf("Testing DeleteAlias\n");
3115 d.in.alias_handle = alias_handle;
3116 d.out.alias_handle = alias_handle;
3118 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
3119 if (!NT_STATUS_IS_OK(status)) {
3120 printf("DeleteAlias failed - %s\n", nt_errstr(status));
3127 static bool test_CreateAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
3128 struct policy_handle *domain_handle,