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
7 Copyright (C) Guenther Deschner 2008-2010
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "torture/torture.h"
25 #include "system/time.h"
26 #include "librpc/gen_ndr/lsa.h"
27 #include "librpc/gen_ndr/ndr_netlogon.h"
28 #include "librpc/gen_ndr/ndr_netlogon_c.h"
29 #include "librpc/gen_ndr/ndr_samr_c.h"
30 #include "librpc/gen_ndr/ndr_lsa_c.h"
31 #include "../lib/crypto/crypto.h"
32 #include "libcli/auth/libcli_auth.h"
33 #include "libcli/security/security.h"
34 #include "torture/rpc/rpc.h"
35 #include "param/param.h"
36 #include "auth/gensec/gensec.h"
37 #include "auth/gensec/gensec_proto.h"
38 #include "../libcli/auth/schannel.h"
39 #include "auth/gensec/schannel_state.h"
43 #define TEST_ACCOUNT_NAME "samrtorturetest"
44 #define TEST_ACCOUNT_NAME_PWD "samrpwdlastset"
45 #define TEST_ALIASNAME "samrtorturetestalias"
46 #define TEST_GROUPNAME "samrtorturetestgroup"
47 #define TEST_MACHINENAME "samrtestmach$"
48 #define TEST_DOMAINNAME "samrtestdom$"
50 enum torture_samr_choice {
51 TORTURE_SAMR_PASSWORDS,
52 TORTURE_SAMR_PASSWORDS_PWDLASTSET,
53 TORTURE_SAMR_PASSWORDS_BADPWDCOUNT,
54 TORTURE_SAMR_USER_ATTRIBUTES,
55 TORTURE_SAMR_USER_PRIVILEGES,
57 TORTURE_SAMR_MANY_ACCOUNTS,
58 TORTURE_SAMR_MANY_GROUPS,
59 TORTURE_SAMR_MANY_ALIASES
62 struct torture_samr_context {
63 struct policy_handle handle;
64 struct cli_credentials *machine_credentials;
65 enum torture_samr_choice choice;
66 uint32_t num_objects_large_dc;
69 static bool test_QueryUserInfo(struct dcerpc_pipe *p,
70 struct torture_context *tctx,
71 struct policy_handle *handle);
73 static bool test_QueryUserInfo2(struct dcerpc_pipe *p,
74 struct torture_context *tctx,
75 struct policy_handle *handle);
77 static bool test_QueryAliasInfo(struct dcerpc_pipe *p,
78 struct torture_context *tctx,
79 struct policy_handle *handle);
81 static bool test_ChangePassword(struct dcerpc_pipe *p,
82 struct torture_context *tctx,
83 const char *acct_name,
84 struct policy_handle *domain_handle, char **password);
86 static void init_lsa_String(struct lsa_String *string, const char *s)
91 static void init_lsa_StringLarge(struct lsa_StringLarge *string, const char *s)
96 static void init_lsa_BinaryString(struct lsa_BinaryString *string, const char *s, uint32_t length)
98 string->length = length;
99 string->size = length;
100 string->array = (uint16_t *)discard_const(s);
103 bool test_samr_handle_Close(struct dcerpc_pipe *p, struct torture_context *tctx,
104 struct policy_handle *handle)
109 r.in.handle = handle;
110 r.out.handle = handle;
112 status = dcerpc_samr_Close(p, tctx, &r);
113 torture_assert_ntstatus_ok(tctx, status, "Close");
118 static bool test_Shutdown(struct dcerpc_pipe *p, struct torture_context *tctx,
119 struct policy_handle *handle)
122 struct samr_Shutdown r;
124 if (!torture_setting_bool(tctx, "dangerous", false)) {
125 torture_skip(tctx, "samr_Shutdown disabled - enable dangerous tests to use\n");
129 r.in.connect_handle = handle;
131 torture_comment(tctx, "testing samr_Shutdown\n");
133 status = dcerpc_samr_Shutdown(p, tctx, &r);
134 torture_assert_ntstatus_ok(tctx, status, "samr_Shutdown");
139 static bool test_SetDsrmPassword(struct dcerpc_pipe *p, struct torture_context *tctx,
140 struct policy_handle *handle)
143 struct samr_SetDsrmPassword r;
144 struct lsa_String string;
145 struct samr_Password hash;
147 if (!torture_setting_bool(tctx, "dangerous", false)) {
148 torture_skip(tctx, "samr_SetDsrmPassword disabled - enable dangerous tests to use");
151 E_md4hash("TeSTDSRM123", hash.hash);
153 init_lsa_String(&string, "Administrator");
159 torture_comment(tctx, "testing samr_SetDsrmPassword\n");
161 status = dcerpc_samr_SetDsrmPassword(p, tctx, &r);
162 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_SUPPORTED, "samr_SetDsrmPassword");
168 static bool test_QuerySecurity(struct dcerpc_pipe *p,
169 struct torture_context *tctx,
170 struct policy_handle *handle)
173 struct samr_QuerySecurity r;
174 struct samr_SetSecurity s;
175 struct sec_desc_buf *sdbuf = NULL;
177 r.in.handle = handle;
179 r.out.sdbuf = &sdbuf;
181 status = dcerpc_samr_QuerySecurity(p, tctx, &r);
182 torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
184 torture_assert(tctx, sdbuf != NULL, "sdbuf is NULL");
186 s.in.handle = handle;
190 if (torture_setting_bool(tctx, "samba4", false)) {
191 torture_skip(tctx, "skipping SetSecurity test against Samba4\n");
194 status = dcerpc_samr_SetSecurity(p, tctx, &s);
195 torture_assert_ntstatus_ok(tctx, status, "SetSecurity");
197 status = dcerpc_samr_QuerySecurity(p, tctx, &r);
198 torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
204 static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
205 struct policy_handle *handle, uint32_t base_acct_flags,
206 const char *base_account_name)
209 struct samr_SetUserInfo s;
210 struct samr_SetUserInfo2 s2;
211 struct samr_QueryUserInfo q;
212 struct samr_QueryUserInfo q0;
213 union samr_UserInfo u;
214 union samr_UserInfo *info;
216 const char *test_account_name;
218 uint32_t user_extra_flags = 0;
220 if (!torture_setting_bool(tctx, "samba3", false)) {
221 if (base_acct_flags == ACB_NORMAL) {
222 /* When created, accounts are expired by default */
223 user_extra_flags = ACB_PW_EXPIRED;
227 s.in.user_handle = handle;
230 s2.in.user_handle = handle;
233 q.in.user_handle = handle;
237 #define TESTCALL(call, r) \
238 status = dcerpc_samr_ ##call(p, tctx, &r); \
239 if (!NT_STATUS_IS_OK(status)) { \
240 torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
241 r.in.level, nt_errstr(status), __location__); \
246 #define STRING_EQUAL(s1, s2, field) \
247 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
248 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
249 #field, s2, __location__); \
254 #define MEM_EQUAL(s1, s2, length, field) \
255 if ((s1 && !s2) || (s2 && !s1) || memcmp(s1, s2, length)) { \
256 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
257 #field, (const char *)s2, __location__); \
262 #define INT_EQUAL(i1, i2, field) \
264 torture_comment(tctx, "Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \
265 #field, (unsigned long long)i2, (unsigned long long)i1, __location__); \
270 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
271 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
273 TESTCALL(QueryUserInfo, q) \
275 s2.in.level = lvl1; \
278 ZERO_STRUCT(u.info21); \
279 u.info21.fields_present = fpval; \
281 init_lsa_String(&u.info ## lvl1.field1, value); \
282 TESTCALL(SetUserInfo, s) \
283 TESTCALL(SetUserInfo2, s2) \
284 init_lsa_String(&u.info ## lvl1.field1, ""); \
285 TESTCALL(QueryUserInfo, q); \
287 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
289 TESTCALL(QueryUserInfo, q) \
291 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
294 #define TEST_USERINFO_BINARYSTRING(lvl1, field1, lvl2, field2, value, fpval) do { \
295 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
297 TESTCALL(QueryUserInfo, q) \
299 s2.in.level = lvl1; \
302 ZERO_STRUCT(u.info21); \
303 u.info21.fields_present = fpval; \
305 init_lsa_BinaryString(&u.info ## lvl1.field1, value, strlen(value)); \
306 TESTCALL(SetUserInfo, s) \
307 TESTCALL(SetUserInfo2, s2) \
308 init_lsa_BinaryString(&u.info ## lvl1.field1, "", 1); \
309 TESTCALL(QueryUserInfo, q); \
311 MEM_EQUAL(u.info ## lvl1.field1.array, value, strlen(value), field1); \
313 TESTCALL(QueryUserInfo, q) \
315 MEM_EQUAL(u.info ## lvl2.field2.array, value, strlen(value), field2); \
318 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
319 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
321 TESTCALL(QueryUserInfo, q) \
323 s2.in.level = lvl1; \
326 uint8_t *bits = u.info21.logon_hours.bits; \
327 ZERO_STRUCT(u.info21); \
328 if (fpval == SAMR_FIELD_LOGON_HOURS) { \
329 u.info21.logon_hours.units_per_week = 168; \
330 u.info21.logon_hours.bits = bits; \
332 u.info21.fields_present = fpval; \
334 u.info ## lvl1.field1 = value; \
335 TESTCALL(SetUserInfo, s) \
336 TESTCALL(SetUserInfo2, s2) \
337 u.info ## lvl1.field1 = 0; \
338 TESTCALL(QueryUserInfo, q); \
340 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
342 TESTCALL(QueryUserInfo, q) \
344 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
347 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
348 TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
352 do { TESTCALL(QueryUserInfo, q0) } while (0);
354 TEST_USERINFO_STRING(2, comment, 1, comment, "xx2-1 comment", 0);
355 TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
356 TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment",
359 test_account_name = talloc_asprintf(tctx, "%sxx7-1", base_account_name);
360 TEST_USERINFO_STRING(7, account_name, 1, account_name, base_account_name, 0);
361 test_account_name = talloc_asprintf(tctx, "%sxx7-3", base_account_name);
362 TEST_USERINFO_STRING(7, account_name, 3, account_name, base_account_name, 0);
363 test_account_name = talloc_asprintf(tctx, "%sxx7-5", base_account_name);
364 TEST_USERINFO_STRING(7, account_name, 5, account_name, base_account_name, 0);
365 test_account_name = talloc_asprintf(tctx, "%sxx7-6", base_account_name);
366 TEST_USERINFO_STRING(7, account_name, 6, account_name, base_account_name, 0);
367 test_account_name = talloc_asprintf(tctx, "%sxx7-7", base_account_name);
368 TEST_USERINFO_STRING(7, account_name, 7, account_name, base_account_name, 0);
369 test_account_name = talloc_asprintf(tctx, "%sxx7-21", base_account_name);
370 TEST_USERINFO_STRING(7, account_name, 21, account_name, base_account_name, 0);
371 test_account_name = base_account_name;
372 TEST_USERINFO_STRING(21, account_name, 21, account_name, base_account_name,
373 SAMR_FIELD_ACCOUNT_NAME);
375 TEST_USERINFO_STRING(6, full_name, 1, full_name, "xx6-1 full_name", 0);
376 TEST_USERINFO_STRING(6, full_name, 3, full_name, "xx6-3 full_name", 0);
377 TEST_USERINFO_STRING(6, full_name, 5, full_name, "xx6-5 full_name", 0);
378 TEST_USERINFO_STRING(6, full_name, 6, full_name, "xx6-6 full_name", 0);
379 TEST_USERINFO_STRING(6, full_name, 8, full_name, "xx6-8 full_name", 0);
380 TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
381 TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
382 TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name",
383 SAMR_FIELD_FULL_NAME);
385 TEST_USERINFO_STRING(6, full_name, 1, full_name, "", 0);
386 TEST_USERINFO_STRING(6, full_name, 3, full_name, "", 0);
387 TEST_USERINFO_STRING(6, full_name, 5, full_name, "", 0);
388 TEST_USERINFO_STRING(6, full_name, 6, full_name, "", 0);
389 TEST_USERINFO_STRING(6, full_name, 8, full_name, "", 0);
390 TEST_USERINFO_STRING(6, full_name, 21, full_name, "", 0);
391 TEST_USERINFO_STRING(8, full_name, 21, full_name, "", 0);
392 TEST_USERINFO_STRING(21, full_name, 21, full_name, "",
393 SAMR_FIELD_FULL_NAME);
395 TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
396 TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
397 TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
398 TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script",
399 SAMR_FIELD_LOGON_SCRIPT);
401 TEST_USERINFO_STRING(12, profile_path, 3, profile_path, "xx12-3 profile_path", 0);
402 TEST_USERINFO_STRING(12, profile_path, 5, profile_path, "xx12-5 profile_path", 0);
403 TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
404 TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path",
405 SAMR_FIELD_PROFILE_PATH);
407 TEST_USERINFO_STRING(10, home_directory, 3, home_directory, "xx10-3 home_directory", 0);
408 TEST_USERINFO_STRING(10, home_directory, 5, home_directory, "xx10-5 home_directory", 0);
409 TEST_USERINFO_STRING(10, home_directory, 21, home_directory, "xx10-21 home_directory", 0);
410 TEST_USERINFO_STRING(21, home_directory, 21, home_directory, "xx21-21 home_directory",
411 SAMR_FIELD_HOME_DIRECTORY);
412 TEST_USERINFO_STRING(21, home_directory, 10, home_directory, "xx21-10 home_directory",
413 SAMR_FIELD_HOME_DIRECTORY);
415 TEST_USERINFO_STRING(10, home_drive, 3, home_drive, "xx10-3 home_drive", 0);
416 TEST_USERINFO_STRING(10, home_drive, 5, home_drive, "xx10-5 home_drive", 0);
417 TEST_USERINFO_STRING(10, home_drive, 21, home_drive, "xx10-21 home_drive", 0);
418 TEST_USERINFO_STRING(21, home_drive, 21, home_drive, "xx21-21 home_drive",
419 SAMR_FIELD_HOME_DRIVE);
420 TEST_USERINFO_STRING(21, home_drive, 10, home_drive, "xx21-10 home_drive",
421 SAMR_FIELD_HOME_DRIVE);
423 TEST_USERINFO_STRING(13, description, 1, description, "xx13-1 description", 0);
424 TEST_USERINFO_STRING(13, description, 5, description, "xx13-5 description", 0);
425 TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
426 TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description",
427 SAMR_FIELD_DESCRIPTION);
429 TEST_USERINFO_STRING(14, workstations, 3, workstations, "14workstation3", 0);
430 TEST_USERINFO_STRING(14, workstations, 5, workstations, "14workstation4", 0);
431 TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
432 TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21",
433 SAMR_FIELD_WORKSTATIONS);
434 TEST_USERINFO_STRING(21, workstations, 3, workstations, "21workstation3",
435 SAMR_FIELD_WORKSTATIONS);
436 TEST_USERINFO_STRING(21, workstations, 5, workstations, "21workstation5",
437 SAMR_FIELD_WORKSTATIONS);
438 TEST_USERINFO_STRING(21, workstations, 14, workstations, "21workstation14",
439 SAMR_FIELD_WORKSTATIONS);
441 TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
442 TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "xx21-21 parameters",
443 SAMR_FIELD_PARAMETERS);
444 TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "xx21-20 parameters",
445 SAMR_FIELD_PARAMETERS);
446 /* also empty user parameters are allowed */
447 TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "", 0);
448 TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "",
449 SAMR_FIELD_PARAMETERS);
450 TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "",
451 SAMR_FIELD_PARAMETERS);
453 /* Samba 3 cannot store country_code and copy_page atm. - gd */
454 if (!torture_setting_bool(tctx, "samba3", false)) {
455 TEST_USERINFO_INT(2, country_code, 2, country_code, __LINE__, 0);
456 TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
457 TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__,
458 SAMR_FIELD_COUNTRY_CODE);
459 TEST_USERINFO_INT(21, country_code, 2, country_code, __LINE__,
460 SAMR_FIELD_COUNTRY_CODE);
462 TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
463 TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__,
464 SAMR_FIELD_CODE_PAGE);
465 TEST_USERINFO_INT(21, code_page, 2, code_page, __LINE__,
466 SAMR_FIELD_CODE_PAGE);
469 if (!torture_setting_bool(tctx, "samba3", false)) {
470 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, __LINE__, 0);
471 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, __LINE__, 0);
472 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, __LINE__,
473 SAMR_FIELD_ACCT_EXPIRY);
474 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, __LINE__,
475 SAMR_FIELD_ACCT_EXPIRY);
476 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, __LINE__,
477 SAMR_FIELD_ACCT_EXPIRY);
479 /* Samba 3 can only store seconds / time_t in passdb - gd */
481 unix_to_nt_time(&nt, time(NULL) + __LINE__);
482 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, nt, 0);
483 unix_to_nt_time(&nt, time(NULL) + __LINE__);
484 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, nt, 0);
485 unix_to_nt_time(&nt, time(NULL) + __LINE__);
486 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
487 unix_to_nt_time(&nt, time(NULL) + __LINE__);
488 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
489 unix_to_nt_time(&nt, time(NULL) + __LINE__);
490 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
493 TEST_USERINFO_INT(4, logon_hours.bits[3], 3, logon_hours.bits[3], 1, 0);
494 TEST_USERINFO_INT(4, logon_hours.bits[3], 5, logon_hours.bits[3], 2, 0);
495 TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
496 TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4,
497 SAMR_FIELD_LOGON_HOURS);
499 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
500 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
501 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
503 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
504 (base_acct_flags | ACB_DISABLED),
505 (base_acct_flags | ACB_DISABLED | user_extra_flags),
508 /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
509 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
510 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
511 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
513 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
514 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
515 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
519 /* The 'autolock' flag doesn't stick - check this */
520 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
521 (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK),
522 (base_acct_flags | ACB_DISABLED | user_extra_flags),
525 /* Removing the 'disabled' flag doesn't stick - check this */
526 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
528 (base_acct_flags | ACB_DISABLED | user_extra_flags),
532 /* Samba3 cannot store these atm */
533 if (!torture_setting_bool(tctx, "samba3", false)) {
534 /* The 'store plaintext' flag does stick */
535 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
536 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED),
537 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags),
539 /* The 'use DES' flag does stick */
540 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
541 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY),
542 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags),
544 /* The 'don't require kerberos pre-authentication flag does stick */
545 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
546 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH),
547 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags),
549 /* The 'no kerberos PAC required' flag sticks */
550 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
551 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD),
552 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags),
555 TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags,
556 (base_acct_flags | ACB_DISABLED),
557 (base_acct_flags | ACB_DISABLED | user_extra_flags),
558 SAMR_FIELD_ACCT_FLAGS);
561 /* these fail with win2003 - it appears you can't set the primary gid?
562 the set succeeds, but the gid isn't changed. Very weird! */
563 TEST_USERINFO_INT(9, primary_gid, 1, primary_gid, 513);
564 TEST_USERINFO_INT(9, primary_gid, 3, primary_gid, 513);
565 TEST_USERINFO_INT(9, primary_gid, 5, primary_gid, 513);
566 TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
573 generate a random password for password change tests
575 static char *samr_rand_pass_silent(TALLOC_CTX *mem_ctx, int min_len)
577 size_t len = MAX(8, min_len) + (random() % 6);
578 char *s = generate_random_str(mem_ctx, len);
582 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
584 char *s = samr_rand_pass_silent(mem_ctx, min_len);
585 printf("Generated password '%s'\n", s);
591 generate a random password for password change tests
593 static DATA_BLOB samr_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
596 DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
597 generate_random_buffer(password.data, password.length);
599 for (i=0; i < len; i++) {
600 if (((uint16_t *)password.data)[i] == 0) {
601 ((uint16_t *)password.data)[i] = 1;
609 generate a random password for password change tests (fixed length)
611 static char *samr_rand_pass_fixed_len(TALLOC_CTX *mem_ctx, int len)
613 char *s = generate_random_str(mem_ctx, len);
614 printf("Generated password '%s'\n", s);
618 static bool test_SetUserPass(struct dcerpc_pipe *p, struct torture_context *tctx,
619 struct policy_handle *handle, char **password)
622 struct samr_SetUserInfo s;
623 union samr_UserInfo u;
625 DATA_BLOB session_key;
627 struct samr_GetUserPwInfo pwp;
628 struct samr_PwInfo info;
629 int policy_min_pw_len = 0;
630 pwp.in.user_handle = handle;
631 pwp.out.info = &info;
633 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
634 if (NT_STATUS_IS_OK(status)) {
635 policy_min_pw_len = pwp.out.info->min_password_length;
637 newpass = samr_rand_pass(tctx, policy_min_pw_len);
639 s.in.user_handle = handle;
643 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
644 u.info24.password_expired = 0;
646 status = dcerpc_fetch_session_key(p, &session_key);
647 if (!NT_STATUS_IS_OK(status)) {
648 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
649 s.in.level, nt_errstr(status));
653 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
655 torture_comment(tctx, "Testing SetUserInfo level 24 (set password)\n");
657 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
658 if (!NT_STATUS_IS_OK(status)) {
659 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
660 s.in.level, nt_errstr(status));
670 static bool test_SetUserPass_23(struct dcerpc_pipe *p, struct torture_context *tctx,
671 struct policy_handle *handle, uint32_t fields_present,
675 struct samr_SetUserInfo s;
676 union samr_UserInfo u;
678 DATA_BLOB session_key;
680 struct samr_GetUserPwInfo pwp;
681 struct samr_PwInfo info;
682 int policy_min_pw_len = 0;
683 pwp.in.user_handle = handle;
684 pwp.out.info = &info;
686 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
687 if (NT_STATUS_IS_OK(status)) {
688 policy_min_pw_len = pwp.out.info->min_password_length;
690 newpass = samr_rand_pass(tctx, policy_min_pw_len);
692 s.in.user_handle = handle;
698 u.info23.info.fields_present = fields_present;
700 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
702 status = dcerpc_fetch_session_key(p, &session_key);
703 if (!NT_STATUS_IS_OK(status)) {
704 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
705 s.in.level, nt_errstr(status));
709 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
711 torture_comment(tctx, "Testing SetUserInfo level 23 (set password)\n");
713 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
714 if (!NT_STATUS_IS_OK(status)) {
715 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
716 s.in.level, nt_errstr(status));
722 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
724 status = dcerpc_fetch_session_key(p, &session_key);
725 if (!NT_STATUS_IS_OK(status)) {
726 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
727 s.in.level, nt_errstr(status));
731 /* This should break the key nicely */
732 session_key.length--;
733 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
735 torture_comment(tctx, "Testing SetUserInfo level 23 (set password) with wrong password\n");
737 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
738 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
739 torture_warning(tctx, "SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
740 s.in.level, nt_errstr(status));
748 static bool test_SetUserPassEx(struct dcerpc_pipe *p, struct torture_context *tctx,
749 struct policy_handle *handle, bool makeshort,
753 struct samr_SetUserInfo s;
754 union samr_UserInfo u;
756 DATA_BLOB session_key;
757 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
758 uint8_t confounder[16];
760 struct MD5Context ctx;
761 struct samr_GetUserPwInfo pwp;
762 struct samr_PwInfo info;
763 int policy_min_pw_len = 0;
764 pwp.in.user_handle = handle;
765 pwp.out.info = &info;
767 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
768 if (NT_STATUS_IS_OK(status)) {
769 policy_min_pw_len = pwp.out.info->min_password_length;
771 if (makeshort && policy_min_pw_len) {
772 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len - 1);
774 newpass = samr_rand_pass(tctx, policy_min_pw_len);
777 s.in.user_handle = handle;
781 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
782 u.info26.password_expired = 0;
784 status = dcerpc_fetch_session_key(p, &session_key);
785 if (!NT_STATUS_IS_OK(status)) {
786 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
787 s.in.level, nt_errstr(status));
791 generate_random_buffer((uint8_t *)confounder, 16);
794 MD5Update(&ctx, confounder, 16);
795 MD5Update(&ctx, session_key.data, session_key.length);
796 MD5Final(confounded_session_key.data, &ctx);
798 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
799 memcpy(&u.info26.password.data[516], confounder, 16);
801 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex)\n");
803 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
804 if (!NT_STATUS_IS_OK(status)) {
805 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
806 s.in.level, nt_errstr(status));
812 /* This should break the key nicely */
813 confounded_session_key.data[0]++;
815 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
816 memcpy(&u.info26.password.data[516], confounder, 16);
818 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
820 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
821 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
822 torture_warning(tctx, "SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
823 s.in.level, nt_errstr(status));
832 static bool test_SetUserPass_25(struct dcerpc_pipe *p, struct torture_context *tctx,
833 struct policy_handle *handle, uint32_t fields_present,
837 struct samr_SetUserInfo s;
838 union samr_UserInfo u;
840 DATA_BLOB session_key;
841 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
842 struct MD5Context ctx;
843 uint8_t confounder[16];
845 struct samr_GetUserPwInfo pwp;
846 struct samr_PwInfo info;
847 int policy_min_pw_len = 0;
848 pwp.in.user_handle = handle;
849 pwp.out.info = &info;
851 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
852 if (NT_STATUS_IS_OK(status)) {
853 policy_min_pw_len = pwp.out.info->min_password_length;
855 newpass = samr_rand_pass(tctx, policy_min_pw_len);
857 s.in.user_handle = handle;
863 u.info25.info.fields_present = fields_present;
865 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
867 status = dcerpc_fetch_session_key(p, &session_key);
868 if (!NT_STATUS_IS_OK(status)) {
869 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
870 s.in.level, nt_errstr(status));
874 generate_random_buffer((uint8_t *)confounder, 16);
877 MD5Update(&ctx, confounder, 16);
878 MD5Update(&ctx, session_key.data, session_key.length);
879 MD5Final(confounded_session_key.data, &ctx);
881 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
882 memcpy(&u.info25.password.data[516], confounder, 16);
884 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex)\n");
886 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
887 if (!NT_STATUS_IS_OK(status)) {
888 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
889 s.in.level, nt_errstr(status));
895 /* This should break the key nicely */
896 confounded_session_key.data[0]++;
898 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
899 memcpy(&u.info25.password.data[516], confounder, 16);
901 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
903 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
904 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
905 torture_warning(tctx, "SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
906 s.in.level, nt_errstr(status));
913 static bool test_SetUserPass_18(struct dcerpc_pipe *p, struct torture_context *tctx,
914 struct policy_handle *handle, char **password)
917 struct samr_SetUserInfo s;
918 union samr_UserInfo u;
920 DATA_BLOB session_key;
922 struct samr_GetUserPwInfo pwp;
923 struct samr_PwInfo info;
924 int policy_min_pw_len = 0;
925 uint8_t lm_hash[16], nt_hash[16];
927 pwp.in.user_handle = handle;
928 pwp.out.info = &info;
930 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
931 if (NT_STATUS_IS_OK(status)) {
932 policy_min_pw_len = pwp.out.info->min_password_length;
934 newpass = samr_rand_pass(tctx, policy_min_pw_len);
936 s.in.user_handle = handle;
942 u.info18.nt_pwd_active = true;
943 u.info18.lm_pwd_active = true;
945 E_md4hash(newpass, nt_hash);
946 E_deshash(newpass, lm_hash);
948 status = dcerpc_fetch_session_key(p, &session_key);
949 if (!NT_STATUS_IS_OK(status)) {
950 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
951 s.in.level, nt_errstr(status));
957 in = data_blob_const(nt_hash, 16);
958 out = data_blob_talloc_zero(tctx, 16);
959 sess_crypt_blob(&out, &in, &session_key, true);
960 memcpy(u.info18.nt_pwd.hash, out.data, out.length);
964 in = data_blob_const(lm_hash, 16);
965 out = data_blob_talloc_zero(tctx, 16);
966 sess_crypt_blob(&out, &in, &session_key, true);
967 memcpy(u.info18.lm_pwd.hash, out.data, out.length);
970 torture_comment(tctx, "Testing SetUserInfo level 18 (set password hash)\n");
972 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
973 if (!NT_STATUS_IS_OK(status)) {
974 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
975 s.in.level, nt_errstr(status));
984 static bool test_SetUserPass_21(struct dcerpc_pipe *p, struct torture_context *tctx,
985 struct policy_handle *handle, uint32_t fields_present,
989 struct samr_SetUserInfo s;
990 union samr_UserInfo u;
992 DATA_BLOB session_key;
994 struct samr_GetUserPwInfo pwp;
995 struct samr_PwInfo info;
996 int policy_min_pw_len = 0;
997 uint8_t lm_hash[16], nt_hash[16];
999 pwp.in.user_handle = handle;
1000 pwp.out.info = &info;
1002 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1003 if (NT_STATUS_IS_OK(status)) {
1004 policy_min_pw_len = pwp.out.info->min_password_length;
1006 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1008 s.in.user_handle = handle;
1012 E_md4hash(newpass, nt_hash);
1013 E_deshash(newpass, lm_hash);
1017 u.info21.fields_present = fields_present;
1019 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1020 u.info21.lm_owf_password.length = 16;
1021 u.info21.lm_owf_password.size = 16;
1022 u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
1023 u.info21.lm_password_set = true;
1026 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1027 u.info21.nt_owf_password.length = 16;
1028 u.info21.nt_owf_password.size = 16;
1029 u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
1030 u.info21.nt_password_set = true;
1033 status = dcerpc_fetch_session_key(p, &session_key);
1034 if (!NT_STATUS_IS_OK(status)) {
1035 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
1036 s.in.level, nt_errstr(status));
1040 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1042 in = data_blob_const(u.info21.lm_owf_password.array,
1043 u.info21.lm_owf_password.length);
1044 out = data_blob_talloc_zero(tctx, 16);
1045 sess_crypt_blob(&out, &in, &session_key, true);
1046 u.info21.lm_owf_password.array = (uint16_t *)out.data;
1049 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1051 in = data_blob_const(u.info21.nt_owf_password.array,
1052 u.info21.nt_owf_password.length);
1053 out = data_blob_talloc_zero(tctx, 16);
1054 sess_crypt_blob(&out, &in, &session_key, true);
1055 u.info21.nt_owf_password.array = (uint16_t *)out.data;
1058 torture_comment(tctx, "Testing SetUserInfo level 21 (set password hash)\n");
1060 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1061 if (!NT_STATUS_IS_OK(status)) {
1062 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
1063 s.in.level, nt_errstr(status));
1066 *password = newpass;
1069 /* try invalid length */
1070 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1072 u.info21.nt_owf_password.length++;
1074 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1076 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1077 torture_warning(tctx, "SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1078 s.in.level, nt_errstr(status));
1083 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1085 u.info21.lm_owf_password.length++;
1087 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1089 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1090 torture_warning(tctx, "SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1091 s.in.level, nt_errstr(status));
1099 static bool test_SetUserPass_level_ex(struct dcerpc_pipe *p,
1100 struct torture_context *tctx,
1101 struct policy_handle *handle,
1103 uint32_t fields_present,
1104 char **password, uint8_t password_expired,
1106 bool *matched_expected_error)
1109 NTSTATUS expected_error = NT_STATUS_OK;
1110 struct samr_SetUserInfo s;
1111 struct samr_SetUserInfo2 s2;
1112 union samr_UserInfo u;
1114 DATA_BLOB session_key;
1115 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
1116 struct MD5Context ctx;
1117 uint8_t confounder[16];
1119 struct samr_GetUserPwInfo pwp;
1120 struct samr_PwInfo info;
1121 int policy_min_pw_len = 0;
1122 const char *comment = NULL;
1123 uint8_t lm_hash[16], nt_hash[16];
1125 pwp.in.user_handle = handle;
1126 pwp.out.info = &info;
1128 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1129 if (NT_STATUS_IS_OK(status)) {
1130 policy_min_pw_len = pwp.out.info->min_password_length;
1132 newpass = samr_rand_pass_silent(tctx, policy_min_pw_len);
1135 s2.in.user_handle = handle;
1137 s2.in.level = level;
1139 s.in.user_handle = handle;
1144 if (fields_present & SAMR_FIELD_COMMENT) {
1145 comment = talloc_asprintf(tctx, "comment: %ld\n", time(NULL));
1152 E_md4hash(newpass, nt_hash);
1153 E_deshash(newpass, lm_hash);
1155 u.info18.nt_pwd_active = true;
1156 u.info18.lm_pwd_active = true;
1157 u.info18.password_expired = password_expired;
1159 memcpy(u.info18.lm_pwd.hash, lm_hash, 16);
1160 memcpy(u.info18.nt_pwd.hash, nt_hash, 16);
1164 E_md4hash(newpass, nt_hash);
1165 E_deshash(newpass, lm_hash);
1167 u.info21.fields_present = fields_present;
1168 u.info21.password_expired = password_expired;
1169 u.info21.comment.string = comment;
1171 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1172 u.info21.lm_owf_password.length = 16;
1173 u.info21.lm_owf_password.size = 16;
1174 u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
1175 u.info21.lm_password_set = true;
1178 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1179 u.info21.nt_owf_password.length = 16;
1180 u.info21.nt_owf_password.size = 16;
1181 u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
1182 u.info21.nt_password_set = true;
1187 u.info23.info.fields_present = fields_present;
1188 u.info23.info.password_expired = password_expired;
1189 u.info23.info.comment.string = comment;
1191 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
1195 u.info24.password_expired = password_expired;
1197 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
1201 u.info25.info.fields_present = fields_present;
1202 u.info25.info.password_expired = password_expired;
1203 u.info25.info.comment.string = comment;
1205 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
1209 u.info26.password_expired = password_expired;
1211 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
1216 status = dcerpc_fetch_session_key(p, &session_key);
1217 if (!NT_STATUS_IS_OK(status)) {
1218 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
1219 s.in.level, nt_errstr(status));
1223 generate_random_buffer((uint8_t *)confounder, 16);
1226 MD5Update(&ctx, confounder, 16);
1227 MD5Update(&ctx, session_key.data, session_key.length);
1228 MD5Final(confounded_session_key.data, &ctx);
1234 in = data_blob_const(u.info18.nt_pwd.hash, 16);
1235 out = data_blob_talloc_zero(tctx, 16);
1236 sess_crypt_blob(&out, &in, &session_key, true);
1237 memcpy(u.info18.nt_pwd.hash, out.data, out.length);
1241 in = data_blob_const(u.info18.lm_pwd.hash, 16);
1242 out = data_blob_talloc_zero(tctx, 16);
1243 sess_crypt_blob(&out, &in, &session_key, true);
1244 memcpy(u.info18.lm_pwd.hash, out.data, out.length);
1249 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1251 in = data_blob_const(u.info21.lm_owf_password.array,
1252 u.info21.lm_owf_password.length);
1253 out = data_blob_talloc_zero(tctx, 16);
1254 sess_crypt_blob(&out, &in, &session_key, true);
1255 u.info21.lm_owf_password.array = (uint16_t *)out.data;
1257 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1259 in = data_blob_const(u.info21.nt_owf_password.array,
1260 u.info21.nt_owf_password.length);
1261 out = data_blob_talloc_zero(tctx, 16);
1262 sess_crypt_blob(&out, &in, &session_key, true);
1263 u.info21.nt_owf_password.array = (uint16_t *)out.data;
1267 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
1270 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
1273 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
1274 memcpy(&u.info25.password.data[516], confounder, 16);
1277 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
1278 memcpy(&u.info26.password.data[516], confounder, 16);
1283 status = dcerpc_samr_SetUserInfo2(p, tctx, &s2);
1285 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1288 if (!NT_STATUS_IS_OK(status)) {
1289 if (fields_present == 0) {
1290 expected_error = NT_STATUS_INVALID_PARAMETER;
1292 if (fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
1293 expected_error = NT_STATUS_ACCESS_DENIED;
1297 if (!NT_STATUS_IS_OK(expected_error)) {
1299 torture_assert_ntstatus_equal(tctx,
1301 expected_error, "SetUserInfo2 failed");
1303 torture_assert_ntstatus_equal(tctx,
1305 expected_error, "SetUserInfo failed");
1307 *matched_expected_error = true;
1311 if (!NT_STATUS_IS_OK(status)) {
1312 torture_warning(tctx, "SetUserInfo%s level %u failed - %s\n",
1313 use_setinfo2 ? "2":"", level, nt_errstr(status));
1316 *password = newpass;
1322 static bool test_SetAliasInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1323 struct policy_handle *handle)
1326 struct samr_SetAliasInfo r;
1327 struct samr_QueryAliasInfo q;
1328 union samr_AliasInfo *info;
1329 uint16_t levels[] = {2, 3};
1333 /* Ignoring switch level 1, as that includes the number of members for the alias
1334 * and setting this to a wrong value might have negative consequences
1337 for (i=0;i<ARRAY_SIZE(levels);i++) {
1338 torture_comment(tctx, "Testing SetAliasInfo level %u\n", levels[i]);
1340 r.in.alias_handle = handle;
1341 r.in.level = levels[i];
1342 r.in.info = talloc(tctx, union samr_AliasInfo);
1343 switch (r.in.level) {
1344 case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
1345 case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
1346 "Test Description, should test I18N as well"); break;
1347 case ALIASINFOALL: torture_comment(tctx, "ALIASINFOALL ignored\n"); break;
1350 status = dcerpc_samr_SetAliasInfo(p, tctx, &r);
1351 if (!NT_STATUS_IS_OK(status)) {
1352 torture_warning(tctx, "SetAliasInfo level %u failed - %s\n",
1353 levels[i], nt_errstr(status));
1357 q.in.alias_handle = handle;
1358 q.in.level = levels[i];
1361 status = dcerpc_samr_QueryAliasInfo(p, tctx, &q);
1362 if (!NT_STATUS_IS_OK(status)) {
1363 torture_warning(tctx, "QueryAliasInfo level %u failed - %s\n",
1364 levels[i], nt_errstr(status));
1372 static bool test_GetGroupsForUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1373 struct policy_handle *user_handle)
1375 struct samr_GetGroupsForUser r;
1376 struct samr_RidWithAttributeArray *rids = NULL;
1379 torture_comment(tctx, "testing GetGroupsForUser\n");
1381 r.in.user_handle = user_handle;
1384 status = dcerpc_samr_GetGroupsForUser(p, tctx, &r);
1385 torture_assert_ntstatus_ok(tctx, status, "GetGroupsForUser");
1391 static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1392 struct lsa_String *domain_name)
1395 struct samr_GetDomPwInfo r;
1396 struct samr_PwInfo info;
1398 r.in.domain_name = domain_name;
1401 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1403 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1404 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1406 r.in.domain_name->string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1407 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1409 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1410 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1412 r.in.domain_name->string = "\\\\__NONAME__";
1413 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1415 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1416 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1418 r.in.domain_name->string = "\\\\Builtin";
1419 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1421 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1422 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1427 static bool test_GetUserPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1428 struct policy_handle *handle)
1431 struct samr_GetUserPwInfo r;
1432 struct samr_PwInfo info;
1434 torture_comment(tctx, "Testing GetUserPwInfo\n");
1436 r.in.user_handle = handle;
1439 status = dcerpc_samr_GetUserPwInfo(p, tctx, &r);
1440 torture_assert_ntstatus_ok(tctx, status, "GetUserPwInfo");
1445 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, struct torture_context *tctx,
1446 struct policy_handle *domain_handle, const char *name,
1450 struct samr_LookupNames n;
1451 struct lsa_String sname[2];
1452 struct samr_Ids rids, types;
1454 init_lsa_String(&sname[0], name);
1456 n.in.domain_handle = domain_handle;
1460 n.out.types = &types;
1461 status = dcerpc_samr_LookupNames(p, tctx, &n);
1462 if (NT_STATUS_IS_OK(status)) {
1463 *rid = n.out.rids->ids[0];
1468 init_lsa_String(&sname[1], "xxNONAMExx");
1470 status = dcerpc_samr_LookupNames(p, tctx, &n);
1471 if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
1472 torture_warning(tctx, "LookupNames[2] failed - %s\n", nt_errstr(status));
1473 if (NT_STATUS_IS_OK(status)) {
1474 return NT_STATUS_UNSUCCESSFUL;
1480 status = dcerpc_samr_LookupNames(p, tctx, &n);
1481 if (!NT_STATUS_IS_OK(status)) {
1482 torture_warning(tctx, "LookupNames[0] failed - %s\n", nt_errstr(status));
1486 init_lsa_String(&sname[0], "xxNONAMExx");
1488 status = dcerpc_samr_LookupNames(p, tctx, &n);
1489 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1490 torture_warning(tctx, "LookupNames[1 bad name] failed - %s\n", nt_errstr(status));
1491 if (NT_STATUS_IS_OK(status)) {
1492 return NT_STATUS_UNSUCCESSFUL;
1497 init_lsa_String(&sname[0], "xxNONAMExx");
1498 init_lsa_String(&sname[1], "xxNONAME2xx");
1500 status = dcerpc_samr_LookupNames(p, tctx, &n);
1501 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1502 torture_warning(tctx, "LookupNames[2 bad names] failed - %s\n", nt_errstr(status));
1503 if (NT_STATUS_IS_OK(status)) {
1504 return NT_STATUS_UNSUCCESSFUL;
1509 return NT_STATUS_OK;
1512 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p,
1513 struct torture_context *tctx,
1514 struct policy_handle *domain_handle,
1515 const char *name, struct policy_handle *user_handle)
1518 struct samr_OpenUser r;
1521 status = test_LookupName(p, tctx, domain_handle, name, &rid);
1522 if (!NT_STATUS_IS_OK(status)) {
1526 r.in.domain_handle = domain_handle;
1527 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1529 r.out.user_handle = user_handle;
1530 status = dcerpc_samr_OpenUser(p, tctx, &r);
1531 if (!NT_STATUS_IS_OK(status)) {
1532 torture_warning(tctx, "OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(status));
1539 static bool test_ChangePasswordNT3(struct dcerpc_pipe *p,
1540 struct torture_context *tctx,
1541 struct policy_handle *handle)
1544 struct samr_ChangePasswordUser r;
1546 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1547 struct policy_handle user_handle;
1548 char *oldpass = "test";
1549 char *newpass = "test2";
1550 uint8_t old_nt_hash[16], new_nt_hash[16];
1551 uint8_t old_lm_hash[16], new_lm_hash[16];
1553 status = test_OpenUser_byname(p, tctx, handle, "testuser", &user_handle);
1554 if (!NT_STATUS_IS_OK(status)) {
1558 torture_comment(tctx, "Testing ChangePasswordUser for user 'testuser'\n");
1560 torture_comment(tctx, "old password: %s\n", oldpass);
1561 torture_comment(tctx, "new password: %s\n", newpass);
1563 E_md4hash(oldpass, old_nt_hash);
1564 E_md4hash(newpass, new_nt_hash);
1565 E_deshash(oldpass, old_lm_hash);
1566 E_deshash(newpass, new_lm_hash);
1568 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1569 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1570 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1571 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1572 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1573 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1575 r.in.handle = &user_handle;
1576 r.in.lm_present = 1;
1577 r.in.old_lm_crypted = &hash1;
1578 r.in.new_lm_crypted = &hash2;
1579 r.in.nt_present = 1;
1580 r.in.old_nt_crypted = &hash3;
1581 r.in.new_nt_crypted = &hash4;
1582 r.in.cross1_present = 1;
1583 r.in.nt_cross = &hash5;
1584 r.in.cross2_present = 1;
1585 r.in.lm_cross = &hash6;
1587 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1588 if (!NT_STATUS_IS_OK(status)) {
1589 torture_warning(tctx, "ChangePasswordUser failed - %s\n", nt_errstr(status));
1593 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
1601 static bool test_ChangePasswordUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1602 const char *acct_name,
1603 struct policy_handle *handle, char **password)
1606 struct samr_ChangePasswordUser r;
1608 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1609 struct policy_handle user_handle;
1611 uint8_t old_nt_hash[16], new_nt_hash[16];
1612 uint8_t old_lm_hash[16], new_lm_hash[16];
1613 bool changed = true;
1616 struct samr_GetUserPwInfo pwp;
1617 struct samr_PwInfo info;
1618 int policy_min_pw_len = 0;
1620 status = test_OpenUser_byname(p, tctx, handle, acct_name, &user_handle);
1621 if (!NT_STATUS_IS_OK(status)) {
1624 pwp.in.user_handle = &user_handle;
1625 pwp.out.info = &info;
1627 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1628 if (NT_STATUS_IS_OK(status)) {
1629 policy_min_pw_len = pwp.out.info->min_password_length;
1631 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1633 torture_comment(tctx, "Testing ChangePasswordUser\n");
1635 torture_assert(tctx, *password != NULL,
1636 "Failing ChangePasswordUser as old password was NULL. Previous test failed?");
1638 oldpass = *password;
1640 E_md4hash(oldpass, old_nt_hash);
1641 E_md4hash(newpass, new_nt_hash);
1642 E_deshash(oldpass, old_lm_hash);
1643 E_deshash(newpass, new_lm_hash);
1645 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1646 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1647 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1648 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1649 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1650 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1652 r.in.user_handle = &user_handle;
1653 r.in.lm_present = 1;
1654 /* Break the LM hash */
1656 r.in.old_lm_crypted = &hash1;
1657 r.in.new_lm_crypted = &hash2;
1658 r.in.nt_present = 1;
1659 r.in.old_nt_crypted = &hash3;
1660 r.in.new_nt_crypted = &hash4;
1661 r.in.cross1_present = 1;
1662 r.in.nt_cross = &hash5;
1663 r.in.cross2_present = 1;
1664 r.in.lm_cross = &hash6;
1666 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1667 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1668 "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash");
1670 /* Unbreak the LM hash */
1673 r.in.user_handle = &user_handle;
1674 r.in.lm_present = 1;
1675 r.in.old_lm_crypted = &hash1;
1676 r.in.new_lm_crypted = &hash2;
1677 /* Break the NT hash */
1679 r.in.nt_present = 1;
1680 r.in.old_nt_crypted = &hash3;
1681 r.in.new_nt_crypted = &hash4;
1682 r.in.cross1_present = 1;
1683 r.in.nt_cross = &hash5;
1684 r.in.cross2_present = 1;
1685 r.in.lm_cross = &hash6;
1687 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1688 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1689 "expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash");
1691 /* Unbreak the NT hash */
1694 r.in.user_handle = &user_handle;
1695 r.in.lm_present = 1;
1696 r.in.old_lm_crypted = &hash1;
1697 r.in.new_lm_crypted = &hash2;
1698 r.in.nt_present = 1;
1699 r.in.old_nt_crypted = &hash3;
1700 r.in.new_nt_crypted = &hash4;
1701 r.in.cross1_present = 1;
1702 r.in.nt_cross = &hash5;
1703 r.in.cross2_present = 1;
1704 /* Break the LM cross */
1706 r.in.lm_cross = &hash6;
1708 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1709 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1710 torture_warning(tctx, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status));
1714 /* Unbreak the LM cross */
1717 r.in.user_handle = &user_handle;
1718 r.in.lm_present = 1;
1719 r.in.old_lm_crypted = &hash1;
1720 r.in.new_lm_crypted = &hash2;
1721 r.in.nt_present = 1;
1722 r.in.old_nt_crypted = &hash3;
1723 r.in.new_nt_crypted = &hash4;
1724 r.in.cross1_present = 1;
1725 /* Break the NT cross */
1727 r.in.nt_cross = &hash5;
1728 r.in.cross2_present = 1;
1729 r.in.lm_cross = &hash6;
1731 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1732 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1733 torture_warning(tctx, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status));
1737 /* Unbreak the NT cross */
1741 /* Reset the hashes to not broken values */
1742 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1743 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1744 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1745 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1746 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1747 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1749 r.in.user_handle = &user_handle;
1750 r.in.lm_present = 1;
1751 r.in.old_lm_crypted = &hash1;
1752 r.in.new_lm_crypted = &hash2;
1753 r.in.nt_present = 1;
1754 r.in.old_nt_crypted = &hash3;
1755 r.in.new_nt_crypted = &hash4;
1756 r.in.cross1_present = 1;
1757 r.in.nt_cross = &hash5;
1758 r.in.cross2_present = 0;
1759 r.in.lm_cross = NULL;
1761 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1762 if (NT_STATUS_IS_OK(status)) {
1764 *password = newpass;
1765 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1766 torture_warning(tctx, "ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(status));
1771 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1773 E_md4hash(oldpass, old_nt_hash);
1774 E_md4hash(newpass, new_nt_hash);
1775 E_deshash(oldpass, old_lm_hash);
1776 E_deshash(newpass, new_lm_hash);
1779 /* Reset the hashes to not broken values */
1780 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1781 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1782 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1783 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1784 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1785 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1787 r.in.user_handle = &user_handle;
1788 r.in.lm_present = 1;
1789 r.in.old_lm_crypted = &hash1;
1790 r.in.new_lm_crypted = &hash2;
1791 r.in.nt_present = 1;
1792 r.in.old_nt_crypted = &hash3;
1793 r.in.new_nt_crypted = &hash4;
1794 r.in.cross1_present = 0;
1795 r.in.nt_cross = NULL;
1796 r.in.cross2_present = 1;
1797 r.in.lm_cross = &hash6;
1799 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1800 if (NT_STATUS_IS_OK(status)) {
1802 *password = newpass;
1803 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1804 torture_warning(tctx, "ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status));
1809 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1811 E_md4hash(oldpass, old_nt_hash);
1812 E_md4hash(newpass, new_nt_hash);
1813 E_deshash(oldpass, old_lm_hash);
1814 E_deshash(newpass, new_lm_hash);
1817 /* Reset the hashes to not broken values */
1818 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1819 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1820 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1821 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1822 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1823 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1825 r.in.user_handle = &user_handle;
1826 r.in.lm_present = 1;
1827 r.in.old_lm_crypted = &hash1;
1828 r.in.new_lm_crypted = &hash2;
1829 r.in.nt_present = 1;
1830 r.in.old_nt_crypted = &hash3;
1831 r.in.new_nt_crypted = &hash4;
1832 r.in.cross1_present = 1;
1833 r.in.nt_cross = &hash5;
1834 r.in.cross2_present = 1;
1835 r.in.lm_cross = &hash6;
1837 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1838 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1839 torture_comment(tctx, "ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1840 } else if (!NT_STATUS_IS_OK(status)) {
1841 torture_warning(tctx, "ChangePasswordUser failed - %s\n", nt_errstr(status));
1845 *password = newpass;
1848 r.in.user_handle = &user_handle;
1849 r.in.lm_present = 1;
1850 r.in.old_lm_crypted = &hash1;
1851 r.in.new_lm_crypted = &hash2;
1852 r.in.nt_present = 1;
1853 r.in.old_nt_crypted = &hash3;
1854 r.in.new_nt_crypted = &hash4;
1855 r.in.cross1_present = 1;
1856 r.in.nt_cross = &hash5;
1857 r.in.cross2_present = 1;
1858 r.in.lm_cross = &hash6;
1861 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1862 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1863 torture_comment(tctx, "ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1864 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1865 torture_warning(tctx, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status));
1871 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
1879 static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
1880 const char *acct_name,
1881 struct policy_handle *handle, char **password)
1884 struct samr_OemChangePasswordUser2 r;
1886 struct samr_Password lm_verifier;
1887 struct samr_CryptPassword lm_pass;
1888 struct lsa_AsciiString server, account, account_bad;
1891 uint8_t old_lm_hash[16], new_lm_hash[16];
1893 struct samr_GetDomPwInfo dom_pw_info;
1894 struct samr_PwInfo info;
1895 int policy_min_pw_len = 0;
1897 struct lsa_String domain_name;
1899 domain_name.string = "";
1900 dom_pw_info.in.domain_name = &domain_name;
1901 dom_pw_info.out.info = &info;
1903 torture_comment(tctx, "Testing OemChangePasswordUser2\n");
1905 torture_assert(tctx, *password != NULL,
1906 "Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?");
1908 oldpass = *password;
1910 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
1911 if (NT_STATUS_IS_OK(status)) {
1912 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
1915 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1917 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1918 account.string = acct_name;
1920 E_deshash(oldpass, old_lm_hash);
1921 E_deshash(newpass, new_lm_hash);
1923 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1924 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1925 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1927 r.in.server = &server;
1928 r.in.account = &account;
1929 r.in.password = &lm_pass;
1930 r.in.hash = &lm_verifier;
1932 /* Break the verification */
1933 lm_verifier.hash[0]++;
1935 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1937 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1938 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1939 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1944 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1945 /* Break the old password */
1947 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1948 /* unbreak it for the next operation */
1950 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1952 r.in.server = &server;
1953 r.in.account = &account;
1954 r.in.password = &lm_pass;
1955 r.in.hash = &lm_verifier;
1957 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1959 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1960 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1961 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1966 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1967 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1969 r.in.server = &server;
1970 r.in.account = &account;
1971 r.in.password = &lm_pass;
1974 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1976 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1977 && !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1978 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
1983 /* This shouldn't be a valid name */
1984 account_bad.string = TEST_ACCOUNT_NAME "XX";
1985 r.in.account = &account_bad;
1987 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1989 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1990 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
1995 /* This shouldn't be a valid name */
1996 account_bad.string = TEST_ACCOUNT_NAME "XX";
1997 r.in.account = &account_bad;
1998 r.in.password = &lm_pass;
1999 r.in.hash = &lm_verifier;
2001 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
2003 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
2004 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
2009 /* This shouldn't be a valid name */
2010 account_bad.string = TEST_ACCOUNT_NAME "XX";
2011 r.in.account = &account_bad;
2012 r.in.password = NULL;
2013 r.in.hash = &lm_verifier;
2015 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
2017 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
2018 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
2023 E_deshash(oldpass, old_lm_hash);
2024 E_deshash(newpass, new_lm_hash);
2026 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
2027 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2028 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
2030 r.in.server = &server;
2031 r.in.account = &account;
2032 r.in.password = &lm_pass;
2033 r.in.hash = &lm_verifier;
2035 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
2036 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2037 torture_comment(tctx, "OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
2038 } else if (!NT_STATUS_IS_OK(status)) {
2039 torture_warning(tctx, "OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
2042 *password = newpass;
2049 static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
2050 const char *acct_name,
2052 char *newpass, bool allow_password_restriction)
2055 struct samr_ChangePasswordUser2 r;
2057 struct lsa_String server, account;
2058 struct samr_CryptPassword nt_pass, lm_pass;
2059 struct samr_Password nt_verifier, lm_verifier;
2061 uint8_t old_nt_hash[16], new_nt_hash[16];
2062 uint8_t old_lm_hash[16], new_lm_hash[16];
2064 struct samr_GetDomPwInfo dom_pw_info;
2065 struct samr_PwInfo info;
2067 struct lsa_String domain_name;
2069 domain_name.string = "";
2070 dom_pw_info.in.domain_name = &domain_name;
2071 dom_pw_info.out.info = &info;
2073 torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name);
2075 torture_assert(tctx, *password != NULL,
2076 "Failing ChangePasswordUser2 as old password was NULL. Previous test failed?");
2077 oldpass = *password;
2080 int policy_min_pw_len = 0;
2081 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
2082 if (NT_STATUS_IS_OK(status)) {
2083 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
2086 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2089 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2090 init_lsa_String(&account, acct_name);
2092 E_md4hash(oldpass, old_nt_hash);
2093 E_md4hash(newpass, new_nt_hash);
2095 E_deshash(oldpass, old_lm_hash);
2096 E_deshash(newpass, new_lm_hash);
2098 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
2099 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2100 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2102 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2103 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2104 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2106 r.in.server = &server;
2107 r.in.account = &account;
2108 r.in.nt_password = &nt_pass;
2109 r.in.nt_verifier = &nt_verifier;
2111 r.in.lm_password = &lm_pass;
2112 r.in.lm_verifier = &lm_verifier;
2114 status = dcerpc_samr_ChangePasswordUser2(p, tctx, &r);
2115 if (allow_password_restriction && NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2116 torture_comment(tctx, "ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
2117 } else if (!NT_STATUS_IS_OK(status)) {
2118 torture_warning(tctx, "ChangePasswordUser2 failed - %s\n", nt_errstr(status));
2121 *password = newpass;
2128 bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tctx,
2129 const char *account_string,
2130 int policy_min_pw_len,
2132 const char *newpass,
2133 NTTIME last_password_change,
2134 bool handle_reject_reason)
2137 struct samr_ChangePasswordUser3 r;
2139 struct lsa_String server, account, account_bad;
2140 struct samr_CryptPassword nt_pass, lm_pass;
2141 struct samr_Password nt_verifier, lm_verifier;
2143 uint8_t old_nt_hash[16], new_nt_hash[16];
2144 uint8_t old_lm_hash[16], new_lm_hash[16];
2146 struct samr_DomInfo1 *dominfo = NULL;
2147 struct userPwdChangeFailureInformation *reject = NULL;
2149 torture_comment(tctx, "Testing ChangePasswordUser3\n");
2151 if (newpass == NULL) {
2153 if (policy_min_pw_len == 0) {
2154 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2156 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len);
2158 } while (check_password_quality(newpass) == false);
2160 torture_comment(tctx, "Using password '%s'\n", newpass);
2163 torture_assert(tctx, *password != NULL,
2164 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2166 oldpass = *password;
2167 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2168 init_lsa_String(&account, account_string);
2170 E_md4hash(oldpass, old_nt_hash);
2171 E_md4hash(newpass, new_nt_hash);
2173 E_deshash(oldpass, old_lm_hash);
2174 E_deshash(newpass, new_lm_hash);
2176 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2177 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2178 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2180 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2181 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2182 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2184 /* Break the verification */
2185 nt_verifier.hash[0]++;
2187 r.in.server = &server;
2188 r.in.account = &account;
2189 r.in.nt_password = &nt_pass;
2190 r.in.nt_verifier = &nt_verifier;
2192 r.in.lm_password = &lm_pass;
2193 r.in.lm_verifier = &lm_verifier;
2194 r.in.password3 = NULL;
2195 r.out.dominfo = &dominfo;
2196 r.out.reject = &reject;
2198 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2199 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
2200 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
2201 torture_warning(tctx, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
2206 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2207 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2208 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2210 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2211 /* Break the NT hash */
2213 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2214 /* Unbreak it again */
2216 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2218 r.in.server = &server;
2219 r.in.account = &account;
2220 r.in.nt_password = &nt_pass;
2221 r.in.nt_verifier = &nt_verifier;
2223 r.in.lm_password = &lm_pass;
2224 r.in.lm_verifier = &lm_verifier;
2225 r.in.password3 = NULL;
2226 r.out.dominfo = &dominfo;
2227 r.out.reject = &reject;
2229 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2230 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
2231 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
2232 torture_warning(tctx, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
2237 /* This shouldn't be a valid name */
2238 init_lsa_String(&account_bad, talloc_asprintf(tctx, "%sXX", account_string));
2240 r.in.account = &account_bad;
2241 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2242 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
2243 torture_warning(tctx, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
2248 E_md4hash(oldpass, old_nt_hash);
2249 E_md4hash(newpass, new_nt_hash);
2251 E_deshash(oldpass, old_lm_hash);
2252 E_deshash(newpass, new_lm_hash);
2254 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2255 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2256 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2258 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2259 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2260 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2262 r.in.server = &server;
2263 r.in.account = &account;
2264 r.in.nt_password = &nt_pass;
2265 r.in.nt_verifier = &nt_verifier;
2267 r.in.lm_password = &lm_pass;
2268 r.in.lm_verifier = &lm_verifier;
2269 r.in.password3 = NULL;
2270 r.out.dominfo = &dominfo;
2271 r.out.reject = &reject;
2273 unix_to_nt_time(&t, time(NULL));
2275 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2277 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
2280 && handle_reject_reason
2281 && (!null_nttime(last_password_change) || !dominfo->min_password_age)) {
2282 if (dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
2284 if (reject && (reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR)) {
2285 torture_warning(tctx, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2286 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2291 /* We tested the order of precendence which is as follows:
2300 if ((dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
2301 (last_password_change + dominfo->min_password_age > t)) {
2303 if (reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2304 torture_warning(tctx, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2305 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2309 } else if ((dominfo->min_password_length > 0) &&
2310 (strlen(newpass) < dominfo->min_password_length)) {
2312 if (reject->extendedFailureReason != SAM_PWD_CHANGE_PASSWORD_TOO_SHORT) {
2313 torture_warning(tctx, "expected SAM_PWD_CHANGE_PASSWORD_TOO_SHORT (%d), got %d\n",
2314 SAM_PWD_CHANGE_PASSWORD_TOO_SHORT, reject->extendedFailureReason);
2318 } else if ((dominfo->password_history_length > 0) &&
2319 strequal(oldpass, newpass)) {
2321 if (reject->extendedFailureReason != SAM_PWD_CHANGE_PWD_IN_HISTORY) {
2322 torture_warning(tctx, "expected SAM_PWD_CHANGE_PWD_IN_HISTORY (%d), got %d\n",
2323 SAM_PWD_CHANGE_PWD_IN_HISTORY, reject->extendedFailureReason);
2326 } else if (dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
2328 if (reject->extendedFailureReason != SAM_PWD_CHANGE_NOT_COMPLEX) {
2329 torture_warning(tctx, "expected SAM_PWD_CHANGE_NOT_COMPLEX (%d), got %d\n",
2330 SAM_PWD_CHANGE_NOT_COMPLEX, reject->extendedFailureReason);
2336 if (reject->extendedFailureReason == SAM_PWD_CHANGE_PASSWORD_TOO_SHORT) {
2337 /* retry with adjusted size */
2338 return test_ChangePasswordUser3(p, tctx, account_string,
2339 dominfo->min_password_length,
2340 password, NULL, 0, false);
2344 } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2345 if (reject && reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2346 torture_warning(tctx, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2347 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2350 /* Perhaps the server has a 'min password age' set? */
2353 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3");
2354 *password = talloc_strdup(tctx, newpass);
2360 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_context *tctx,
2361 const char *account_string,
2362 struct policy_handle *handle,
2366 struct samr_ChangePasswordUser3 r;
2367 struct samr_SetUserInfo s;
2368 union samr_UserInfo u;
2369 DATA_BLOB session_key;
2370 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
2371 uint8_t confounder[16];
2372 struct MD5Context ctx;
2375 struct lsa_String server, account;
2376 struct samr_CryptPassword nt_pass;
2377 struct samr_Password nt_verifier;
2378 DATA_BLOB new_random_pass;
2381 uint8_t old_nt_hash[16], new_nt_hash[16];
2383 struct samr_DomInfo1 *dominfo = NULL;
2384 struct userPwdChangeFailureInformation *reject = NULL;
2386 new_random_pass = samr_very_rand_pass(tctx, 128);
2388 torture_assert(tctx, *password != NULL,
2389 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2391 oldpass = *password;
2392 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2393 init_lsa_String(&account, account_string);
2395 s.in.user_handle = handle;
2401 u.info25.info.fields_present = SAMR_FIELD_NT_PASSWORD_PRESENT;
2403 set_pw_in_buffer(u.info25.password.data, &new_random_pass);
2405 status = dcerpc_fetch_session_key(p, &session_key);
2406 if (!NT_STATUS_IS_OK(status)) {
2407 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
2408 s.in.level, nt_errstr(status));
2412 generate_random_buffer((uint8_t *)confounder, 16);
2415 MD5Update(&ctx, confounder, 16);
2416 MD5Update(&ctx, session_key.data, session_key.length);
2417 MD5Final(confounded_session_key.data, &ctx);
2419 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
2420 memcpy(&u.info25.password.data[516], confounder, 16);
2422 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
2424 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
2425 if (!NT_STATUS_IS_OK(status)) {
2426 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
2427 s.in.level, nt_errstr(status));
2431 torture_comment(tctx, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
2433 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2435 new_random_pass = samr_very_rand_pass(tctx, 128);
2437 mdfour(new_nt_hash, new_random_pass.data, new_random_pass.length);
2439 set_pw_in_buffer(nt_pass.data, &new_random_pass);
2440 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2441 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2443 r.in.server = &server;
2444 r.in.account = &account;
2445 r.in.nt_password = &nt_pass;
2446 r.in.nt_verifier = &nt_verifier;
2448 r.in.lm_password = NULL;
2449 r.in.lm_verifier = NULL;
2450 r.in.password3 = NULL;
2451 r.out.dominfo = &dominfo;
2452 r.out.reject = &reject;
2454 unix_to_nt_time(&t, time(NULL));
2456 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2458 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2459 if (reject && reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2460 torture_warning(tctx, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2461 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2464 /* Perhaps the server has a 'min password age' set? */
2466 } else if (!NT_STATUS_IS_OK(status)) {
2467 torture_warning(tctx, "ChangePasswordUser3 failed - %s\n", nt_errstr(status));
2471 newpass = samr_rand_pass(tctx, 128);
2473 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2475 E_md4hash(newpass, new_nt_hash);
2477 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2478 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2479 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2481 r.in.server = &server;
2482 r.in.account = &account;
2483 r.in.nt_password = &nt_pass;
2484 r.in.nt_verifier = &nt_verifier;
2486 r.in.lm_password = NULL;
2487 r.in.lm_verifier = NULL;
2488 r.in.password3 = NULL;
2489 r.out.dominfo = &dominfo;
2490 r.out.reject = &reject;
2492 unix_to_nt_time(&t, time(NULL));
2494 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2496 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2497 if (reject && reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2498 torture_warning(tctx, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2499 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2502 /* Perhaps the server has a 'min password age' set? */
2505 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3 (on second random password)");
2506 *password = talloc_strdup(tctx, newpass);
2513 static bool test_GetMembersInAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2514 struct policy_handle *alias_handle)
2516 struct samr_GetMembersInAlias r;
2517 struct lsa_SidArray sids;
2520 torture_comment(tctx, "Testing GetMembersInAlias\n");
2522 r.in.alias_handle = alias_handle;
2525 status = dcerpc_samr_GetMembersInAlias(p, tctx, &r);
2526 torture_assert_ntstatus_ok(tctx, status, "GetMembersInAlias");
2531 static bool test_AddMemberToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2532 struct policy_handle *alias_handle,
2533 const struct dom_sid *domain_sid)
2535 struct samr_AddAliasMember r;
2536 struct samr_DeleteAliasMember d;
2538 struct dom_sid *sid;
2540 sid = dom_sid_add_rid(tctx, domain_sid, 512);
2542 torture_comment(tctx, "testing AddAliasMember\n");
2543 r.in.alias_handle = alias_handle;
2546 status = dcerpc_samr_AddAliasMember(p, tctx, &r);
2547 torture_assert_ntstatus_ok(tctx, status, "AddAliasMember");
2549 d.in.alias_handle = alias_handle;
2552 status = dcerpc_samr_DeleteAliasMember(p, tctx, &d);
2553 torture_assert_ntstatus_ok(tctx, status, "DelAliasMember");
2558 static bool test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2559 struct policy_handle *alias_handle)
2561 struct samr_AddMultipleMembersToAlias a;
2562 struct samr_RemoveMultipleMembersFromAlias r;
2564 struct lsa_SidArray sids;
2566 torture_comment(tctx, "testing AddMultipleMembersToAlias\n");
2567 a.in.alias_handle = alias_handle;
2571 sids.sids = talloc_array(tctx, struct lsa_SidPtr, 3);
2573 sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2574 sids.sids[1].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-2");
2575 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-3");
2577 status = dcerpc_samr_AddMultipleMembersToAlias(p, tctx, &a);
2578 torture_assert_ntstatus_ok(tctx, status, "AddMultipleMembersToAlias");
2581 torture_comment(tctx, "testing RemoveMultipleMembersFromAlias\n");
2582 r.in.alias_handle = alias_handle;
2585 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2586 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2588 /* strange! removing twice doesn't give any error */
2589 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2590 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2592 /* but removing an alias that isn't there does */
2593 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-4");
2595 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2596 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, "RemoveMultipleMembersFromAlias");
2601 static bool test_GetAliasMembership(struct dcerpc_pipe *p,
2602 struct torture_context *tctx,
2603 struct policy_handle *domain_handle)
2605 struct samr_GetAliasMembership r;
2606 struct lsa_SidArray sids;
2607 struct samr_Ids rids;
2610 torture_comment(tctx, "Testing GetAliasMembership\n");
2612 if (torture_setting_bool(tctx, "samba4", false)) {
2613 torture_skip(tctx, "skipping GetAliasMembership against s4");
2616 r.in.domain_handle = domain_handle;
2621 sids.sids = talloc_zero_array(tctx, struct lsa_SidPtr, sids.num_sids);
2623 status = dcerpc_samr_GetAliasMembership(p, tctx, &r);
2624 torture_assert_ntstatus_ok(tctx, status,
2625 "samr_GetAliasMembership failed");
2627 torture_assert_int_equal(tctx, sids.num_sids, rids.count,
2628 "protocol misbehaviour");
2631 sids.sids = talloc_zero_array(tctx, struct lsa_SidPtr, sids.num_sids);
2632 sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2634 status = dcerpc_samr_GetAliasMembership(p, tctx, &r);
2635 torture_assert_ntstatus_ok(tctx, status,
2636 "samr_GetAliasMembership failed");
2639 /* only true for w2k8 it seems
2640 * win7, xp, w2k3 will return a 0 length array pointer */
2642 torture_assert(tctx, (rids.ids && !rids.count),
2643 "samr_GetAliasMembership protocol misbehaviour");
2645 torture_assert(tctx, (!rids.ids && rids.count),
2646 "samr_GetAliasMembership protocol misbehaviour");
2651 static bool test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2652 struct policy_handle *user_handle)
2654 struct samr_TestPrivateFunctionsUser r;
2657 torture_comment(tctx, "Testing TestPrivateFunctionsUser\n");
2659 r.in.user_handle = user_handle;
2661 status = dcerpc_samr_TestPrivateFunctionsUser(p, tctx, &r);
2662 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsUser");
2667 static bool test_QueryUserInfo_pwdlastset(struct dcerpc_pipe *p,
2668 struct torture_context *tctx,
2669 struct policy_handle *handle,
2674 uint16_t levels[] = { /* 3, */ 5, 21 };
2676 NTTIME pwdlastset3 = 0;
2677 NTTIME pwdlastset5 = 0;
2678 NTTIME pwdlastset21 = 0;
2680 torture_comment(tctx, "Testing QueryUserInfo%s level 5 and 21 call ",
2681 use_info2 ? "2":"");
2683 for (i=0; i<ARRAY_SIZE(levels); i++) {
2685 struct samr_QueryUserInfo r;
2686 struct samr_QueryUserInfo2 r2;
2687 union samr_UserInfo *info;
2690 r2.in.user_handle = handle;
2691 r2.in.level = levels[i];
2692 r2.out.info = &info;
2693 status = dcerpc_samr_QueryUserInfo2(p, tctx, &r2);
2696 r.in.user_handle = handle;
2697 r.in.level = levels[i];
2699 status = dcerpc_samr_QueryUserInfo(p, tctx, &r);
2702 if (!NT_STATUS_IS_OK(status) &&
2703 !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
2704 torture_warning(tctx, "QueryUserInfo%s level %u failed - %s\n",
2705 use_info2 ? "2":"", levels[i], nt_errstr(status));
2709 switch (levels[i]) {
2711 pwdlastset3 = info->info3.last_password_change;
2714 pwdlastset5 = info->info5.last_password_change;
2717 pwdlastset21 = info->info21.last_password_change;
2723 /* torture_assert_int_equal(tctx, pwdlastset3, pwdlastset5,
2724 "pwdlastset mixup"); */
2725 torture_assert_int_equal(tctx, pwdlastset5, pwdlastset21,
2726 "pwdlastset mixup");
2728 *pwdlastset = pwdlastset21;
2730 torture_comment(tctx, "(pwdlastset: %lld)\n", *pwdlastset);
2735 static bool test_SamLogon(struct torture_context *tctx,
2736 struct dcerpc_pipe *p,
2737 struct cli_credentials *test_credentials,
2738 NTSTATUS expected_result,
2742 struct netr_LogonSamLogonEx r;
2743 union netr_LogonLevel logon;
2744 union netr_Validation validation;
2745 uint8_t authoritative;
2746 struct netr_IdentityInfo identity;
2747 struct netr_NetworkInfo ninfo;
2748 struct netr_PasswordInfo pinfo;
2749 DATA_BLOB names_blob, chal, lm_resp, nt_resp;
2750 int flags = CLI_CRED_NTLM_AUTH;
2751 uint32_t samlogon_flags = 0;
2752 struct netlogon_creds_CredentialState *creds;
2753 struct netr_Authenticator a;
2755 torture_assert_ntstatus_ok(tctx, dcerpc_schannel_creds(p->conn->security_state.generic_state, tctx, &creds), "");
2757 if (lp_client_lanman_auth(tctx->lp_ctx)) {
2758 flags |= CLI_CRED_LANMAN_AUTH;
2761 if (lp_client_ntlmv2_auth(tctx->lp_ctx)) {
2762 flags |= CLI_CRED_NTLMv2_AUTH;
2765 cli_credentials_get_ntlm_username_domain(test_credentials, tctx,
2766 &identity.account_name.string,
2767 &identity.domain_name.string);
2769 identity.parameter_control =
2770 MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT |
2771 MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;
2772 identity.logon_id_low = 0;
2773 identity.logon_id_high = 0;
2774 identity.workstation.string = cli_credentials_get_workstation(test_credentials);
2777 netlogon_creds_client_authenticator(creds, &a);
2779 if (!E_deshash(cli_credentials_get_password(test_credentials), pinfo.lmpassword.hash)) {
2780 ZERO_STRUCT(pinfo.lmpassword.hash);
2782 E_md4hash(cli_credentials_get_password(test_credentials), pinfo.ntpassword.hash);
2784 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
2785 netlogon_creds_arcfour_crypt(creds, pinfo.lmpassword.hash, 16);
2786 netlogon_creds_arcfour_crypt(creds, pinfo.ntpassword.hash, 16);
2788 netlogon_creds_des_encrypt(creds, &pinfo.lmpassword);
2789 netlogon_creds_des_encrypt(creds, &pinfo.ntpassword);
2792 pinfo.identity_info = identity;
2793 logon.password = &pinfo;
2795 r.in.logon_level = NetlogonInteractiveInformation;
2797 generate_random_buffer(ninfo.challenge,
2798 sizeof(ninfo.challenge));
2799 chal = data_blob_const(ninfo.challenge,
2800 sizeof(ninfo.challenge));
2802 names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(test_credentials),
2803 cli_credentials_get_domain(test_credentials));
2805 status = cli_credentials_get_ntlm_response(test_credentials, tctx,
2811 torture_assert_ntstatus_ok(tctx, status, "cli_credentials_get_ntlm_response failed");
2813 ninfo.lm.data = lm_resp.data;
2814 ninfo.lm.length = lm_resp.length;
2816 ninfo.nt.data = nt_resp.data;
2817 ninfo.nt.length = nt_resp.length;
2819 ninfo.identity_info = identity;
2820 logon.network = &ninfo;
2822 r.in.logon_level = NetlogonNetworkInformation;
2825 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2826 r.in.computer_name = cli_credentials_get_workstation(test_credentials);
2827 r.in.logon = &logon;
2828 r.in.flags = &samlogon_flags;
2829 r.out.flags = &samlogon_flags;
2830 r.out.validation = &validation;
2831 r.out.authoritative = &authoritative;
2833 torture_comment(tctx, "Testing LogonSamLogon with name %s\n", identity.account_name.string);
2835 r.in.validation_level = 6;
2837 status = dcerpc_netr_LogonSamLogonEx(p, tctx, &r);
2838 if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
2839 r.in.validation_level = 3;
2840 status = dcerpc_netr_LogonSamLogonEx(p, tctx, &r);
2842 if (!NT_STATUS_IS_OK(status)) {
2843 torture_assert_ntstatus_equal(tctx, status, expected_result, "LogonSamLogonEx failed");
2846 torture_assert_ntstatus_ok(tctx, status, "LogonSamLogonEx failed");
2852 static bool test_SamLogon_with_creds(struct torture_context *tctx,
2853 struct dcerpc_pipe *p,
2854 struct cli_credentials *machine_creds,
2855 const char *acct_name,
2857 NTSTATUS expected_samlogon_result,
2861 struct cli_credentials *test_credentials;
2863 test_credentials = cli_credentials_init(tctx);
2865 cli_credentials_set_workstation(test_credentials,
2866 cli_credentials_get_workstation(machine_creds), CRED_SPECIFIED);
2867 cli_credentials_set_domain(test_credentials,
2868 cli_credentials_get_domain(machine_creds), CRED_SPECIFIED);
2869 cli_credentials_set_username(test_credentials,
2870 acct_name, CRED_SPECIFIED);
2871 cli_credentials_set_password(test_credentials,
2872 password, CRED_SPECIFIED);
2874 torture_comment(tctx, "testing samlogon (%s) as %s password: %s\n",
2875 interactive ? "interactive" : "network", acct_name, password);
2877 if (!test_SamLogon(tctx, p, test_credentials,
2878 expected_samlogon_result, interactive)) {
2879 torture_warning(tctx, "new password did not work\n");
2886 static bool test_SetPassword_level(struct dcerpc_pipe *p,
2887 struct dcerpc_pipe *np,
2888 struct torture_context *tctx,
2889 struct policy_handle *handle,
2891 uint32_t fields_present,
2892 uint8_t password_expired,
2893 bool *matched_expected_error,
2895 const char *acct_name,
2897 struct cli_credentials *machine_creds,
2898 bool use_queryinfo2,
2900 NTSTATUS expected_samlogon_result)
2902 const char *fields = NULL;
2909 fields = talloc_asprintf(tctx, "(fields_present: 0x%08x)",
2916 torture_comment(tctx, "Testing SetUserInfo%s level %d call "
2917 "(password_expired: %d) %s\n",
2918 use_setinfo2 ? "2":"", level, password_expired,
2919 fields ? fields : "");
2921 if (!test_SetUserPass_level_ex(p, tctx, handle, level,
2926 matched_expected_error)) {
2930 if (!test_QueryUserInfo_pwdlastset(p, tctx, handle,
2936 if (*matched_expected_error == true) {
2940 if (!test_SamLogon_with_creds(tctx, np,
2944 expected_samlogon_result,
2952 static bool test_SetPassword_pwdlastset(struct dcerpc_pipe *p,
2953 struct torture_context *tctx,
2954 uint32_t acct_flags,
2955 const char *acct_name,
2956 struct policy_handle *handle,
2958 struct cli_credentials *machine_credentials)
2960 int s = 0, q = 0, f = 0, l = 0, z = 0;
2961 struct dcerpc_binding *b;
2964 bool set_levels[] = { false, true };
2965 bool query_levels[] = { false, true };
2966 uint32_t levels[] = { 18, 21, 26, 23, 24, 25 }; /* Second half only used when TEST_ALL_LEVELS defined */
2967 uint32_t nonzeros[] = { 1, 24 };
2968 uint32_t fields_present[] = {
2970 SAMR_FIELD_EXPIRED_FLAG,
2971 SAMR_FIELD_LAST_PWD_CHANGE,
2972 SAMR_FIELD_EXPIRED_FLAG | SAMR_FIELD_LAST_PWD_CHANGE,
2974 SAMR_FIELD_NT_PASSWORD_PRESENT,
2975 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
2976 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
2977 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
2978 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
2979 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
2980 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE | SAMR_FIELD_EXPIRED_FLAG
2983 struct dcerpc_pipe *np = NULL;
2985 if (torture_setting_bool(tctx, "samba3", false)) {
2987 torture_comment(tctx, "Samba3 has second granularity, setting delay to: %d\n",
2991 status = torture_rpc_binding(tctx, &b);
2992 if (!NT_STATUS_IS_OK(status)) {
2997 /* We have to use schannel, otherwise the SamLogonEx fails
2998 * with INTERNAL_ERROR */
3000 b->flags &= ~DCERPC_AUTH_OPTIONS;
3001 b->flags |= DCERPC_SCHANNEL | DCERPC_SIGN | DCERPC_SCHANNEL_128;
3003 status = dcerpc_pipe_connect_b(tctx, &np, b,
3004 &ndr_table_netlogon,
3005 machine_credentials, tctx->ev, tctx->lp_ctx);
3007 if (!NT_STATUS_IS_OK(status)) {
3008 torture_warning(tctx, "RPC pipe connect as domain member failed: %s\n", nt_errstr(status));
3013 /* set to 1 to enable testing for all possible opcode
3014 (SetUserInfo, SetUserInfo2, QueryUserInfo, QueryUserInfo2)
3017 #define TEST_ALL_LEVELS 1
3018 #define TEST_SET_LEVELS 1
3019 #define TEST_QUERY_LEVELS 1
3021 #ifdef TEST_ALL_LEVELS
3022 for (l=0; l<ARRAY_SIZE(levels); l++) {
3024 for (l=0; l<(ARRAY_SIZE(levels))/2; l++) {
3026 for (z=0; z<ARRAY_SIZE(nonzeros); z++) {
3027 for (f=0; f<ARRAY_SIZE(fields_present); f++) {
3028 #ifdef TEST_SET_LEVELS
3029 for (s=0; s<ARRAY_SIZE(set_levels); s++) {
3031 #ifdef TEST_QUERY_LEVELS
3032 for (q=0; q<ARRAY_SIZE(query_levels); q++) {
3034 NTTIME pwdlastset_old = 0;
3035 NTTIME pwdlastset_new = 0;
3036 bool matched_expected_error = false;
3037 NTSTATUS expected_samlogon_result = NT_STATUS_ACCOUNT_DISABLED;
3039 torture_comment(tctx, "------------------------------\n"
3040 "Testing pwdLastSet attribute for flags: 0x%08x "
3041 "(s: %d (l: %d), q: %d)\n",
3042 acct_flags, s, levels[l], q);
3044 switch (levels[l]) {
3048 if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3049 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT))) {
3050 expected_samlogon_result = NT_STATUS_WRONG_PASSWORD;
3058 /* set a password and force password change (pwdlastset 0) by
3059 * setting the password expired flag to a non-0 value */
3061 if (!test_SetPassword_level(p, np, tctx, handle,
3065 &matched_expected_error,
3069 machine_credentials,
3072 expected_samlogon_result)) {
3076 if (matched_expected_error == true) {
3077 /* skipping on expected failure */
3081 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3082 * set without the SAMR_FIELD_EXPIRED_FLAG */
3084 switch (levels[l]) {
3088 if ((pwdlastset_new != 0) &&
3089 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
3090 torture_comment(tctx, "not considering a non-0 "
3091 "pwdLastSet as a an error as the "
3092 "SAMR_FIELD_EXPIRED_FLAG has not "
3097 if (pwdlastset_new != 0) {
3098 torture_warning(tctx, "pwdLastSet test failed: "
3099 "expected pwdLastSet 0 but got %lld\n",
3106 switch (levels[l]) {
3110 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3111 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3112 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3113 (pwdlastset_old >= pwdlastset_new)) {
3114 torture_warning(tctx, "pwdlastset not increasing\n");
3119 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3120 (pwdlastset_old >= pwdlastset_new)) {
3121 torture_warning(tctx, "pwdlastset not increasing\n");
3131 /* set a password, pwdlastset needs to get updated (increased
3132 * value), password_expired value used here is 0 */
3134 if (!test_SetPassword_level(p, np, tctx, handle,
3138 &matched_expected_error,
3142 machine_credentials,
3145 expected_samlogon_result)) {
3149 /* when a password has been changed, pwdlastset must not be 0 afterwards
3150 * and must be larger then the old value */
3152 switch (levels[l]) {
3157 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3158 * password has been changed, old and new pwdlastset
3159 * need to be the same value */
3161 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3162 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3163 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3165 torture_assert_int_equal(tctx, pwdlastset_old,
3166 pwdlastset_new, "pwdlastset must be equal");
3170 if (pwdlastset_old >= pwdlastset_new) {
3171 torture_warning(tctx, "pwdLastSet test failed: "
3172 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
3173 pwdlastset_old, pwdlastset_new);
3176 if (pwdlastset_new == 0) {
3177 torture_warning(tctx, "pwdLastSet test failed: "
3178 "expected non-0 pwdlastset, got: %lld\n",
3184 switch (levels[l]) {
3188 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3189 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3190 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3191 (pwdlastset_old >= pwdlastset_new)) {
3192 torture_warning(tctx, "pwdlastset not increasing\n");
3197 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3198 (pwdlastset_old >= pwdlastset_new)) {
3199 torture_warning(tctx, "pwdlastset not increasing\n");
3205 pwdlastset_old = pwdlastset_new;
3211 /* set a password, pwdlastset needs to get updated (increased
3212 * value), password_expired value used here is 0 */
3214 if (!test_SetPassword_level(p, np, tctx, handle,
3218 &matched_expected_error,
3222 machine_credentials,
3225 expected_samlogon_result)) {
3229 /* when a password has been changed, pwdlastset must not be 0 afterwards
3230 * and must be larger then the old value */
3232 switch (levels[l]) {
3237 /* if no password has been changed, old and new pwdlastset
3238 * need to be the same value */
3240 if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3241 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3243 torture_assert_int_equal(tctx, pwdlastset_old,
3244 pwdlastset_new, "pwdlastset must be equal");
3248 if (pwdlastset_old >= pwdlastset_new) {
3249 torture_warning(tctx, "pwdLastSet test failed: "
3250 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
3251 pwdlastset_old, pwdlastset_new);
3254 if (pwdlastset_new == 0) {
3255 torture_warning(tctx, "pwdLastSet test failed: "
3256 "expected non-0 pwdlastset, got: %lld\n",
3264 /* set a password and force password change (pwdlastset 0) by
3265 * setting the password expired flag to a non-0 value */
3267 if (!test_SetPassword_level(p, np, tctx, handle,
3271 &matched_expected_error,
3275 machine_credentials,
3278 expected_samlogon_result)) {
3282 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3283 * set without the SAMR_FIELD_EXPIRED_FLAG */
3285 switch (levels[l]) {
3289 if ((pwdlastset_new != 0) &&
3290 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
3291 torture_comment(tctx, "not considering a non-0 "
3292 "pwdLastSet as a an error as the "
3293 "SAMR_FIELD_EXPIRED_FLAG has not "
3298 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3299 * password has been changed, old and new pwdlastset
3300 * need to be the same value */
3302 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3303 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3304 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3306 torture_assert_int_equal(tctx, pwdlastset_old,
3307 pwdlastset_new, "pwdlastset must be equal");
3312 if (pwdlastset_old == pwdlastset_new) {
3313 torture_warning(tctx, "pwdLastSet test failed: "
3314 "expected last pwdlastset (%lld) != new pwdlastset (%lld)\n",
3315 pwdlastset_old, pwdlastset_new);
3319 if (pwdlastset_new != 0) {
3320 torture_warning(tctx, "pwdLastSet test failed: "
3321 "expected pwdLastSet 0, got %lld\n",
3328 switch (levels[l]) {
3332 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3333 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3334 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3335 (pwdlastset_old >= pwdlastset_new)) {
3336 torture_warning(tctx, "pwdlastset not increasing\n");
3341 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3342 (pwdlastset_old >= pwdlastset_new)) {
3343 torture_warning(tctx, "pwdlastset not increasing\n");
3349 /* if the level we are testing does not have a fields_present
3350 * field, skip all fields present tests by setting f to to
3352 switch (levels[l]) {
3356 f = ARRAY_SIZE(fields_present);
3360 #ifdef TEST_QUERY_LEVELS
3363 #ifdef TEST_SET_LEVELS
3366 } /* fields present */
3370 #undef TEST_SET_LEVELS
3371 #undef TEST_QUERY_LEVELS
3378 static bool test_QueryUserInfo_badpwdcount(struct dcerpc_pipe *p,
3379 struct torture_context *tctx,
3380 struct policy_handle *handle,
3381 uint32_t *badpwdcount)
3383 union samr_UserInfo *info;
3384 struct samr_QueryUserInfo r;
3386 r.in.user_handle = handle;
3390 torture_comment(tctx, "Testing QueryUserInfo level %d", r.in.level);
3392 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo(p, tctx, &r),
3393 "failed to query userinfo");
3395 *badpwdcount = info->info3.bad_password_count;
3397 torture_comment(tctx, " (bad password count: %d)\n", *badpwdcount);
3402 static bool test_reset_badpwdcount(struct dcerpc_pipe *p,
3403 struct torture_context *tctx,
3404 struct policy_handle *user_handle,
3405 uint32_t acct_flags,
3408 struct samr_SetUserInfo r;
3409 union samr_UserInfo user_info;
3411 torture_assert(tctx, test_SetUserPass(p, tctx, user_handle, password),
3412 "failed to set password");
3414 torture_comment(tctx, "Testing SetUserInfo level 16 (enable account)\n");
3416 user_info.info16.acct_flags = acct_flags;
3417 user_info.info16.acct_flags &= ~ACB_DISABLED;
3419 r.in.user_handle = user_handle;
3421 r.in.info = &user_info;
3423 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo(p, tctx, &r),
3424 "failed to enable user");
3426 torture_assert(tctx, test_SetUserPass(p, tctx, user_handle, password),
3427 "failed to set password");
3432 static bool test_Password_badpwdcount(struct dcerpc_pipe *p,
3433 struct dcerpc_pipe *np,
3434 struct torture_context *tctx,
3435 uint32_t acct_flags,
3436 const char *acct_name,
3437 struct policy_handle *domain_handle,
3438 struct policy_handle *user_handle,
3440 struct cli_credentials *machine_credentials,
3441 const char *comment,
3444 NTSTATUS expected_success_status,
3445 struct samr_DomInfo1 *info1,
3446 struct samr_DomInfo12 *info12)
3448 union samr_DomainInfo info;
3451 uint32_t badpwdcount, tmp;
3452 uint32_t password_history_length = 12;
3453 uint32_t lockout_threshold = 15;
3455 torture_comment(tctx, "\nTesting bad pwd count with: %s\n", comment);
3457 torture_assert(tctx, password_history_length < lockout_threshold,
3458 "password history length needs to be smaller than account lockout threshold for this test");
3463 info.info1 = *info1;
3465 info.info1.password_history_length = password_history_length;
3468 struct samr_SetDomainInfo r;
3470 r.in.domain_handle = domain_handle;
3471 r.in.level = DomainPasswordInformation;
3474 torture_assert_ntstatus_ok(tctx,
3475 dcerpc_samr_SetDomainInfo(p, tctx, &r),
3476 "failed to set domain info level 1");
3479 info.info12 = *info12;
3481 info.info12.lockout_threshold = lockout_threshold;
3484 struct samr_SetDomainInfo r;
3486 r.in.domain_handle = domain_handle;
3487 r.in.level = DomainLockoutInformation;
3490 torture_assert_ntstatus_ok(tctx,
3491 dcerpc_samr_SetDomainInfo(p, tctx, &r),
3492 "failed to set domain info level 12");
3495 /* reset bad pwd count */
3497 torture_assert(tctx,
3498 test_reset_badpwdcount(p, tctx, user_handle, acct_flags, password), "");
3501 /* enable or disable account */
3503 struct samr_SetUserInfo r;
3504 union samr_UserInfo user_info;
3506 torture_comment(tctx, "Testing SetUserInfo level 16 (%s account)\n",
3507 disable ? "disable" : "enable");
3509 user_info.info16.acct_flags = acct_flags;
3511 user_info.info16.acct_flags |= ACB_DISABLED;
3513 user_info.info16.acct_flags &= ~ACB_DISABLED;
3516 r.in.user_handle = user_handle;
3518 r.in.info = &user_info;
3520 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo(p, tctx, &r),
3521 "failed to enable user");
3525 /* setup password history */
3527 passwords = talloc_array(tctx, char *, password_history_length);
3529 for (i=0; i < password_history_length; i++) {
3531 torture_assert(tctx, test_SetUserPass(p, tctx, user_handle, password),
3532 "failed to set password");
3533 passwords[i] = talloc_strdup(tctx, *password);
3535 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3536 acct_name, passwords[i],
3537 expected_success_status, interactive)) {
3538 torture_fail(tctx, "failed to auth with latest password");
3541 torture_assert(tctx,
3542 test_QueryUserInfo_badpwdcount(p, tctx, user_handle, &badpwdcount), "");
3544 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
3548 /* test with wrong password */
3550 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3551 acct_name, "random_crap",
3552 NT_STATUS_WRONG_PASSWORD, interactive)) {
3553 torture_fail(tctx, "succeeded to authenticate with wrong password");
3556 torture_assert(tctx,
3557 test_QueryUserInfo_badpwdcount(p, tctx, user_handle, &badpwdcount), "");
3559 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
3562 /* test with latest good password */
3564 if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
3565 passwords[password_history_length-1],
3566 expected_success_status, interactive)) {
3567 torture_fail(tctx, "succeeded to authenticate with wrong password");
3570 torture_assert(tctx,
3571 test_QueryUserInfo_badpwdcount(p, tctx, user_handle, &badpwdcount), "");
3574 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
3576 /* only enabled accounts get the bad pwd count reset upon
3577 * successful logon */
3578 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
3584 /* test password history */
3586 for (i=0; i < password_history_length; i++) {
3588 torture_comment(tctx, "Testing bad password count behavior with "
3589 "password #%d of #%d\n", i, password_history_length);
3591 /* - network samlogon will succeed auth and not
3592 * increase badpwdcount for 2 last entries
3593 * - interactive samlogon only for the last one */
3595 if (i == password_history_length - 1 ||
3596 (i == password_history_length - 2 && !interactive)) {
3598 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3599 acct_name, passwords[i],
3600 expected_success_status, interactive)) {
3601 torture_fail(tctx, talloc_asprintf(tctx, "succeeded to authenticate with old password (#%d of #%d in history)", i, password_history_length));
3604 torture_assert(tctx,
3605 test_QueryUserInfo_badpwdcount(p, tctx, user_handle, &badpwdcount), "");
3608 /* torture_comment(tctx, "expecting bad pwd count to *NOT INCREASE* for pwd history entry %d\n", i); */
3609 torture_assert_int_equal(tctx, badpwdcount, tmp, "unexpected badpwdcount");
3611 /* torture_comment(tctx, "expecting bad pwd count to be 0 for pwd history entry %d\n", i); */
3612 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");