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_18(struct dcerpc_pipe *p, struct torture_context *tctx,
853 struct policy_handle *handle, char **password)
856 struct samr_SetUserInfo s;
857 union samr_UserInfo u;
859 DATA_BLOB session_key;
861 struct samr_GetUserPwInfo pwp;
862 struct samr_PwInfo info;
863 int policy_min_pw_len = 0;
864 uint8_t lm_hash[16], nt_hash[16];
866 pwp.in.user_handle = handle;
867 pwp.out.info = &info;
869 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
870 if (NT_STATUS_IS_OK(status)) {
871 policy_min_pw_len = pwp.out.info->min_password_length;
873 newpass = samr_rand_pass(tctx, policy_min_pw_len);
875 s.in.user_handle = handle;
881 u.info18.nt_pwd_active = true;
882 u.info18.lm_pwd_active = true;
884 E_md4hash(newpass, nt_hash);
885 E_deshash(newpass, lm_hash);
887 status = dcerpc_fetch_session_key(p, &session_key);
888 if (!NT_STATUS_IS_OK(status)) {
889 printf("SetUserInfo level %u - no session key - %s\n",
890 s.in.level, nt_errstr(status));
896 in = data_blob_const(nt_hash, 16);
897 out = data_blob_talloc_zero(tctx, 16);
898 sess_crypt_blob(&out, &in, &session_key, true);
899 memcpy(u.info18.nt_pwd.hash, out.data, out.length);
903 in = data_blob_const(lm_hash, 16);
904 out = data_blob_talloc_zero(tctx, 16);
905 sess_crypt_blob(&out, &in, &session_key, true);
906 memcpy(u.info18.lm_pwd.hash, out.data, out.length);
909 torture_comment(tctx, "Testing SetUserInfo level 18 (set password hash)\n");
911 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
912 if (!NT_STATUS_IS_OK(status)) {
913 printf("SetUserInfo level %u failed - %s\n",
914 s.in.level, nt_errstr(status));
923 static bool test_SetUserPass_21(struct dcerpc_pipe *p, struct torture_context *tctx,
924 struct policy_handle *handle, uint32_t fields_present,
928 struct samr_SetUserInfo s;
929 union samr_UserInfo u;
931 DATA_BLOB session_key;
933 struct samr_GetUserPwInfo pwp;
934 struct samr_PwInfo info;
935 int policy_min_pw_len = 0;
936 uint8_t lm_hash[16], nt_hash[16];
938 pwp.in.user_handle = handle;
939 pwp.out.info = &info;
941 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
942 if (NT_STATUS_IS_OK(status)) {
943 policy_min_pw_len = pwp.out.info->min_password_length;
945 newpass = samr_rand_pass(tctx, policy_min_pw_len);
947 s.in.user_handle = handle;
951 E_md4hash(newpass, nt_hash);
952 E_deshash(newpass, lm_hash);
956 u.info21.fields_present = fields_present;
958 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
959 u.info21.lm_owf_password.length = 16;
960 u.info21.lm_owf_password.size = 16;
961 u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
962 u.info21.lm_password_set = true;
965 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
966 u.info21.nt_owf_password.length = 16;
967 u.info21.nt_owf_password.size = 16;
968 u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
969 u.info21.nt_password_set = true;
972 status = dcerpc_fetch_session_key(p, &session_key);
973 if (!NT_STATUS_IS_OK(status)) {
974 printf("SetUserInfo level %u - no session key - %s\n",
975 s.in.level, nt_errstr(status));
979 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
981 in = data_blob_const(u.info21.lm_owf_password.array,
982 u.info21.lm_owf_password.length);
983 out = data_blob_talloc_zero(tctx, 16);
984 sess_crypt_blob(&out, &in, &session_key, true);
985 u.info21.lm_owf_password.array = (uint16_t *)out.data;
988 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
990 in = data_blob_const(u.info21.nt_owf_password.array,
991 u.info21.nt_owf_password.length);
992 out = data_blob_talloc_zero(tctx, 16);
993 sess_crypt_blob(&out, &in, &session_key, true);
994 u.info21.nt_owf_password.array = (uint16_t *)out.data;
997 torture_comment(tctx, "Testing SetUserInfo level 21 (set password hash)\n");
999 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1000 if (!NT_STATUS_IS_OK(status)) {
1001 printf("SetUserInfo level %u failed - %s\n",
1002 s.in.level, nt_errstr(status));
1005 *password = newpass;
1008 /* try invalid length */
1009 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1011 u.info21.nt_owf_password.length++;
1013 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1015 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1016 printf("SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1017 s.in.level, nt_errstr(status));
1022 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1024 u.info21.lm_owf_password.length++;
1026 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1028 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1029 printf("SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1030 s.in.level, nt_errstr(status));
1038 static bool test_SetUserPass_level_ex(struct dcerpc_pipe *p,
1039 struct torture_context *tctx,
1040 struct policy_handle *handle,
1042 uint32_t fields_present,
1043 char **password, uint8_t password_expired,
1045 bool *matched_expected_error)
1048 NTSTATUS expected_error = NT_STATUS_OK;
1049 struct samr_SetUserInfo s;
1050 struct samr_SetUserInfo2 s2;
1051 union samr_UserInfo u;
1053 DATA_BLOB session_key;
1054 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
1055 struct MD5Context ctx;
1056 uint8_t confounder[16];
1058 struct samr_GetUserPwInfo pwp;
1059 struct samr_PwInfo info;
1060 int policy_min_pw_len = 0;
1061 const char *comment = NULL;
1063 pwp.in.user_handle = handle;
1064 pwp.out.info = &info;
1066 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1067 if (NT_STATUS_IS_OK(status)) {
1068 policy_min_pw_len = pwp.out.info->min_password_length;
1070 newpass = samr_rand_pass_silent(tctx, policy_min_pw_len);
1073 s2.in.user_handle = handle;
1075 s2.in.level = level;
1077 s.in.user_handle = handle;
1082 if (fields_present & SAMR_FIELD_COMMENT) {
1083 comment = talloc_asprintf(tctx, "comment: %d\n", time(NULL));
1090 u.info21.fields_present = fields_present;
1091 u.info21.password_expired = password_expired;
1092 u.info21.comment.string = comment;
1096 u.info23.info.fields_present = fields_present;
1097 u.info23.info.password_expired = password_expired;
1098 u.info23.info.comment.string = comment;
1100 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
1104 u.info24.password_expired = password_expired;
1106 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
1110 u.info25.info.fields_present = fields_present;
1111 u.info25.info.password_expired = password_expired;
1112 u.info25.info.comment.string = comment;
1114 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
1118 u.info26.password_expired = password_expired;
1120 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
1125 status = dcerpc_fetch_session_key(p, &session_key);
1126 if (!NT_STATUS_IS_OK(status)) {
1127 printf("SetUserInfo level %u - no session key - %s\n",
1128 s.in.level, nt_errstr(status));
1132 generate_random_buffer((uint8_t *)confounder, 16);
1135 MD5Update(&ctx, confounder, 16);
1136 MD5Update(&ctx, session_key.data, session_key.length);
1137 MD5Final(confounded_session_key.data, &ctx);
1141 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
1144 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
1147 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
1148 memcpy(&u.info25.password.data[516], confounder, 16);
1151 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
1152 memcpy(&u.info26.password.data[516], confounder, 16);
1157 status = dcerpc_samr_SetUserInfo2(p, tctx, &s2);
1159 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1162 if (!NT_STATUS_IS_OK(status)) {
1163 if (fields_present == 0) {
1164 expected_error = NT_STATUS_INVALID_PARAMETER;
1166 if (fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
1167 expected_error = NT_STATUS_ACCESS_DENIED;
1171 if (!NT_STATUS_IS_OK(expected_error)) {
1173 torture_assert_ntstatus_equal(tctx,
1175 expected_error, "SetUserInfo2 failed");
1177 torture_assert_ntstatus_equal(tctx,
1179 expected_error, "SetUserInfo failed");
1181 *matched_expected_error = true;
1185 if (!NT_STATUS_IS_OK(status)) {
1186 printf("SetUserInfo%s level %u failed - %s\n",
1187 use_setinfo2 ? "2":"", level, nt_errstr(status));
1191 *password = newpass;
1198 static bool test_SetAliasInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1199 struct policy_handle *handle)
1202 struct samr_SetAliasInfo r;
1203 struct samr_QueryAliasInfo q;
1204 union samr_AliasInfo *info;
1205 uint16_t levels[] = {2, 3};
1209 /* Ignoring switch level 1, as that includes the number of members for the alias
1210 * and setting this to a wrong value might have negative consequences
1213 for (i=0;i<ARRAY_SIZE(levels);i++) {
1214 torture_comment(tctx, "Testing SetAliasInfo level %u\n", levels[i]);
1216 r.in.alias_handle = handle;
1217 r.in.level = levels[i];
1218 r.in.info = talloc(tctx, union samr_AliasInfo);
1219 switch (r.in.level) {
1220 case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
1221 case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
1222 "Test Description, should test I18N as well"); break;
1223 case ALIASINFOALL: printf("ALIASINFOALL ignored\n"); break;
1226 status = dcerpc_samr_SetAliasInfo(p, tctx, &r);
1227 if (!NT_STATUS_IS_OK(status)) {
1228 printf("SetAliasInfo level %u failed - %s\n",
1229 levels[i], nt_errstr(status));
1233 q.in.alias_handle = handle;
1234 q.in.level = levels[i];
1237 status = dcerpc_samr_QueryAliasInfo(p, tctx, &q);
1238 if (!NT_STATUS_IS_OK(status)) {
1239 printf("QueryAliasInfo level %u failed - %s\n",
1240 levels[i], nt_errstr(status));
1248 static bool test_GetGroupsForUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1249 struct policy_handle *user_handle)
1251 struct samr_GetGroupsForUser r;
1252 struct samr_RidWithAttributeArray *rids = NULL;
1255 torture_comment(tctx, "testing GetGroupsForUser\n");
1257 r.in.user_handle = user_handle;
1260 status = dcerpc_samr_GetGroupsForUser(p, tctx, &r);
1261 torture_assert_ntstatus_ok(tctx, status, "GetGroupsForUser");
1267 static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1268 struct lsa_String *domain_name)
1271 struct samr_GetDomPwInfo r;
1272 struct samr_PwInfo info;
1274 r.in.domain_name = domain_name;
1277 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1279 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1280 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1282 r.in.domain_name->string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1283 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1285 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1286 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1288 r.in.domain_name->string = "\\\\__NONAME__";
1289 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1291 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1292 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1294 r.in.domain_name->string = "\\\\Builtin";
1295 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1297 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1298 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1303 static bool test_GetUserPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1304 struct policy_handle *handle)
1307 struct samr_GetUserPwInfo r;
1308 struct samr_PwInfo info;
1310 torture_comment(tctx, "Testing GetUserPwInfo\n");
1312 r.in.user_handle = handle;
1315 status = dcerpc_samr_GetUserPwInfo(p, tctx, &r);
1316 torture_assert_ntstatus_ok(tctx, status, "GetUserPwInfo");
1321 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, struct torture_context *tctx,
1322 struct policy_handle *domain_handle, const char *name,
1326 struct samr_LookupNames n;
1327 struct lsa_String sname[2];
1328 struct samr_Ids rids, types;
1330 init_lsa_String(&sname[0], name);
1332 n.in.domain_handle = domain_handle;
1336 n.out.types = &types;
1337 status = dcerpc_samr_LookupNames(p, tctx, &n);
1338 if (NT_STATUS_IS_OK(status)) {
1339 *rid = n.out.rids->ids[0];
1344 init_lsa_String(&sname[1], "xxNONAMExx");
1346 status = dcerpc_samr_LookupNames(p, tctx, &n);
1347 if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
1348 printf("LookupNames[2] failed - %s\n", nt_errstr(status));
1349 if (NT_STATUS_IS_OK(status)) {
1350 return NT_STATUS_UNSUCCESSFUL;
1356 status = dcerpc_samr_LookupNames(p, tctx, &n);
1357 if (!NT_STATUS_IS_OK(status)) {
1358 printf("LookupNames[0] failed - %s\n", nt_errstr(status));
1362 init_lsa_String(&sname[0], "xxNONAMExx");
1364 status = dcerpc_samr_LookupNames(p, tctx, &n);
1365 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1366 printf("LookupNames[1 bad name] failed - %s\n", nt_errstr(status));
1367 if (NT_STATUS_IS_OK(status)) {
1368 return NT_STATUS_UNSUCCESSFUL;
1373 init_lsa_String(&sname[0], "xxNONAMExx");
1374 init_lsa_String(&sname[1], "xxNONAME2xx");
1376 status = dcerpc_samr_LookupNames(p, tctx, &n);
1377 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1378 printf("LookupNames[2 bad names] failed - %s\n", nt_errstr(status));
1379 if (NT_STATUS_IS_OK(status)) {
1380 return NT_STATUS_UNSUCCESSFUL;
1385 return NT_STATUS_OK;
1388 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1389 struct policy_handle *domain_handle,
1390 const char *name, struct policy_handle *user_handle)
1393 struct samr_OpenUser r;
1396 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
1397 if (!NT_STATUS_IS_OK(status)) {
1401 r.in.domain_handle = domain_handle;
1402 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1404 r.out.user_handle = user_handle;
1405 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
1406 if (!NT_STATUS_IS_OK(status)) {
1407 printf("OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(status));
1414 static bool test_ChangePasswordNT3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1415 struct policy_handle *handle)
1418 struct samr_ChangePasswordUser r;
1420 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1421 struct policy_handle user_handle;
1422 char *oldpass = "test";
1423 char *newpass = "test2";
1424 uint8_t old_nt_hash[16], new_nt_hash[16];
1425 uint8_t old_lm_hash[16], new_lm_hash[16];
1427 status = test_OpenUser_byname(p, mem_ctx, handle, "testuser", &user_handle);
1428 if (!NT_STATUS_IS_OK(status)) {
1432 printf("Testing ChangePasswordUser for user 'testuser'\n");
1434 printf("old password: %s\n", oldpass);
1435 printf("new password: %s\n", newpass);
1437 E_md4hash(oldpass, old_nt_hash);
1438 E_md4hash(newpass, new_nt_hash);
1439 E_deshash(oldpass, old_lm_hash);
1440 E_deshash(newpass, new_lm_hash);
1442 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1443 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1444 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1445 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1446 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1447 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1449 r.in.handle = &user_handle;
1450 r.in.lm_present = 1;
1451 r.in.old_lm_crypted = &hash1;
1452 r.in.new_lm_crypted = &hash2;
1453 r.in.nt_present = 1;
1454 r.in.old_nt_crypted = &hash3;
1455 r.in.new_nt_crypted = &hash4;
1456 r.in.cross1_present = 1;
1457 r.in.nt_cross = &hash5;
1458 r.in.cross2_present = 1;
1459 r.in.lm_cross = &hash6;
1461 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1462 if (!NT_STATUS_IS_OK(status)) {
1463 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1467 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1475 static bool test_ChangePasswordUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1476 const char *acct_name,
1477 struct policy_handle *handle, char **password)
1480 struct samr_ChangePasswordUser r;
1482 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1483 struct policy_handle user_handle;
1485 uint8_t old_nt_hash[16], new_nt_hash[16];
1486 uint8_t old_lm_hash[16], new_lm_hash[16];
1487 bool changed = true;
1490 struct samr_GetUserPwInfo pwp;
1491 struct samr_PwInfo info;
1492 int policy_min_pw_len = 0;
1494 status = test_OpenUser_byname(p, tctx, handle, acct_name, &user_handle);
1495 if (!NT_STATUS_IS_OK(status)) {
1498 pwp.in.user_handle = &user_handle;
1499 pwp.out.info = &info;
1501 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1502 if (NT_STATUS_IS_OK(status)) {
1503 policy_min_pw_len = pwp.out.info->min_password_length;
1505 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1507 torture_comment(tctx, "Testing ChangePasswordUser\n");
1509 torture_assert(tctx, *password != NULL,
1510 "Failing ChangePasswordUser as old password was NULL. Previous test failed?");
1512 oldpass = *password;
1514 E_md4hash(oldpass, old_nt_hash);
1515 E_md4hash(newpass, new_nt_hash);
1516 E_deshash(oldpass, old_lm_hash);
1517 E_deshash(newpass, new_lm_hash);
1519 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1520 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1521 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1522 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1523 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1524 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1526 r.in.user_handle = &user_handle;
1527 r.in.lm_present = 1;
1528 /* Break the LM hash */
1530 r.in.old_lm_crypted = &hash1;
1531 r.in.new_lm_crypted = &hash2;
1532 r.in.nt_present = 1;
1533 r.in.old_nt_crypted = &hash3;
1534 r.in.new_nt_crypted = &hash4;
1535 r.in.cross1_present = 1;
1536 r.in.nt_cross = &hash5;
1537 r.in.cross2_present = 1;
1538 r.in.lm_cross = &hash6;
1540 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1541 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1542 "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash");
1544 /* Unbreak the LM hash */
1547 r.in.user_handle = &user_handle;
1548 r.in.lm_present = 1;
1549 r.in.old_lm_crypted = &hash1;
1550 r.in.new_lm_crypted = &hash2;
1551 /* Break the NT hash */
1553 r.in.nt_present = 1;
1554 r.in.old_nt_crypted = &hash3;
1555 r.in.new_nt_crypted = &hash4;
1556 r.in.cross1_present = 1;
1557 r.in.nt_cross = &hash5;
1558 r.in.cross2_present = 1;
1559 r.in.lm_cross = &hash6;
1561 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1562 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1563 "expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash");
1565 /* Unbreak the NT hash */
1568 r.in.user_handle = &user_handle;
1569 r.in.lm_present = 1;
1570 r.in.old_lm_crypted = &hash1;
1571 r.in.new_lm_crypted = &hash2;
1572 r.in.nt_present = 1;
1573 r.in.old_nt_crypted = &hash3;
1574 r.in.new_nt_crypted = &hash4;
1575 r.in.cross1_present = 1;
1576 r.in.nt_cross = &hash5;
1577 r.in.cross2_present = 1;
1578 /* Break the LM cross */
1580 r.in.lm_cross = &hash6;
1582 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1583 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1584 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status));
1588 /* Unbreak the LM cross */
1591 r.in.user_handle = &user_handle;
1592 r.in.lm_present = 1;
1593 r.in.old_lm_crypted = &hash1;
1594 r.in.new_lm_crypted = &hash2;
1595 r.in.nt_present = 1;
1596 r.in.old_nt_crypted = &hash3;
1597 r.in.new_nt_crypted = &hash4;
1598 r.in.cross1_present = 1;
1599 /* Break the NT cross */
1601 r.in.nt_cross = &hash5;
1602 r.in.cross2_present = 1;
1603 r.in.lm_cross = &hash6;
1605 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1606 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1607 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status));
1611 /* Unbreak the NT cross */
1615 /* Reset the hashes to not broken values */
1616 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1617 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1618 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1619 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1620 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1621 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1623 r.in.user_handle = &user_handle;
1624 r.in.lm_present = 1;
1625 r.in.old_lm_crypted = &hash1;
1626 r.in.new_lm_crypted = &hash2;
1627 r.in.nt_present = 1;
1628 r.in.old_nt_crypted = &hash3;
1629 r.in.new_nt_crypted = &hash4;
1630 r.in.cross1_present = 1;
1631 r.in.nt_cross = &hash5;
1632 r.in.cross2_present = 0;
1633 r.in.lm_cross = NULL;
1635 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1636 if (NT_STATUS_IS_OK(status)) {
1638 *password = newpass;
1639 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1640 printf("ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(status));
1645 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1647 E_md4hash(oldpass, old_nt_hash);
1648 E_md4hash(newpass, new_nt_hash);
1649 E_deshash(oldpass, old_lm_hash);
1650 E_deshash(newpass, new_lm_hash);
1653 /* Reset the hashes to not broken values */
1654 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1655 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1656 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1657 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1658 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1659 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1661 r.in.user_handle = &user_handle;
1662 r.in.lm_present = 1;
1663 r.in.old_lm_crypted = &hash1;
1664 r.in.new_lm_crypted = &hash2;
1665 r.in.nt_present = 1;
1666 r.in.old_nt_crypted = &hash3;
1667 r.in.new_nt_crypted = &hash4;
1668 r.in.cross1_present = 0;
1669 r.in.nt_cross = NULL;
1670 r.in.cross2_present = 1;
1671 r.in.lm_cross = &hash6;
1673 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1674 if (NT_STATUS_IS_OK(status)) {
1676 *password = newpass;
1677 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1678 printf("ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status));
1683 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1685 E_md4hash(oldpass, old_nt_hash);
1686 E_md4hash(newpass, new_nt_hash);
1687 E_deshash(oldpass, old_lm_hash);
1688 E_deshash(newpass, new_lm_hash);
1691 /* Reset the hashes to not broken values */
1692 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1693 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1694 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1695 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1696 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1697 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1699 r.in.user_handle = &user_handle;
1700 r.in.lm_present = 1;
1701 r.in.old_lm_crypted = &hash1;
1702 r.in.new_lm_crypted = &hash2;
1703 r.in.nt_present = 1;
1704 r.in.old_nt_crypted = &hash3;
1705 r.in.new_nt_crypted = &hash4;
1706 r.in.cross1_present = 1;
1707 r.in.nt_cross = &hash5;
1708 r.in.cross2_present = 1;
1709 r.in.lm_cross = &hash6;
1711 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1712 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1713 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1714 } else if (!NT_STATUS_IS_OK(status)) {
1715 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1719 *password = newpass;
1722 r.in.user_handle = &user_handle;
1723 r.in.lm_present = 1;
1724 r.in.old_lm_crypted = &hash1;
1725 r.in.new_lm_crypted = &hash2;
1726 r.in.nt_present = 1;
1727 r.in.old_nt_crypted = &hash3;
1728 r.in.new_nt_crypted = &hash4;
1729 r.in.cross1_present = 1;
1730 r.in.nt_cross = &hash5;
1731 r.in.cross2_present = 1;
1732 r.in.lm_cross = &hash6;
1735 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1736 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1737 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1738 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1739 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status));
1745 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
1753 static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
1754 const char *acct_name,
1755 struct policy_handle *handle, char **password)
1758 struct samr_OemChangePasswordUser2 r;
1760 struct samr_Password lm_verifier;
1761 struct samr_CryptPassword lm_pass;
1762 struct lsa_AsciiString server, account, account_bad;
1765 uint8_t old_lm_hash[16], new_lm_hash[16];
1767 struct samr_GetDomPwInfo dom_pw_info;
1768 struct samr_PwInfo info;
1769 int policy_min_pw_len = 0;
1771 struct lsa_String domain_name;
1773 domain_name.string = "";
1774 dom_pw_info.in.domain_name = &domain_name;
1775 dom_pw_info.out.info = &info;
1777 torture_comment(tctx, "Testing OemChangePasswordUser2\n");
1779 torture_assert(tctx, *password != NULL,
1780 "Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?");
1782 oldpass = *password;
1784 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
1785 if (NT_STATUS_IS_OK(status)) {
1786 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
1789 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1791 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1792 account.string = acct_name;
1794 E_deshash(oldpass, old_lm_hash);
1795 E_deshash(newpass, new_lm_hash);
1797 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1798 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1799 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1801 r.in.server = &server;
1802 r.in.account = &account;
1803 r.in.password = &lm_pass;
1804 r.in.hash = &lm_verifier;
1806 /* Break the verification */
1807 lm_verifier.hash[0]++;
1809 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1811 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1812 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1813 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1818 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1819 /* Break the old password */
1821 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1822 /* unbreak it for the next operation */
1824 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1826 r.in.server = &server;
1827 r.in.account = &account;
1828 r.in.password = &lm_pass;
1829 r.in.hash = &lm_verifier;
1831 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1833 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1834 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1835 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1840 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1841 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1843 r.in.server = &server;
1844 r.in.account = &account;
1845 r.in.password = &lm_pass;
1848 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1850 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1851 && !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1852 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
1857 /* This shouldn't be a valid name */
1858 account_bad.string = TEST_ACCOUNT_NAME "XX";
1859 r.in.account = &account_bad;
1861 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1863 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1864 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
1869 /* This shouldn't be a valid name */
1870 account_bad.string = TEST_ACCOUNT_NAME "XX";
1871 r.in.account = &account_bad;
1872 r.in.password = &lm_pass;
1873 r.in.hash = &lm_verifier;
1875 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1877 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1878 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1883 /* This shouldn't be a valid name */
1884 account_bad.string = TEST_ACCOUNT_NAME "XX";
1885 r.in.account = &account_bad;
1886 r.in.password = NULL;
1887 r.in.hash = &lm_verifier;
1889 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1891 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1892 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
1897 E_deshash(oldpass, old_lm_hash);
1898 E_deshash(newpass, new_lm_hash);
1900 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1901 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1902 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1904 r.in.server = &server;
1905 r.in.account = &account;
1906 r.in.password = &lm_pass;
1907 r.in.hash = &lm_verifier;
1909 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1910 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1911 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1912 } else if (!NT_STATUS_IS_OK(status)) {
1913 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
1916 *password = newpass;
1923 static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
1924 const char *acct_name,
1926 char *newpass, bool allow_password_restriction)
1929 struct samr_ChangePasswordUser2 r;
1931 struct lsa_String server, account;
1932 struct samr_CryptPassword nt_pass, lm_pass;
1933 struct samr_Password nt_verifier, lm_verifier;
1935 uint8_t old_nt_hash[16], new_nt_hash[16];
1936 uint8_t old_lm_hash[16], new_lm_hash[16];
1938 struct samr_GetDomPwInfo dom_pw_info;
1939 struct samr_PwInfo info;
1941 struct lsa_String domain_name;
1943 domain_name.string = "";
1944 dom_pw_info.in.domain_name = &domain_name;
1945 dom_pw_info.out.info = &info;
1947 torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name);
1949 torture_assert(tctx, *password != NULL,
1950 "Failing ChangePasswordUser2 as old password was NULL. Previous test failed?");
1951 oldpass = *password;
1954 int policy_min_pw_len = 0;
1955 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
1956 if (NT_STATUS_IS_OK(status)) {
1957 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
1960 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1963 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1964 init_lsa_String(&account, acct_name);
1966 E_md4hash(oldpass, old_nt_hash);
1967 E_md4hash(newpass, new_nt_hash);
1969 E_deshash(oldpass, old_lm_hash);
1970 E_deshash(newpass, new_lm_hash);
1972 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
1973 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1974 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1976 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1977 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1978 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1980 r.in.server = &server;
1981 r.in.account = &account;
1982 r.in.nt_password = &nt_pass;
1983 r.in.nt_verifier = &nt_verifier;
1985 r.in.lm_password = &lm_pass;
1986 r.in.lm_verifier = &lm_verifier;
1988 status = dcerpc_samr_ChangePasswordUser2(p, tctx, &r);
1989 if (allow_password_restriction && NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1990 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1991 } else if (!NT_STATUS_IS_OK(status)) {
1992 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
1995 *password = newpass;
2002 bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tctx,
2003 const char *account_string,
2004 int policy_min_pw_len,
2006 const char *newpass,
2007 NTTIME last_password_change,
2008 bool handle_reject_reason)
2011 struct samr_ChangePasswordUser3 r;
2013 struct lsa_String server, account, account_bad;
2014 struct samr_CryptPassword nt_pass, lm_pass;
2015 struct samr_Password nt_verifier, lm_verifier;
2017 uint8_t old_nt_hash[16], new_nt_hash[16];
2018 uint8_t old_lm_hash[16], new_lm_hash[16];
2020 struct samr_DomInfo1 *dominfo = NULL;
2021 struct samr_ChangeReject *reject = NULL;
2023 torture_comment(tctx, "Testing ChangePasswordUser3\n");
2025 if (newpass == NULL) {
2027 if (policy_min_pw_len == 0) {
2028 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2030 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len);
2032 } while (check_password_quality(newpass) == false);
2034 torture_comment(tctx, "Using password '%s'\n", newpass);
2037 torture_assert(tctx, *password != NULL,
2038 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2040 oldpass = *password;
2041 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2042 init_lsa_String(&account, account_string);
2044 E_md4hash(oldpass, old_nt_hash);
2045 E_md4hash(newpass, new_nt_hash);
2047 E_deshash(oldpass, old_lm_hash);
2048 E_deshash(newpass, new_lm_hash);
2050 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2051 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2052 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2054 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2055 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2056 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2058 /* Break the verification */
2059 nt_verifier.hash[0]++;
2061 r.in.server = &server;
2062 r.in.account = &account;
2063 r.in.nt_password = &nt_pass;
2064 r.in.nt_verifier = &nt_verifier;
2066 r.in.lm_password = &lm_pass;
2067 r.in.lm_verifier = &lm_verifier;
2068 r.in.password3 = NULL;
2069 r.out.dominfo = &dominfo;
2070 r.out.reject = &reject;
2072 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2073 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
2074 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
2075 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
2080 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2081 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2082 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2084 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2085 /* Break the NT hash */
2087 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2088 /* Unbreak it again */
2090 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2092 r.in.server = &server;
2093 r.in.account = &account;
2094 r.in.nt_password = &nt_pass;
2095 r.in.nt_verifier = &nt_verifier;
2097 r.in.lm_password = &lm_pass;
2098 r.in.lm_verifier = &lm_verifier;
2099 r.in.password3 = NULL;
2100 r.out.dominfo = &dominfo;
2101 r.out.reject = &reject;
2103 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2104 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
2105 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
2106 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
2111 /* This shouldn't be a valid name */
2112 init_lsa_String(&account_bad, talloc_asprintf(tctx, "%sXX", account_string));
2114 r.in.account = &account_bad;
2115 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2116 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
2117 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
2122 E_md4hash(oldpass, old_nt_hash);
2123 E_md4hash(newpass, new_nt_hash);
2125 E_deshash(oldpass, old_lm_hash);
2126 E_deshash(newpass, new_lm_hash);
2128 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2129 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2130 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2132 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2133 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2134 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2136 r.in.server = &server;
2137 r.in.account = &account;
2138 r.in.nt_password = &nt_pass;
2139 r.in.nt_verifier = &nt_verifier;
2141 r.in.lm_password = &lm_pass;
2142 r.in.lm_verifier = &lm_verifier;
2143 r.in.password3 = NULL;
2144 r.out.dominfo = &dominfo;
2145 r.out.reject = &reject;
2147 unix_to_nt_time(&t, time(NULL));
2149 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2151 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
2154 && handle_reject_reason
2155 && (!null_nttime(last_password_change) || !dominfo->min_password_age)) {
2156 if (dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
2158 if (reject && (reject->reason != SAMR_REJECT_OTHER)) {
2159 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2160 SAMR_REJECT_OTHER, reject->reason);
2165 /* We tested the order of precendence which is as follows:
2174 if ((dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
2175 (last_password_change + dominfo->min_password_age > t)) {
2177 if (reject->reason != SAMR_REJECT_OTHER) {
2178 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2179 SAMR_REJECT_OTHER, reject->reason);
2183 } else if ((dominfo->min_password_length > 0) &&
2184 (strlen(newpass) < dominfo->min_password_length)) {
2186 if (reject->reason != SAMR_REJECT_TOO_SHORT) {
2187 printf("expected SAMR_REJECT_TOO_SHORT (%d), got %d\n",
2188 SAMR_REJECT_TOO_SHORT, reject->reason);
2192 } else if ((dominfo->password_history_length > 0) &&
2193 strequal(oldpass, newpass)) {
2195 if (reject->reason != SAMR_REJECT_IN_HISTORY) {
2196 printf("expected SAMR_REJECT_IN_HISTORY (%d), got %d\n",
2197 SAMR_REJECT_IN_HISTORY, reject->reason);
2200 } else if (dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
2202 if (reject->reason != SAMR_REJECT_COMPLEXITY) {
2203 printf("expected SAMR_REJECT_COMPLEXITY (%d), got %d\n",
2204 SAMR_REJECT_COMPLEXITY, reject->reason);
2210 if (reject->reason == SAMR_REJECT_TOO_SHORT) {
2211 /* retry with adjusted size */
2212 return test_ChangePasswordUser3(p, tctx, account_string,
2213 dominfo->min_password_length,
2214 password, NULL, 0, false);
2218 } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2219 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2220 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2221 SAMR_REJECT_OTHER, reject->reason);
2224 /* Perhaps the server has a 'min password age' set? */
2227 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3");
2228 *password = talloc_strdup(tctx, newpass);
2234 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_context *tctx,
2235 const char *account_string,
2236 struct policy_handle *handle,
2240 struct samr_ChangePasswordUser3 r;
2241 struct samr_SetUserInfo s;
2242 union samr_UserInfo u;
2243 DATA_BLOB session_key;
2244 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
2245 uint8_t confounder[16];
2246 struct MD5Context ctx;
2249 struct lsa_String server, account;
2250 struct samr_CryptPassword nt_pass;
2251 struct samr_Password nt_verifier;
2252 DATA_BLOB new_random_pass;
2255 uint8_t old_nt_hash[16], new_nt_hash[16];
2257 struct samr_DomInfo1 *dominfo = NULL;
2258 struct samr_ChangeReject *reject = NULL;
2260 new_random_pass = samr_very_rand_pass(tctx, 128);
2262 torture_assert(tctx, *password != NULL,
2263 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2265 oldpass = *password;
2266 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2267 init_lsa_String(&account, account_string);
2269 s.in.user_handle = handle;
2275 u.info25.info.fields_present = SAMR_FIELD_NT_PASSWORD_PRESENT;
2277 set_pw_in_buffer(u.info25.password.data, &new_random_pass);
2279 status = dcerpc_fetch_session_key(p, &session_key);
2280 if (!NT_STATUS_IS_OK(status)) {
2281 printf("SetUserInfo level %u - no session key - %s\n",
2282 s.in.level, nt_errstr(status));
2286 generate_random_buffer((uint8_t *)confounder, 16);
2289 MD5Update(&ctx, confounder, 16);
2290 MD5Update(&ctx, session_key.data, session_key.length);
2291 MD5Final(confounded_session_key.data, &ctx);
2293 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
2294 memcpy(&u.info25.password.data[516], confounder, 16);
2296 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
2298 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
2299 if (!NT_STATUS_IS_OK(status)) {
2300 printf("SetUserInfo level %u failed - %s\n",
2301 s.in.level, nt_errstr(status));
2305 torture_comment(tctx, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
2307 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2309 new_random_pass = samr_very_rand_pass(tctx, 128);
2311 mdfour(new_nt_hash, new_random_pass.data, new_random_pass.length);
2313 set_pw_in_buffer(nt_pass.data, &new_random_pass);
2314 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2315 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2317 r.in.server = &server;
2318 r.in.account = &account;
2319 r.in.nt_password = &nt_pass;
2320 r.in.nt_verifier = &nt_verifier;
2322 r.in.lm_password = NULL;
2323 r.in.lm_verifier = NULL;
2324 r.in.password3 = NULL;
2325 r.out.dominfo = &dominfo;
2326 r.out.reject = &reject;
2328 unix_to_nt_time(&t, time(NULL));
2330 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2332 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2333 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2334 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2335 SAMR_REJECT_OTHER, reject->reason);
2338 /* Perhaps the server has a 'min password age' set? */
2340 } else if (!NT_STATUS_IS_OK(status)) {
2341 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
2345 newpass = samr_rand_pass(tctx, 128);
2347 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2349 E_md4hash(newpass, new_nt_hash);
2351 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2352 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2353 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2355 r.in.server = &server;
2356 r.in.account = &account;
2357 r.in.nt_password = &nt_pass;
2358 r.in.nt_verifier = &nt_verifier;
2360 r.in.lm_password = NULL;
2361 r.in.lm_verifier = NULL;
2362 r.in.password3 = NULL;
2363 r.out.dominfo = &dominfo;
2364 r.out.reject = &reject;
2366 unix_to_nt_time(&t, time(NULL));
2368 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2370 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2371 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2372 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2373 SAMR_REJECT_OTHER, reject->reason);
2376 /* Perhaps the server has a 'min password age' set? */
2379 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3 (on second random password)");
2380 *password = talloc_strdup(tctx, newpass);
2387 static bool test_GetMembersInAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2388 struct policy_handle *alias_handle)
2390 struct samr_GetMembersInAlias r;
2391 struct lsa_SidArray sids;
2394 torture_comment(tctx, "Testing GetMembersInAlias\n");
2396 r.in.alias_handle = alias_handle;
2399 status = dcerpc_samr_GetMembersInAlias(p, tctx, &r);
2400 torture_assert_ntstatus_ok(tctx, status, "GetMembersInAlias");
2405 static bool test_AddMemberToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2406 struct policy_handle *alias_handle,
2407 const struct dom_sid *domain_sid)
2409 struct samr_AddAliasMember r;
2410 struct samr_DeleteAliasMember d;
2412 struct dom_sid *sid;
2414 sid = dom_sid_add_rid(tctx, domain_sid, 512);
2416 torture_comment(tctx, "testing AddAliasMember\n");
2417 r.in.alias_handle = alias_handle;
2420 status = dcerpc_samr_AddAliasMember(p, tctx, &r);
2421 torture_assert_ntstatus_ok(tctx, status, "AddAliasMember");
2423 d.in.alias_handle = alias_handle;
2426 status = dcerpc_samr_DeleteAliasMember(p, tctx, &d);
2427 torture_assert_ntstatus_ok(tctx, status, "DelAliasMember");
2432 static bool test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2433 struct policy_handle *alias_handle)
2435 struct samr_AddMultipleMembersToAlias a;
2436 struct samr_RemoveMultipleMembersFromAlias r;
2438 struct lsa_SidArray sids;
2440 torture_comment(tctx, "testing AddMultipleMembersToAlias\n");
2441 a.in.alias_handle = alias_handle;
2445 sids.sids = talloc_array(tctx, struct lsa_SidPtr, 3);
2447 sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2448 sids.sids[1].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-2");
2449 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-3");
2451 status = dcerpc_samr_AddMultipleMembersToAlias(p, tctx, &a);
2452 torture_assert_ntstatus_ok(tctx, status, "AddMultipleMembersToAlias");
2455 torture_comment(tctx, "testing RemoveMultipleMembersFromAlias\n");
2456 r.in.alias_handle = alias_handle;
2459 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2460 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2462 /* strange! removing twice doesn't give any error */
2463 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2464 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2466 /* but removing an alias that isn't there does */
2467 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-4");
2469 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2470 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, "RemoveMultipleMembersFromAlias");
2475 static bool test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2476 struct policy_handle *user_handle)
2478 struct samr_TestPrivateFunctionsUser r;
2481 torture_comment(tctx, "Testing TestPrivateFunctionsUser\n");
2483 r.in.user_handle = user_handle;
2485 status = dcerpc_samr_TestPrivateFunctionsUser(p, tctx, &r);
2486 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsUser");
2491 static bool test_QueryUserInfo_pwdlastset(struct dcerpc_pipe *p,
2492 struct torture_context *tctx,
2493 struct policy_handle *handle,
2498 uint16_t levels[] = { /* 3, */ 5, 21 };
2500 NTTIME pwdlastset3 = 0;
2501 NTTIME pwdlastset5 = 0;
2502 NTTIME pwdlastset21 = 0;
2504 torture_comment(tctx, "Testing QueryUserInfo%s level 5 and 21 call ",
2505 use_info2 ? "2":"");
2507 for (i=0; i<ARRAY_SIZE(levels); i++) {
2509 struct samr_QueryUserInfo r;
2510 struct samr_QueryUserInfo2 r2;
2511 union samr_UserInfo *info;
2514 r2.in.user_handle = handle;
2515 r2.in.level = levels[i];
2516 r2.out.info = &info;
2517 status = dcerpc_samr_QueryUserInfo2(p, tctx, &r2);
2520 r.in.user_handle = handle;
2521 r.in.level = levels[i];
2523 status = dcerpc_samr_QueryUserInfo(p, tctx, &r);
2526 if (!NT_STATUS_IS_OK(status) &&
2527 !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
2528 printf("QueryUserInfo%s level %u failed - %s\n",
2529 use_info2 ? "2":"", levels[i], nt_errstr(status));
2533 switch (levels[i]) {
2535 pwdlastset3 = info->info3.last_password_change;
2538 pwdlastset5 = info->info5.last_password_change;
2541 pwdlastset21 = info->info21.last_password_change;
2547 /* torture_assert_int_equal(tctx, pwdlastset3, pwdlastset5,
2548 "pwdlastset mixup"); */
2549 torture_assert_int_equal(tctx, pwdlastset5, pwdlastset21,
2550 "pwdlastset mixup");
2552 *pwdlastset = pwdlastset21;
2554 torture_comment(tctx, "(pwdlastset: %lld)\n", *pwdlastset);
2559 static bool test_SetPassword_level(struct dcerpc_pipe *p,
2560 struct torture_context *tctx,
2561 struct policy_handle *handle,
2563 uint32_t fields_present,
2564 uint8_t password_expired,
2565 bool *matched_expected_error,
2568 bool use_queryinfo2,
2571 const char *fields = NULL;
2578 fields = talloc_asprintf(tctx, "(fields_present: 0x%08x)",
2585 torture_comment(tctx, "Testing SetUserInfo%s level %d call "
2586 "(password_expired: %d) %s\n",
2587 use_setinfo2 ? "2":"", level, password_expired,
2588 fields ? fields : "");
2596 if (!test_SetUserPass_level_ex(p, tctx, handle, level,
2601 matched_expected_error)) {
2609 if (!test_QueryUserInfo_pwdlastset(p, tctx, handle,
2618 static bool test_SetPassword_pwdlastset(struct dcerpc_pipe *p,
2619 struct torture_context *tctx,
2620 uint32_t acct_flags,
2621 struct policy_handle *handle,
2624 int i, s = 0, q = 0, f = 0;
2627 bool set_levels[] = { false, true };
2628 bool query_levels[] = { false, true };
2629 uint32_t fields_present[] = {
2631 SAMR_FIELD_EXPIRED_FLAG,
2632 SAMR_FIELD_LAST_PWD_CHANGE,
2633 SAMR_FIELD_EXPIRED_FLAG | SAMR_FIELD_LAST_PWD_CHANGE,
2635 SAMR_FIELD_NT_PASSWORD_PRESENT,
2636 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
2637 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
2638 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
2639 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
2640 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
2641 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE | SAMR_FIELD_EXPIRED_FLAG
2646 uint8_t password_expired_nonzero;
2652 .password_expired_nonzero = 1,
2655 .password_expired_nonzero = 24,
2660 .password_expired_nonzero = 1,
2663 .password_expired_nonzero = 24,
2669 .password_expired_nonzero = 1,
2672 .password_expired_nonzero = 24,
2678 .password_expired_nonzero = 1,
2681 .password_expired_nonzero = 24
2687 .password_expired_nonzero = 1,
2690 .password_expired_nonzero = 24,
2694 if (torture_setting_bool(tctx, "samba3", false)) {
2696 printf("Samba3 has second granularity, setting delay to: %d\n",
2700 /* set to 1 to enable testing for all possible opcode
2701 (SetUserInfo, SetUserInfo2, QueryUserInfo, QueryUserInfo2)
2704 #define TEST_SET_LEVELS 1
2705 #define TEST_QUERY_LEVELS 1
2707 for (i=0; i<ARRAY_SIZE(pwd_tests); i++) {
2708 for (f=0; f<ARRAY_SIZE(fields_present); f++) {
2709 #ifdef TEST_SET_LEVELS
2710 for (s=0; s<ARRAY_SIZE(set_levels); s++) {
2712 #ifdef TEST_QUERY_LEVELS
2713 for (q=0; q<ARRAY_SIZE(query_levels); q++) {
2715 NTTIME pwdlastset_old = 0;
2716 NTTIME pwdlastset_new = 0;
2717 bool matched_expected_error = false;
2719 torture_comment(tctx, "------------------------------\n"
2720 "Testing pwdLastSet attribute for flags: 0x%08x "
2721 "(s: %d (l: %d), q: %d)\n",
2722 acct_flags, s, pwd_tests[i].level, q);
2726 /* set a password and force password change (pwdlastset 0) by
2727 * setting the password expired flag to a non-0 value */
2729 if (!test_SetPassword_level(p, tctx, handle,
2732 pwd_tests[i].password_expired_nonzero,
2733 &matched_expected_error,
2741 if (matched_expected_error == true) {
2742 /* skipping on expected failure */
2746 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
2747 * set without the SAMR_FIELD_EXPIRED_FLAG */
2749 switch (pwd_tests[i].level) {
2753 if ((pwdlastset_new != 0) &&
2754 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
2755 torture_comment(tctx, "not considering a non-0 "
2756 "pwdLastSet as a an error as the "
2757 "SAMR_FIELD_EXPIRED_FLAG has not "
2762 if (pwdlastset_new != 0) {
2763 torture_warning(tctx, "pwdLastSet test failed: "
2764 "expected pwdLastSet 0 but got %lld\n",
2771 switch (pwd_tests[i].level) {
2775 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
2776 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
2777 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
2778 (pwdlastset_old >= pwdlastset_new)) {
2779 torture_warning(tctx, "pwdlastset not increasing\n");
2784 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
2785 (pwdlastset_old >= pwdlastset_new)) {
2786 torture_warning(tctx, "pwdlastset not increasing\n");
2796 /* set a password, pwdlastset needs to get updated (increased
2797 * value), password_expired value used here is 0 */
2799 if (!test_SetPassword_level(p, tctx, handle,
2803 &matched_expected_error,
2811 /* when a password has been changed, pwdlastset must not be 0 afterwards
2812 * and must be larger then the old value */
2814 switch (pwd_tests[i].level) {
2819 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
2820 * password has been changed, old and new pwdlastset
2821 * need to be the same value */
2823 if (!(pwd_tests[i].fields_present & SAMR_FIELD_EXPIRED_FLAG) &&
2824 !((pwd_tests[i].fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
2825 (pwd_tests[i].fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)))
2827 torture_assert_int_equal(tctx, pwdlastset_old,
2828 pwdlastset_new, "pwdlastset must be equal");
2832 if (pwdlastset_old >= pwdlastset_new) {
2833 torture_warning(tctx, "pwdLastSet test failed: "
2834 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
2835 pwdlastset_old, pwdlastset_new);
2838 if (pwdlastset_new == 0) {
2839 torture_warning(tctx, "pwdLastSet test failed: "
2840 "expected non-0 pwdlastset, got: %lld\n",
2846 switch (pwd_tests[i].level) {
2850 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
2851 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
2852 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
2853 (pwdlastset_old >= pwdlastset_new)) {
2854 torture_warning(tctx, "pwdlastset not increasing\n");
2859 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
2860 (pwdlastset_old >= pwdlastset_new)) {
2861 torture_warning(tctx, "pwdlastset not increasing\n");
2867 pwdlastset_old = pwdlastset_new;
2873 /* set a password, pwdlastset needs to get updated (increased
2874 * value), password_expired value used here is 0 */
2876 if (!test_SetPassword_level(p, tctx, handle,
2880 &matched_expected_error,
2888 /* when a password has been changed, pwdlastset must not be 0 afterwards
2889 * and must be larger then the old value */
2891 switch (pwd_tests[i].level) {
2896 /* if no password has been changed, old and new pwdlastset
2897 * need to be the same value */
2899 if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
2900 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
2902 torture_assert_int_equal(tctx, pwdlastset_old,
2903 pwdlastset_new, "pwdlastset must be equal");
2907 if (pwdlastset_old >= pwdlastset_new) {
2908 torture_warning(tctx, "pwdLastSet test failed: "
2909 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
2910 pwdlastset_old, pwdlastset_new);
2913 if (pwdlastset_new == 0) {
2914 torture_warning(tctx, "pwdLastSet test failed: "
2915 "expected non-0 pwdlastset, got: %lld\n",
2923 /* set a password and force password change (pwdlastset 0) by
2924 * setting the password expired flag to a non-0 value */
2926 if (!test_SetPassword_level(p, tctx, handle,
2929 pwd_tests[i].password_expired_nonzero,
2930 &matched_expected_error,
2938 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
2939 * set without the SAMR_FIELD_EXPIRED_FLAG */
2941 switch (pwd_tests[i].level) {
2945 if ((pwdlastset_new != 0) &&
2946 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
2947 torture_comment(tctx, "not considering a non-0 "
2948 "pwdLastSet as a an error as the "
2949 "SAMR_FIELD_EXPIRED_FLAG has not "
2954 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
2955 * password has been changed, old and new pwdlastset
2956 * need to be the same value */
2958 if (!(pwd_tests[i].fields_present & SAMR_FIELD_EXPIRED_FLAG) &&
2959 !((pwd_tests[i].fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
2960 (pwd_tests[i].fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)))
2962 torture_assert_int_equal(tctx, pwdlastset_old,
2963 pwdlastset_new, "pwdlastset must be equal");
2968 if (pwdlastset_old == pwdlastset_new) {
2969 torture_warning(tctx, "pwdLastSet test failed: "
2970 "expected last pwdlastset (%lld) != new pwdlastset (%lld)\n",
2971 pwdlastset_old, pwdlastset_new);
2975 if (pwdlastset_new != 0) {
2976 torture_warning(tctx, "pwdLastSet test failed: "
2977 "expected pwdLastSet 0, got %lld\n",
2984 switch (pwd_tests[i].level) {
2988 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
2989 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
2990 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
2991 (pwdlastset_old >= pwdlastset_new)) {
2992 torture_warning(tctx, "pwdlastset not increasing\n");
2997 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
2998 (pwdlastset_old >= pwdlastset_new)) {
2999 torture_warning(tctx, "pwdlastset not increasing\n");
3005 switch (pwd_tests[i].level) {
3008 f = ARRAY_SIZE(fields_present);
3012 #ifdef TEST_QUERY_LEVELS
3015 #ifdef TEST_SET_LEVELS
3021 #undef TEST_SET_LEVELS
3022 #undef TEST_QUERY_LEVELS
3027 static bool test_user_ops(struct dcerpc_pipe *p,
3028 struct torture_context *tctx,
3029 struct policy_handle *user_handle,
3030 struct policy_handle *domain_handle,
3031 uint32_t base_acct_flags,
3032 const char *base_acct_name, enum torture_samr_choice which_ops)
3034 char *password = NULL;
3035 struct samr_QueryUserInfo q;
3036 union samr_UserInfo *info;
3042 const uint32_t password_fields[] = {
3043 SAMR_FIELD_NT_PASSWORD_PRESENT,
3044 SAMR_FIELD_LM_PASSWORD_PRESENT,
3045 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
3049 status = test_LookupName(p, tctx, domain_handle, base_acct_name, &rid);
3050 if (!NT_STATUS_IS_OK(status)) {
3054 switch (which_ops) {
3055 case TORTURE_SAMR_USER_ATTRIBUTES:
3056 if (!test_QuerySecurity(p, tctx, user_handle)) {
3060 if (!test_QueryUserInfo(p, tctx, user_handle)) {
3064 if (!test_QueryUserInfo2(p, tctx, user_handle)) {
3068 if (!test_SetUserInfo(p, tctx, user_handle, base_acct_flags,
3073 if (!test_GetUserPwInfo(p, tctx, user_handle)) {
3077 if (!test_TestPrivateFunctionsUser(p, tctx, user_handle)) {
3081 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
3085 case TORTURE_SAMR_PASSWORDS:
3086 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
3087 char simple_pass[9];
3088 char *v = generate_random_str(tctx, 1);
3090 ZERO_STRUCT(simple_pass);
3091 memset(simple_pass, *v, sizeof(simple_pass) - 1);
3093 printf("Testing machine account password policy rules\n");
3095 /* Workstation trust accounts don't seem to need to honour password quality policy */
3096 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
3100 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
3104 /* reset again, to allow another 'user' password change */
3105 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
3109 /* Try a 'short' password */
3110 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
3114 /* Try a compleatly random password */
3115 if (!test_ChangePasswordRandomBytes(p, tctx, base_acct_name, user_handle, &password)) {
3120 for (i = 0; password_fields[i]; i++) {
3121 if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
3125 /* check it was set right */
3126 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3131 for (i = 0; password_fields[i]; i++) {
3132 if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {