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_PASSWORDS_LOCKOUT,
55 TORTURE_SAMR_USER_ATTRIBUTES,
56 TORTURE_SAMR_USER_PRIVILEGES,
58 TORTURE_SAMR_MANY_ACCOUNTS,
59 TORTURE_SAMR_MANY_GROUPS,
60 TORTURE_SAMR_MANY_ALIASES
63 struct torture_samr_context {
64 struct policy_handle handle;
65 struct cli_credentials *machine_credentials;
66 enum torture_samr_choice choice;
67 uint32_t num_objects_large_dc;
70 static bool test_QueryUserInfo(struct dcerpc_pipe *p,
71 struct torture_context *tctx,
72 struct policy_handle *handle);
74 static bool test_QueryUserInfo2(struct dcerpc_pipe *p,
75 struct torture_context *tctx,
76 struct policy_handle *handle);
78 static bool test_QueryAliasInfo(struct dcerpc_pipe *p,
79 struct torture_context *tctx,
80 struct policy_handle *handle);
82 static bool test_ChangePassword(struct dcerpc_pipe *p,
83 struct torture_context *tctx,
84 const char *acct_name,
85 struct policy_handle *domain_handle, char **password);
87 static void init_lsa_String(struct lsa_String *string, const char *s)
92 static void init_lsa_StringLarge(struct lsa_StringLarge *string, const char *s)
97 static void init_lsa_BinaryString(struct lsa_BinaryString *string, const char *s, uint32_t length)
99 string->length = length;
100 string->size = length;
101 string->array = (uint16_t *)discard_const(s);
104 bool test_samr_handle_Close(struct dcerpc_pipe *p, struct torture_context *tctx,
105 struct policy_handle *handle)
110 r.in.handle = handle;
111 r.out.handle = handle;
113 status = dcerpc_samr_Close(p, tctx, &r);
114 torture_assert_ntstatus_ok(tctx, status, "Close");
119 static bool test_Shutdown(struct dcerpc_pipe *p, struct torture_context *tctx,
120 struct policy_handle *handle)
123 struct samr_Shutdown r;
125 if (!torture_setting_bool(tctx, "dangerous", false)) {
126 torture_skip(tctx, "samr_Shutdown disabled - enable dangerous tests to use\n");
130 r.in.connect_handle = handle;
132 torture_comment(tctx, "testing samr_Shutdown\n");
134 status = dcerpc_samr_Shutdown(p, tctx, &r);
135 torture_assert_ntstatus_ok(tctx, status, "samr_Shutdown");
140 static bool test_SetDsrmPassword(struct dcerpc_pipe *p, struct torture_context *tctx,
141 struct policy_handle *handle)
144 struct samr_SetDsrmPassword r;
145 struct lsa_String string;
146 struct samr_Password hash;
148 if (!torture_setting_bool(tctx, "dangerous", false)) {
149 torture_skip(tctx, "samr_SetDsrmPassword disabled - enable dangerous tests to use");
152 E_md4hash("TeSTDSRM123", hash.hash);
154 init_lsa_String(&string, "Administrator");
160 torture_comment(tctx, "testing samr_SetDsrmPassword\n");
162 status = dcerpc_samr_SetDsrmPassword(p, tctx, &r);
163 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_SUPPORTED, "samr_SetDsrmPassword");
169 static bool test_QuerySecurity(struct dcerpc_pipe *p,
170 struct torture_context *tctx,
171 struct policy_handle *handle)
174 struct samr_QuerySecurity r;
175 struct samr_SetSecurity s;
176 struct sec_desc_buf *sdbuf = NULL;
178 r.in.handle = handle;
180 r.out.sdbuf = &sdbuf;
182 status = dcerpc_samr_QuerySecurity(p, tctx, &r);
183 torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
185 torture_assert(tctx, sdbuf != NULL, "sdbuf is NULL");
187 s.in.handle = handle;
191 if (torture_setting_bool(tctx, "samba4", false)) {
192 torture_skip(tctx, "skipping SetSecurity test against Samba4\n");
195 status = dcerpc_samr_SetSecurity(p, tctx, &s);
196 torture_assert_ntstatus_ok(tctx, status, "SetSecurity");
198 status = dcerpc_samr_QuerySecurity(p, tctx, &r);
199 torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
205 static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
206 struct policy_handle *handle, uint32_t base_acct_flags,
207 const char *base_account_name)
210 struct samr_SetUserInfo s;
211 struct samr_SetUserInfo2 s2;
212 struct samr_QueryUserInfo q;
213 struct samr_QueryUserInfo q0;
214 union samr_UserInfo u;
215 union samr_UserInfo *info;
217 const char *test_account_name;
219 uint32_t user_extra_flags = 0;
221 if (!torture_setting_bool(tctx, "samba3", false)) {
222 if (base_acct_flags == ACB_NORMAL) {
223 /* When created, accounts are expired by default */
224 user_extra_flags = ACB_PW_EXPIRED;
228 s.in.user_handle = handle;
231 s2.in.user_handle = handle;
234 q.in.user_handle = handle;
238 #define TESTCALL(call, r) \
239 status = dcerpc_samr_ ##call(p, tctx, &r); \
240 if (!NT_STATUS_IS_OK(status)) { \
241 torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
242 r.in.level, nt_errstr(status), __location__); \
247 #define STRING_EQUAL(s1, s2, field) \
248 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
249 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
250 #field, s2, __location__); \
255 #define MEM_EQUAL(s1, s2, length, field) \
256 if ((s1 && !s2) || (s2 && !s1) || memcmp(s1, s2, length)) { \
257 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
258 #field, (const char *)s2, __location__); \
263 #define INT_EQUAL(i1, i2, field) \
265 torture_comment(tctx, "Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \
266 #field, (unsigned long long)i2, (unsigned long long)i1, __location__); \
271 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
272 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
274 TESTCALL(QueryUserInfo, q) \
276 s2.in.level = lvl1; \
279 ZERO_STRUCT(u.info21); \
280 u.info21.fields_present = fpval; \
282 init_lsa_String(&u.info ## lvl1.field1, value); \
283 TESTCALL(SetUserInfo, s) \
284 TESTCALL(SetUserInfo2, s2) \
285 init_lsa_String(&u.info ## lvl1.field1, ""); \
286 TESTCALL(QueryUserInfo, q); \
288 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
290 TESTCALL(QueryUserInfo, q) \
292 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
295 #define TEST_USERINFO_BINARYSTRING(lvl1, field1, lvl2, field2, value, fpval) do { \
296 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
298 TESTCALL(QueryUserInfo, q) \
300 s2.in.level = lvl1; \
303 ZERO_STRUCT(u.info21); \
304 u.info21.fields_present = fpval; \
306 init_lsa_BinaryString(&u.info ## lvl1.field1, value, strlen(value)); \
307 TESTCALL(SetUserInfo, s) \
308 TESTCALL(SetUserInfo2, s2) \
309 init_lsa_BinaryString(&u.info ## lvl1.field1, "", 1); \
310 TESTCALL(QueryUserInfo, q); \
312 MEM_EQUAL(u.info ## lvl1.field1.array, value, strlen(value), field1); \
314 TESTCALL(QueryUserInfo, q) \
316 MEM_EQUAL(u.info ## lvl2.field2.array, value, strlen(value), field2); \
319 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
320 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
322 TESTCALL(QueryUserInfo, q) \
324 s2.in.level = lvl1; \
327 uint8_t *bits = u.info21.logon_hours.bits; \
328 ZERO_STRUCT(u.info21); \
329 if (fpval == SAMR_FIELD_LOGON_HOURS) { \
330 u.info21.logon_hours.units_per_week = 168; \
331 u.info21.logon_hours.bits = bits; \
333 u.info21.fields_present = fpval; \
335 u.info ## lvl1.field1 = value; \
336 TESTCALL(SetUserInfo, s) \
337 TESTCALL(SetUserInfo2, s2) \
338 u.info ## lvl1.field1 = 0; \
339 TESTCALL(QueryUserInfo, q); \
341 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
343 TESTCALL(QueryUserInfo, q) \
345 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
348 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
349 TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
353 do { TESTCALL(QueryUserInfo, q0) } while (0);
355 TEST_USERINFO_STRING(2, comment, 1, comment, "xx2-1 comment", 0);
356 TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
357 TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment",
360 test_account_name = talloc_asprintf(tctx, "%sxx7-1", base_account_name);
361 TEST_USERINFO_STRING(7, account_name, 1, account_name, base_account_name, 0);
362 test_account_name = talloc_asprintf(tctx, "%sxx7-3", base_account_name);
363 TEST_USERINFO_STRING(7, account_name, 3, account_name, base_account_name, 0);
364 test_account_name = talloc_asprintf(tctx, "%sxx7-5", base_account_name);
365 TEST_USERINFO_STRING(7, account_name, 5, account_name, base_account_name, 0);
366 test_account_name = talloc_asprintf(tctx, "%sxx7-6", base_account_name);
367 TEST_USERINFO_STRING(7, account_name, 6, account_name, base_account_name, 0);
368 test_account_name = talloc_asprintf(tctx, "%sxx7-7", base_account_name);
369 TEST_USERINFO_STRING(7, account_name, 7, account_name, base_account_name, 0);
370 test_account_name = talloc_asprintf(tctx, "%sxx7-21", base_account_name);
371 TEST_USERINFO_STRING(7, account_name, 21, account_name, base_account_name, 0);
372 test_account_name = base_account_name;
373 TEST_USERINFO_STRING(21, account_name, 21, account_name, base_account_name,
374 SAMR_FIELD_ACCOUNT_NAME);
376 TEST_USERINFO_STRING(6, full_name, 1, full_name, "xx6-1 full_name", 0);
377 TEST_USERINFO_STRING(6, full_name, 3, full_name, "xx6-3 full_name", 0);
378 TEST_USERINFO_STRING(6, full_name, 5, full_name, "xx6-5 full_name", 0);
379 TEST_USERINFO_STRING(6, full_name, 6, full_name, "xx6-6 full_name", 0);
380 TEST_USERINFO_STRING(6, full_name, 8, full_name, "xx6-8 full_name", 0);
381 TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
382 TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
383 TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name",
384 SAMR_FIELD_FULL_NAME);
386 TEST_USERINFO_STRING(6, full_name, 1, full_name, "", 0);
387 TEST_USERINFO_STRING(6, full_name, 3, full_name, "", 0);
388 TEST_USERINFO_STRING(6, full_name, 5, full_name, "", 0);
389 TEST_USERINFO_STRING(6, full_name, 6, full_name, "", 0);
390 TEST_USERINFO_STRING(6, full_name, 8, full_name, "", 0);
391 TEST_USERINFO_STRING(6, full_name, 21, full_name, "", 0);
392 TEST_USERINFO_STRING(8, full_name, 21, full_name, "", 0);
393 TEST_USERINFO_STRING(21, full_name, 21, full_name, "",
394 SAMR_FIELD_FULL_NAME);
396 TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
397 TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
398 TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
399 TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script",
400 SAMR_FIELD_LOGON_SCRIPT);
402 TEST_USERINFO_STRING(12, profile_path, 3, profile_path, "xx12-3 profile_path", 0);
403 TEST_USERINFO_STRING(12, profile_path, 5, profile_path, "xx12-5 profile_path", 0);
404 TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
405 TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path",
406 SAMR_FIELD_PROFILE_PATH);
408 TEST_USERINFO_STRING(10, home_directory, 3, home_directory, "xx10-3 home_directory", 0);
409 TEST_USERINFO_STRING(10, home_directory, 5, home_directory, "xx10-5 home_directory", 0);
410 TEST_USERINFO_STRING(10, home_directory, 21, home_directory, "xx10-21 home_directory", 0);
411 TEST_USERINFO_STRING(21, home_directory, 21, home_directory, "xx21-21 home_directory",
412 SAMR_FIELD_HOME_DIRECTORY);
413 TEST_USERINFO_STRING(21, home_directory, 10, home_directory, "xx21-10 home_directory",
414 SAMR_FIELD_HOME_DIRECTORY);
416 TEST_USERINFO_STRING(10, home_drive, 3, home_drive, "xx10-3 home_drive", 0);
417 TEST_USERINFO_STRING(10, home_drive, 5, home_drive, "xx10-5 home_drive", 0);
418 TEST_USERINFO_STRING(10, home_drive, 21, home_drive, "xx10-21 home_drive", 0);
419 TEST_USERINFO_STRING(21, home_drive, 21, home_drive, "xx21-21 home_drive",
420 SAMR_FIELD_HOME_DRIVE);
421 TEST_USERINFO_STRING(21, home_drive, 10, home_drive, "xx21-10 home_drive",
422 SAMR_FIELD_HOME_DRIVE);
424 TEST_USERINFO_STRING(13, description, 1, description, "xx13-1 description", 0);
425 TEST_USERINFO_STRING(13, description, 5, description, "xx13-5 description", 0);
426 TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
427 TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description",
428 SAMR_FIELD_DESCRIPTION);
430 TEST_USERINFO_STRING(14, workstations, 3, workstations, "14workstation3", 0);
431 TEST_USERINFO_STRING(14, workstations, 5, workstations, "14workstation4", 0);
432 TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
433 TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21",
434 SAMR_FIELD_WORKSTATIONS);
435 TEST_USERINFO_STRING(21, workstations, 3, workstations, "21workstation3",
436 SAMR_FIELD_WORKSTATIONS);
437 TEST_USERINFO_STRING(21, workstations, 5, workstations, "21workstation5",
438 SAMR_FIELD_WORKSTATIONS);
439 TEST_USERINFO_STRING(21, workstations, 14, workstations, "21workstation14",
440 SAMR_FIELD_WORKSTATIONS);
442 TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
443 TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "xx21-21 parameters",
444 SAMR_FIELD_PARAMETERS);
445 TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "xx21-20 parameters",
446 SAMR_FIELD_PARAMETERS);
447 /* also empty user parameters are allowed */
448 TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "", 0);
449 TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "",
450 SAMR_FIELD_PARAMETERS);
451 TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "",
452 SAMR_FIELD_PARAMETERS);
454 /* Samba 3 cannot store country_code and copy_page atm. - gd */
455 if (!torture_setting_bool(tctx, "samba3", false)) {
456 TEST_USERINFO_INT(2, country_code, 2, country_code, __LINE__, 0);
457 TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
458 TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__,
459 SAMR_FIELD_COUNTRY_CODE);
460 TEST_USERINFO_INT(21, country_code, 2, country_code, __LINE__,
461 SAMR_FIELD_COUNTRY_CODE);
463 TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
464 TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__,
465 SAMR_FIELD_CODE_PAGE);
466 TEST_USERINFO_INT(21, code_page, 2, code_page, __LINE__,
467 SAMR_FIELD_CODE_PAGE);
470 if (!torture_setting_bool(tctx, "samba3", false)) {
471 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, __LINE__, 0);
472 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, __LINE__, 0);
473 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, __LINE__,
474 SAMR_FIELD_ACCT_EXPIRY);
475 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, __LINE__,
476 SAMR_FIELD_ACCT_EXPIRY);
477 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, __LINE__,
478 SAMR_FIELD_ACCT_EXPIRY);
480 /* Samba 3 can only store seconds / time_t in passdb - gd */
482 unix_to_nt_time(&nt, time(NULL) + __LINE__);
483 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, nt, 0);
484 unix_to_nt_time(&nt, time(NULL) + __LINE__);
485 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, nt, 0);
486 unix_to_nt_time(&nt, time(NULL) + __LINE__);
487 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
488 unix_to_nt_time(&nt, time(NULL) + __LINE__);
489 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
490 unix_to_nt_time(&nt, time(NULL) + __LINE__);
491 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
494 TEST_USERINFO_INT(4, logon_hours.bits[3], 3, logon_hours.bits[3], 1, 0);
495 TEST_USERINFO_INT(4, logon_hours.bits[3], 5, logon_hours.bits[3], 2, 0);
496 TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
497 TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4,
498 SAMR_FIELD_LOGON_HOURS);
500 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
501 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
502 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
504 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
505 (base_acct_flags | ACB_DISABLED),
506 (base_acct_flags | ACB_DISABLED | user_extra_flags),
509 /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
510 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
511 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
512 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
514 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
515 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
516 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
520 /* The 'autolock' flag doesn't stick - check this */
521 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
522 (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK),
523 (base_acct_flags | ACB_DISABLED | user_extra_flags),
526 /* Removing the 'disabled' flag doesn't stick - check this */
527 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
529 (base_acct_flags | ACB_DISABLED | user_extra_flags),
533 /* Samba3 cannot store these atm */
534 if (!torture_setting_bool(tctx, "samba3", false)) {
535 /* The 'store plaintext' flag does stick */
536 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
537 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED),
538 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags),
540 /* The 'use DES' flag does stick */
541 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
542 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY),
543 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags),
545 /* The 'don't require kerberos pre-authentication flag does stick */
546 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
547 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH),
548 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags),
550 /* The 'no kerberos PAC required' flag sticks */
551 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
552 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD),
553 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags),
556 TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags,
557 (base_acct_flags | ACB_DISABLED),
558 (base_acct_flags | ACB_DISABLED | user_extra_flags),
559 SAMR_FIELD_ACCT_FLAGS);
562 /* these fail with win2003 - it appears you can't set the primary gid?
563 the set succeeds, but the gid isn't changed. Very weird! */
564 TEST_USERINFO_INT(9, primary_gid, 1, primary_gid, 513);
565 TEST_USERINFO_INT(9, primary_gid, 3, primary_gid, 513);
566 TEST_USERINFO_INT(9, primary_gid, 5, primary_gid, 513);
567 TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
574 generate a random password for password change tests
576 static char *samr_rand_pass_silent(TALLOC_CTX *mem_ctx, int min_len)
578 size_t len = MAX(8, min_len) + (random() % 6);
579 char *s = generate_random_str(mem_ctx, len);
583 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
585 char *s = samr_rand_pass_silent(mem_ctx, min_len);
586 printf("Generated password '%s'\n", s);
592 generate a random password for password change tests
594 static DATA_BLOB samr_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
597 DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
598 generate_random_buffer(password.data, password.length);
600 for (i=0; i < len; i++) {
601 if (((uint16_t *)password.data)[i] == 0) {
602 ((uint16_t *)password.data)[i] = 1;
610 generate a random password for password change tests (fixed length)
612 static char *samr_rand_pass_fixed_len(TALLOC_CTX *mem_ctx, int len)
614 char *s = generate_random_str(mem_ctx, len);
615 printf("Generated password '%s'\n", s);
619 static bool test_SetUserPass(struct dcerpc_pipe *p, struct torture_context *tctx,
620 struct policy_handle *handle, char **password)
623 struct samr_SetUserInfo s;
624 union samr_UserInfo u;
626 DATA_BLOB session_key;
628 struct samr_GetUserPwInfo pwp;
629 struct samr_PwInfo info;
630 int policy_min_pw_len = 0;
631 pwp.in.user_handle = handle;
632 pwp.out.info = &info;
634 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
635 if (NT_STATUS_IS_OK(status)) {
636 policy_min_pw_len = pwp.out.info->min_password_length;
638 newpass = samr_rand_pass(tctx, policy_min_pw_len);
640 s.in.user_handle = handle;
644 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
645 u.info24.password_expired = 0;
647 status = dcerpc_fetch_session_key(p, &session_key);
648 if (!NT_STATUS_IS_OK(status)) {
649 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
650 s.in.level, nt_errstr(status));
654 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
656 torture_comment(tctx, "Testing SetUserInfo level 24 (set password)\n");
658 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
659 if (!NT_STATUS_IS_OK(status)) {
660 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
661 s.in.level, nt_errstr(status));
671 static bool test_SetUserPass_23(struct dcerpc_pipe *p, struct torture_context *tctx,
672 struct policy_handle *handle, uint32_t fields_present,
676 struct samr_SetUserInfo s;
677 union samr_UserInfo u;
679 DATA_BLOB session_key;
681 struct samr_GetUserPwInfo pwp;
682 struct samr_PwInfo info;
683 int policy_min_pw_len = 0;
684 pwp.in.user_handle = handle;
685 pwp.out.info = &info;
687 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
688 if (NT_STATUS_IS_OK(status)) {
689 policy_min_pw_len = pwp.out.info->min_password_length;
691 newpass = samr_rand_pass(tctx, policy_min_pw_len);
693 s.in.user_handle = handle;
699 u.info23.info.fields_present = fields_present;
701 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
703 status = dcerpc_fetch_session_key(p, &session_key);
704 if (!NT_STATUS_IS_OK(status)) {
705 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
706 s.in.level, nt_errstr(status));
710 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
712 torture_comment(tctx, "Testing SetUserInfo level 23 (set password)\n");
714 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
715 if (!NT_STATUS_IS_OK(status)) {
716 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
717 s.in.level, nt_errstr(status));
723 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
725 status = dcerpc_fetch_session_key(p, &session_key);
726 if (!NT_STATUS_IS_OK(status)) {
727 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
728 s.in.level, nt_errstr(status));
732 /* This should break the key nicely */
733 session_key.length--;
734 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
736 torture_comment(tctx, "Testing SetUserInfo level 23 (set password) with wrong password\n");
738 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
739 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
740 torture_warning(tctx, "SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
741 s.in.level, nt_errstr(status));
749 static bool test_SetUserPassEx(struct dcerpc_pipe *p, struct torture_context *tctx,
750 struct policy_handle *handle, bool makeshort,
754 struct samr_SetUserInfo s;
755 union samr_UserInfo u;
757 DATA_BLOB session_key;
758 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
759 uint8_t confounder[16];
761 struct MD5Context ctx;
762 struct samr_GetUserPwInfo pwp;
763 struct samr_PwInfo info;
764 int policy_min_pw_len = 0;
765 pwp.in.user_handle = handle;
766 pwp.out.info = &info;
768 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
769 if (NT_STATUS_IS_OK(status)) {
770 policy_min_pw_len = pwp.out.info->min_password_length;
772 if (makeshort && policy_min_pw_len) {
773 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len - 1);
775 newpass = samr_rand_pass(tctx, policy_min_pw_len);
778 s.in.user_handle = handle;
782 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
783 u.info26.password_expired = 0;
785 status = dcerpc_fetch_session_key(p, &session_key);
786 if (!NT_STATUS_IS_OK(status)) {
787 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
788 s.in.level, nt_errstr(status));
792 generate_random_buffer((uint8_t *)confounder, 16);
795 MD5Update(&ctx, confounder, 16);
796 MD5Update(&ctx, session_key.data, session_key.length);
797 MD5Final(confounded_session_key.data, &ctx);
799 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
800 memcpy(&u.info26.password.data[516], confounder, 16);
802 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex)\n");
804 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
805 if (!NT_STATUS_IS_OK(status)) {
806 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
807 s.in.level, nt_errstr(status));
813 /* This should break the key nicely */
814 confounded_session_key.data[0]++;
816 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
817 memcpy(&u.info26.password.data[516], confounder, 16);
819 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
821 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
822 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
823 torture_warning(tctx, "SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
824 s.in.level, nt_errstr(status));
833 static bool test_SetUserPass_25(struct dcerpc_pipe *p, struct torture_context *tctx,
834 struct policy_handle *handle, uint32_t fields_present,
838 struct samr_SetUserInfo s;
839 union samr_UserInfo u;
841 DATA_BLOB session_key;
842 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
843 struct MD5Context ctx;
844 uint8_t confounder[16];
846 struct samr_GetUserPwInfo pwp;
847 struct samr_PwInfo info;
848 int policy_min_pw_len = 0;
849 pwp.in.user_handle = handle;
850 pwp.out.info = &info;
852 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
853 if (NT_STATUS_IS_OK(status)) {
854 policy_min_pw_len = pwp.out.info->min_password_length;
856 newpass = samr_rand_pass(tctx, policy_min_pw_len);
858 s.in.user_handle = handle;
864 u.info25.info.fields_present = fields_present;
866 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
868 status = dcerpc_fetch_session_key(p, &session_key);
869 if (!NT_STATUS_IS_OK(status)) {
870 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
871 s.in.level, nt_errstr(status));
875 generate_random_buffer((uint8_t *)confounder, 16);
878 MD5Update(&ctx, confounder, 16);
879 MD5Update(&ctx, session_key.data, session_key.length);
880 MD5Final(confounded_session_key.data, &ctx);
882 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
883 memcpy(&u.info25.password.data[516], confounder, 16);
885 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex)\n");
887 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
888 if (!NT_STATUS_IS_OK(status)) {
889 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
890 s.in.level, nt_errstr(status));
896 /* This should break the key nicely */
897 confounded_session_key.data[0]++;
899 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
900 memcpy(&u.info25.password.data[516], confounder, 16);
902 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
904 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
905 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
906 torture_warning(tctx, "SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
907 s.in.level, nt_errstr(status));
914 static bool test_SetUserPass_18(struct dcerpc_pipe *p, struct torture_context *tctx,
915 struct policy_handle *handle, char **password)
918 struct samr_SetUserInfo s;
919 union samr_UserInfo u;
921 DATA_BLOB session_key;
923 struct samr_GetUserPwInfo pwp;
924 struct samr_PwInfo info;
925 int policy_min_pw_len = 0;
926 uint8_t lm_hash[16], nt_hash[16];
928 pwp.in.user_handle = handle;
929 pwp.out.info = &info;
931 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
932 if (NT_STATUS_IS_OK(status)) {
933 policy_min_pw_len = pwp.out.info->min_password_length;
935 newpass = samr_rand_pass(tctx, policy_min_pw_len);
937 s.in.user_handle = handle;
943 u.info18.nt_pwd_active = true;
944 u.info18.lm_pwd_active = true;
946 E_md4hash(newpass, nt_hash);
947 E_deshash(newpass, lm_hash);
949 status = dcerpc_fetch_session_key(p, &session_key);
950 if (!NT_STATUS_IS_OK(status)) {
951 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
952 s.in.level, nt_errstr(status));
958 in = data_blob_const(nt_hash, 16);
959 out = data_blob_talloc_zero(tctx, 16);
960 sess_crypt_blob(&out, &in, &session_key, true);
961 memcpy(u.info18.nt_pwd.hash, out.data, out.length);
965 in = data_blob_const(lm_hash, 16);
966 out = data_blob_talloc_zero(tctx, 16);
967 sess_crypt_blob(&out, &in, &session_key, true);
968 memcpy(u.info18.lm_pwd.hash, out.data, out.length);
971 torture_comment(tctx, "Testing SetUserInfo level 18 (set password hash)\n");
973 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
974 if (!NT_STATUS_IS_OK(status)) {
975 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
976 s.in.level, nt_errstr(status));
985 static bool test_SetUserPass_21(struct dcerpc_pipe *p, struct torture_context *tctx,
986 struct policy_handle *handle, uint32_t fields_present,
990 struct samr_SetUserInfo s;
991 union samr_UserInfo u;
993 DATA_BLOB session_key;
995 struct samr_GetUserPwInfo pwp;
996 struct samr_PwInfo info;
997 int policy_min_pw_len = 0;
998 uint8_t lm_hash[16], nt_hash[16];
1000 pwp.in.user_handle = handle;
1001 pwp.out.info = &info;
1003 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1004 if (NT_STATUS_IS_OK(status)) {
1005 policy_min_pw_len = pwp.out.info->min_password_length;
1007 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1009 s.in.user_handle = handle;
1013 E_md4hash(newpass, nt_hash);
1014 E_deshash(newpass, lm_hash);
1018 u.info21.fields_present = fields_present;
1020 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1021 u.info21.lm_owf_password.length = 16;
1022 u.info21.lm_owf_password.size = 16;
1023 u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
1024 u.info21.lm_password_set = true;
1027 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1028 u.info21.nt_owf_password.length = 16;
1029 u.info21.nt_owf_password.size = 16;
1030 u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
1031 u.info21.nt_password_set = true;
1034 status = dcerpc_fetch_session_key(p, &session_key);
1035 if (!NT_STATUS_IS_OK(status)) {
1036 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
1037 s.in.level, nt_errstr(status));
1041 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1043 in = data_blob_const(u.info21.lm_owf_password.array,
1044 u.info21.lm_owf_password.length);
1045 out = data_blob_talloc_zero(tctx, 16);
1046 sess_crypt_blob(&out, &in, &session_key, true);
1047 u.info21.lm_owf_password.array = (uint16_t *)out.data;
1050 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1052 in = data_blob_const(u.info21.nt_owf_password.array,
1053 u.info21.nt_owf_password.length);
1054 out = data_blob_talloc_zero(tctx, 16);
1055 sess_crypt_blob(&out, &in, &session_key, true);
1056 u.info21.nt_owf_password.array = (uint16_t *)out.data;
1059 torture_comment(tctx, "Testing SetUserInfo level 21 (set password hash)\n");
1061 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1062 if (!NT_STATUS_IS_OK(status)) {
1063 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
1064 s.in.level, nt_errstr(status));
1067 *password = newpass;
1070 /* try invalid length */
1071 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1073 u.info21.nt_owf_password.length++;
1075 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1077 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1078 torture_warning(tctx, "SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1079 s.in.level, nt_errstr(status));
1084 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1086 u.info21.lm_owf_password.length++;
1088 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1090 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1091 torture_warning(tctx, "SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1092 s.in.level, nt_errstr(status));
1100 static bool test_SetUserPass_level_ex(struct dcerpc_pipe *p,
1101 struct torture_context *tctx,
1102 struct policy_handle *handle,
1104 uint32_t fields_present,
1105 char **password, uint8_t password_expired,
1107 bool *matched_expected_error)
1110 NTSTATUS expected_error = NT_STATUS_OK;
1111 struct samr_SetUserInfo s;
1112 struct samr_SetUserInfo2 s2;
1113 union samr_UserInfo u;
1115 DATA_BLOB session_key;
1116 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
1117 struct MD5Context ctx;
1118 uint8_t confounder[16];
1120 struct samr_GetUserPwInfo pwp;
1121 struct samr_PwInfo info;
1122 int policy_min_pw_len = 0;
1123 const char *comment = NULL;
1124 uint8_t lm_hash[16], nt_hash[16];
1126 pwp.in.user_handle = handle;
1127 pwp.out.info = &info;
1129 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1130 if (NT_STATUS_IS_OK(status)) {
1131 policy_min_pw_len = pwp.out.info->min_password_length;
1133 newpass = samr_rand_pass_silent(tctx, policy_min_pw_len);
1136 s2.in.user_handle = handle;
1138 s2.in.level = level;
1140 s.in.user_handle = handle;
1145 if (fields_present & SAMR_FIELD_COMMENT) {
1146 comment = talloc_asprintf(tctx, "comment: %ld\n", time(NULL));
1153 E_md4hash(newpass, nt_hash);
1154 E_deshash(newpass, lm_hash);
1156 u.info18.nt_pwd_active = true;
1157 u.info18.lm_pwd_active = true;
1158 u.info18.password_expired = password_expired;
1160 memcpy(u.info18.lm_pwd.hash, lm_hash, 16);
1161 memcpy(u.info18.nt_pwd.hash, nt_hash, 16);
1165 E_md4hash(newpass, nt_hash);
1166 E_deshash(newpass, lm_hash);
1168 u.info21.fields_present = fields_present;
1169 u.info21.password_expired = password_expired;
1170 u.info21.comment.string = comment;
1172 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1173 u.info21.lm_owf_password.length = 16;
1174 u.info21.lm_owf_password.size = 16;
1175 u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
1176 u.info21.lm_password_set = true;
1179 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1180 u.info21.nt_owf_password.length = 16;
1181 u.info21.nt_owf_password.size = 16;
1182 u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
1183 u.info21.nt_password_set = true;
1188 u.info23.info.fields_present = fields_present;
1189 u.info23.info.password_expired = password_expired;
1190 u.info23.info.comment.string = comment;
1192 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
1196 u.info24.password_expired = password_expired;
1198 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
1202 u.info25.info.fields_present = fields_present;
1203 u.info25.info.password_expired = password_expired;
1204 u.info25.info.comment.string = comment;
1206 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
1210 u.info26.password_expired = password_expired;
1212 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
1217 status = dcerpc_fetch_session_key(p, &session_key);
1218 if (!NT_STATUS_IS_OK(status)) {
1219 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
1220 s.in.level, nt_errstr(status));
1224 generate_random_buffer((uint8_t *)confounder, 16);
1227 MD5Update(&ctx, confounder, 16);
1228 MD5Update(&ctx, session_key.data, session_key.length);
1229 MD5Final(confounded_session_key.data, &ctx);
1235 in = data_blob_const(u.info18.nt_pwd.hash, 16);
1236 out = data_blob_talloc_zero(tctx, 16);
1237 sess_crypt_blob(&out, &in, &session_key, true);
1238 memcpy(u.info18.nt_pwd.hash, out.data, out.length);
1242 in = data_blob_const(u.info18.lm_pwd.hash, 16);
1243 out = data_blob_talloc_zero(tctx, 16);
1244 sess_crypt_blob(&out, &in, &session_key, true);
1245 memcpy(u.info18.lm_pwd.hash, out.data, out.length);
1250 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1252 in = data_blob_const(u.info21.lm_owf_password.array,
1253 u.info21.lm_owf_password.length);
1254 out = data_blob_talloc_zero(tctx, 16);
1255 sess_crypt_blob(&out, &in, &session_key, true);
1256 u.info21.lm_owf_password.array = (uint16_t *)out.data;
1258 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1260 in = data_blob_const(u.info21.nt_owf_password.array,
1261 u.info21.nt_owf_password.length);
1262 out = data_blob_talloc_zero(tctx, 16);
1263 sess_crypt_blob(&out, &in, &session_key, true);
1264 u.info21.nt_owf_password.array = (uint16_t *)out.data;
1268 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
1271 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
1274 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
1275 memcpy(&u.info25.password.data[516], confounder, 16);
1278 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
1279 memcpy(&u.info26.password.data[516], confounder, 16);
1284 status = dcerpc_samr_SetUserInfo2(p, tctx, &s2);
1286 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1289 if (!NT_STATUS_IS_OK(status)) {
1290 if (fields_present == 0) {
1291 expected_error = NT_STATUS_INVALID_PARAMETER;
1293 if (fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
1294 expected_error = NT_STATUS_ACCESS_DENIED;
1298 if (!NT_STATUS_IS_OK(expected_error)) {
1300 torture_assert_ntstatus_equal(tctx,
1302 expected_error, "SetUserInfo2 failed");
1304 torture_assert_ntstatus_equal(tctx,
1306 expected_error, "SetUserInfo failed");
1308 *matched_expected_error = true;
1312 if (!NT_STATUS_IS_OK(status)) {
1313 torture_warning(tctx, "SetUserInfo%s level %u failed - %s\n",
1314 use_setinfo2 ? "2":"", level, nt_errstr(status));
1317 *password = newpass;
1323 static bool test_SetAliasInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1324 struct policy_handle *handle)
1327 struct samr_SetAliasInfo r;
1328 struct samr_QueryAliasInfo q;
1329 union samr_AliasInfo *info;
1330 uint16_t levels[] = {2, 3};
1334 /* Ignoring switch level 1, as that includes the number of members for the alias
1335 * and setting this to a wrong value might have negative consequences
1338 for (i=0;i<ARRAY_SIZE(levels);i++) {
1339 torture_comment(tctx, "Testing SetAliasInfo level %u\n", levels[i]);
1341 r.in.alias_handle = handle;
1342 r.in.level = levels[i];
1343 r.in.info = talloc(tctx, union samr_AliasInfo);
1344 switch (r.in.level) {
1345 case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
1346 case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
1347 "Test Description, should test I18N as well"); break;
1348 case ALIASINFOALL: torture_comment(tctx, "ALIASINFOALL ignored\n"); break;
1351 status = dcerpc_samr_SetAliasInfo(p, tctx, &r);
1352 if (!NT_STATUS_IS_OK(status)) {
1353 torture_warning(tctx, "SetAliasInfo level %u failed - %s\n",
1354 levels[i], nt_errstr(status));
1358 q.in.alias_handle = handle;
1359 q.in.level = levels[i];
1362 status = dcerpc_samr_QueryAliasInfo(p, tctx, &q);
1363 if (!NT_STATUS_IS_OK(status)) {
1364 torture_warning(tctx, "QueryAliasInfo level %u failed - %s\n",
1365 levels[i], nt_errstr(status));
1373 static bool test_GetGroupsForUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1374 struct policy_handle *user_handle)
1376 struct samr_GetGroupsForUser r;
1377 struct samr_RidWithAttributeArray *rids = NULL;
1380 torture_comment(tctx, "testing GetGroupsForUser\n");
1382 r.in.user_handle = user_handle;
1385 status = dcerpc_samr_GetGroupsForUser(p, tctx, &r);
1386 torture_assert_ntstatus_ok(tctx, status, "GetGroupsForUser");
1392 static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1393 struct lsa_String *domain_name)
1396 struct samr_GetDomPwInfo r;
1397 struct samr_PwInfo info;
1399 r.in.domain_name = domain_name;
1402 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1404 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1405 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1407 r.in.domain_name->string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1408 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1410 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1411 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1413 r.in.domain_name->string = "\\\\__NONAME__";
1414 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1416 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1417 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1419 r.in.domain_name->string = "\\\\Builtin";
1420 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1422 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1423 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1428 static bool test_GetUserPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1429 struct policy_handle *handle)
1432 struct samr_GetUserPwInfo r;
1433 struct samr_PwInfo info;
1435 torture_comment(tctx, "Testing GetUserPwInfo\n");
1437 r.in.user_handle = handle;
1440 status = dcerpc_samr_GetUserPwInfo(p, tctx, &r);
1441 torture_assert_ntstatus_ok(tctx, status, "GetUserPwInfo");
1446 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, struct torture_context *tctx,
1447 struct policy_handle *domain_handle, const char *name,
1451 struct samr_LookupNames n;
1452 struct lsa_String sname[2];
1453 struct samr_Ids rids, types;
1455 init_lsa_String(&sname[0], name);
1457 n.in.domain_handle = domain_handle;
1461 n.out.types = &types;
1462 status = dcerpc_samr_LookupNames(p, tctx, &n);
1463 if (NT_STATUS_IS_OK(status)) {
1464 *rid = n.out.rids->ids[0];
1469 init_lsa_String(&sname[1], "xxNONAMExx");
1471 status = dcerpc_samr_LookupNames(p, tctx, &n);
1472 if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
1473 torture_warning(tctx, "LookupNames[2] failed - %s\n", nt_errstr(status));
1474 if (NT_STATUS_IS_OK(status)) {
1475 return NT_STATUS_UNSUCCESSFUL;
1481 status = dcerpc_samr_LookupNames(p, tctx, &n);
1482 if (!NT_STATUS_IS_OK(status)) {
1483 torture_warning(tctx, "LookupNames[0] failed - %s\n", nt_errstr(status));
1487 init_lsa_String(&sname[0], "xxNONAMExx");
1489 status = dcerpc_samr_LookupNames(p, tctx, &n);
1490 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1491 torture_warning(tctx, "LookupNames[1 bad name] failed - %s\n", nt_errstr(status));
1492 if (NT_STATUS_IS_OK(status)) {
1493 return NT_STATUS_UNSUCCESSFUL;
1498 init_lsa_String(&sname[0], "xxNONAMExx");
1499 init_lsa_String(&sname[1], "xxNONAME2xx");
1501 status = dcerpc_samr_LookupNames(p, tctx, &n);
1502 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1503 torture_warning(tctx, "LookupNames[2 bad names] failed - %s\n", nt_errstr(status));
1504 if (NT_STATUS_IS_OK(status)) {
1505 return NT_STATUS_UNSUCCESSFUL;
1510 return NT_STATUS_OK;
1513 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p,
1514 struct torture_context *tctx,
1515 struct policy_handle *domain_handle,
1516 const char *name, struct policy_handle *user_handle)
1519 struct samr_OpenUser r;
1522 status = test_LookupName(p, tctx, domain_handle, name, &rid);
1523 if (!NT_STATUS_IS_OK(status)) {
1527 r.in.domain_handle = domain_handle;
1528 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1530 r.out.user_handle = user_handle;
1531 status = dcerpc_samr_OpenUser(p, tctx, &r);
1532 if (!NT_STATUS_IS_OK(status)) {
1533 torture_warning(tctx, "OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(status));
1540 static bool test_ChangePasswordNT3(struct dcerpc_pipe *p,
1541 struct torture_context *tctx,
1542 struct policy_handle *handle)
1545 struct samr_ChangePasswordUser r;
1547 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1548 struct policy_handle user_handle;
1549 char *oldpass = "test";
1550 char *newpass = "test2";
1551 uint8_t old_nt_hash[16], new_nt_hash[16];
1552 uint8_t old_lm_hash[16], new_lm_hash[16];
1554 status = test_OpenUser_byname(p, tctx, handle, "testuser", &user_handle);
1555 if (!NT_STATUS_IS_OK(status)) {
1559 torture_comment(tctx, "Testing ChangePasswordUser for user 'testuser'\n");
1561 torture_comment(tctx, "old password: %s\n", oldpass);
1562 torture_comment(tctx, "new password: %s\n", newpass);
1564 E_md4hash(oldpass, old_nt_hash);
1565 E_md4hash(newpass, new_nt_hash);
1566 E_deshash(oldpass, old_lm_hash);
1567 E_deshash(newpass, new_lm_hash);
1569 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1570 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1571 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1572 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1573 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1574 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1576 r.in.handle = &user_handle;
1577 r.in.lm_present = 1;
1578 r.in.old_lm_crypted = &hash1;
1579 r.in.new_lm_crypted = &hash2;
1580 r.in.nt_present = 1;
1581 r.in.old_nt_crypted = &hash3;
1582 r.in.new_nt_crypted = &hash4;
1583 r.in.cross1_present = 1;
1584 r.in.nt_cross = &hash5;
1585 r.in.cross2_present = 1;
1586 r.in.lm_cross = &hash6;
1588 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1589 if (!NT_STATUS_IS_OK(status)) {
1590 torture_warning(tctx, "ChangePasswordUser failed - %s\n", nt_errstr(status));
1594 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
1602 static bool test_ChangePasswordUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1603 const char *acct_name,
1604 struct policy_handle *handle, char **password)
1607 struct samr_ChangePasswordUser r;
1609 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1610 struct policy_handle user_handle;
1612 uint8_t old_nt_hash[16], new_nt_hash[16];
1613 uint8_t old_lm_hash[16], new_lm_hash[16];
1614 bool changed = true;
1617 struct samr_GetUserPwInfo pwp;
1618 struct samr_PwInfo info;
1619 int policy_min_pw_len = 0;
1621 status = test_OpenUser_byname(p, tctx, handle, acct_name, &user_handle);
1622 if (!NT_STATUS_IS_OK(status)) {
1625 pwp.in.user_handle = &user_handle;
1626 pwp.out.info = &info;
1628 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1629 if (NT_STATUS_IS_OK(status)) {
1630 policy_min_pw_len = pwp.out.info->min_password_length;
1632 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1634 torture_comment(tctx, "Testing ChangePasswordUser\n");
1636 torture_assert(tctx, *password != NULL,
1637 "Failing ChangePasswordUser as old password was NULL. Previous test failed?");
1639 oldpass = *password;
1641 E_md4hash(oldpass, old_nt_hash);
1642 E_md4hash(newpass, new_nt_hash);
1643 E_deshash(oldpass, old_lm_hash);
1644 E_deshash(newpass, new_lm_hash);
1646 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1647 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1648 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1649 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1650 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1651 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1653 r.in.user_handle = &user_handle;
1654 r.in.lm_present = 1;
1655 /* Break the LM hash */
1657 r.in.old_lm_crypted = &hash1;
1658 r.in.new_lm_crypted = &hash2;
1659 r.in.nt_present = 1;
1660 r.in.old_nt_crypted = &hash3;
1661 r.in.new_nt_crypted = &hash4;
1662 r.in.cross1_present = 1;
1663 r.in.nt_cross = &hash5;
1664 r.in.cross2_present = 1;
1665 r.in.lm_cross = &hash6;
1667 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1668 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1669 "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash");
1671 /* Unbreak the LM hash */
1674 r.in.user_handle = &user_handle;
1675 r.in.lm_present = 1;
1676 r.in.old_lm_crypted = &hash1;
1677 r.in.new_lm_crypted = &hash2;
1678 /* Break the NT hash */
1680 r.in.nt_present = 1;
1681 r.in.old_nt_crypted = &hash3;
1682 r.in.new_nt_crypted = &hash4;
1683 r.in.cross1_present = 1;
1684 r.in.nt_cross = &hash5;
1685 r.in.cross2_present = 1;
1686 r.in.lm_cross = &hash6;
1688 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1689 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1690 "expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash");
1692 /* Unbreak the NT hash */
1695 r.in.user_handle = &user_handle;
1696 r.in.lm_present = 1;
1697 r.in.old_lm_crypted = &hash1;
1698 r.in.new_lm_crypted = &hash2;
1699 r.in.nt_present = 1;
1700 r.in.old_nt_crypted = &hash3;
1701 r.in.new_nt_crypted = &hash4;
1702 r.in.cross1_present = 1;
1703 r.in.nt_cross = &hash5;
1704 r.in.cross2_present = 1;
1705 /* Break the LM cross */
1707 r.in.lm_cross = &hash6;
1709 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1710 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1711 torture_warning(tctx, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status));
1715 /* Unbreak the LM cross */
1718 r.in.user_handle = &user_handle;
1719 r.in.lm_present = 1;
1720 r.in.old_lm_crypted = &hash1;
1721 r.in.new_lm_crypted = &hash2;
1722 r.in.nt_present = 1;
1723 r.in.old_nt_crypted = &hash3;
1724 r.in.new_nt_crypted = &hash4;
1725 r.in.cross1_present = 1;
1726 /* Break the NT cross */
1728 r.in.nt_cross = &hash5;
1729 r.in.cross2_present = 1;
1730 r.in.lm_cross = &hash6;
1732 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1733 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1734 torture_warning(tctx, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status));
1738 /* Unbreak the NT cross */
1742 /* Reset the hashes to not broken values */
1743 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1744 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1745 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1746 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1747 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1748 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1750 r.in.user_handle = &user_handle;
1751 r.in.lm_present = 1;
1752 r.in.old_lm_crypted = &hash1;
1753 r.in.new_lm_crypted = &hash2;
1754 r.in.nt_present = 1;
1755 r.in.old_nt_crypted = &hash3;
1756 r.in.new_nt_crypted = &hash4;
1757 r.in.cross1_present = 1;
1758 r.in.nt_cross = &hash5;
1759 r.in.cross2_present = 0;
1760 r.in.lm_cross = NULL;
1762 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1763 if (NT_STATUS_IS_OK(status)) {
1765 *password = newpass;
1766 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1767 torture_warning(tctx, "ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(status));
1772 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1774 E_md4hash(oldpass, old_nt_hash);
1775 E_md4hash(newpass, new_nt_hash);
1776 E_deshash(oldpass, old_lm_hash);
1777 E_deshash(newpass, new_lm_hash);
1780 /* Reset the hashes to not broken values */
1781 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1782 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1783 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1784 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1785 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1786 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1788 r.in.user_handle = &user_handle;
1789 r.in.lm_present = 1;
1790 r.in.old_lm_crypted = &hash1;
1791 r.in.new_lm_crypted = &hash2;
1792 r.in.nt_present = 1;
1793 r.in.old_nt_crypted = &hash3;
1794 r.in.new_nt_crypted = &hash4;
1795 r.in.cross1_present = 0;
1796 r.in.nt_cross = NULL;
1797 r.in.cross2_present = 1;
1798 r.in.lm_cross = &hash6;
1800 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1801 if (NT_STATUS_IS_OK(status)) {
1803 *password = newpass;
1804 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1805 torture_warning(tctx, "ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status));
1810 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1812 E_md4hash(oldpass, old_nt_hash);
1813 E_md4hash(newpass, new_nt_hash);
1814 E_deshash(oldpass, old_lm_hash);
1815 E_deshash(newpass, new_lm_hash);
1818 /* Reset the hashes to not broken values */
1819 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1820 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1821 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1822 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1823 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1824 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1826 r.in.user_handle = &user_handle;
1827 r.in.lm_present = 1;
1828 r.in.old_lm_crypted = &hash1;
1829 r.in.new_lm_crypted = &hash2;
1830 r.in.nt_present = 1;
1831 r.in.old_nt_crypted = &hash3;
1832 r.in.new_nt_crypted = &hash4;
1833 r.in.cross1_present = 1;
1834 r.in.nt_cross = &hash5;
1835 r.in.cross2_present = 1;
1836 r.in.lm_cross = &hash6;
1838 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1839 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1840 torture_comment(tctx, "ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1841 } else if (!NT_STATUS_IS_OK(status)) {
1842 torture_warning(tctx, "ChangePasswordUser failed - %s\n", nt_errstr(status));
1846 *password = newpass;
1849 r.in.user_handle = &user_handle;
1850 r.in.lm_present = 1;
1851 r.in.old_lm_crypted = &hash1;
1852 r.in.new_lm_crypted = &hash2;
1853 r.in.nt_present = 1;
1854 r.in.old_nt_crypted = &hash3;
1855 r.in.new_nt_crypted = &hash4;
1856 r.in.cross1_present = 1;
1857 r.in.nt_cross = &hash5;
1858 r.in.cross2_present = 1;
1859 r.in.lm_cross = &hash6;
1862 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1863 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1864 torture_comment(tctx, "ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1865 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1866 torture_warning(tctx, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status));
1872 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
1880 static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
1881 const char *acct_name,
1882 struct policy_handle *handle, char **password)
1885 struct samr_OemChangePasswordUser2 r;
1887 struct samr_Password lm_verifier;
1888 struct samr_CryptPassword lm_pass;
1889 struct lsa_AsciiString server, account, account_bad;
1892 uint8_t old_lm_hash[16], new_lm_hash[16];
1894 struct samr_GetDomPwInfo dom_pw_info;
1895 struct samr_PwInfo info;
1896 int policy_min_pw_len = 0;
1898 struct lsa_String domain_name;
1900 domain_name.string = "";
1901 dom_pw_info.in.domain_name = &domain_name;
1902 dom_pw_info.out.info = &info;
1904 torture_comment(tctx, "Testing OemChangePasswordUser2\n");
1906 torture_assert(tctx, *password != NULL,
1907 "Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?");
1909 oldpass = *password;
1911 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
1912 if (NT_STATUS_IS_OK(status)) {
1913 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
1916 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1918 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1919 account.string = acct_name;
1921 E_deshash(oldpass, old_lm_hash);
1922 E_deshash(newpass, new_lm_hash);
1924 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1925 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1926 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1928 r.in.server = &server;
1929 r.in.account = &account;
1930 r.in.password = &lm_pass;
1931 r.in.hash = &lm_verifier;
1933 /* Break the verification */
1934 lm_verifier.hash[0]++;
1936 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1938 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1939 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1940 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1945 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1946 /* Break the old password */
1948 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1949 /* unbreak it for the next operation */
1951 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1953 r.in.server = &server;
1954 r.in.account = &account;
1955 r.in.password = &lm_pass;
1956 r.in.hash = &lm_verifier;
1958 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1960 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1961 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1962 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1967 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1968 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1970 r.in.server = &server;
1971 r.in.account = &account;
1972 r.in.password = &lm_pass;
1975 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1977 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1978 && !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1979 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
1984 /* This shouldn't be a valid name */
1985 account_bad.string = TEST_ACCOUNT_NAME "XX";
1986 r.in.account = &account_bad;
1988 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1990 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1991 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
1996 /* This shouldn't be a valid name */
1997 account_bad.string = TEST_ACCOUNT_NAME "XX";
1998 r.in.account = &account_bad;
1999 r.in.password = &lm_pass;
2000 r.in.hash = &lm_verifier;
2002 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
2004 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
2005 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
2010 /* This shouldn't be a valid name */
2011 account_bad.string = TEST_ACCOUNT_NAME "XX";
2012 r.in.account = &account_bad;
2013 r.in.password = NULL;
2014 r.in.hash = &lm_verifier;
2016 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
2018 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
2019 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
2024 E_deshash(oldpass, old_lm_hash);
2025 E_deshash(newpass, new_lm_hash);
2027 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
2028 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2029 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
2031 r.in.server = &server;
2032 r.in.account = &account;
2033 r.in.password = &lm_pass;
2034 r.in.hash = &lm_verifier;
2036 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
2037 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2038 torture_comment(tctx, "OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
2039 } else if (!NT_STATUS_IS_OK(status)) {
2040 torture_warning(tctx, "OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
2043 *password = newpass;
2050 static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
2051 const char *acct_name,
2053 char *newpass, bool allow_password_restriction)
2056 struct samr_ChangePasswordUser2 r;
2058 struct lsa_String server, account;
2059 struct samr_CryptPassword nt_pass, lm_pass;
2060 struct samr_Password nt_verifier, lm_verifier;
2062 uint8_t old_nt_hash[16], new_nt_hash[16];
2063 uint8_t old_lm_hash[16], new_lm_hash[16];
2065 struct samr_GetDomPwInfo dom_pw_info;
2066 struct samr_PwInfo info;
2068 struct lsa_String domain_name;
2070 domain_name.string = "";
2071 dom_pw_info.in.domain_name = &domain_name;
2072 dom_pw_info.out.info = &info;
2074 torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name);
2076 torture_assert(tctx, *password != NULL,
2077 "Failing ChangePasswordUser2 as old password was NULL. Previous test failed?");
2078 oldpass = *password;
2081 int policy_min_pw_len = 0;
2082 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
2083 if (NT_STATUS_IS_OK(status)) {
2084 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
2087 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2090 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2091 init_lsa_String(&account, acct_name);
2093 E_md4hash(oldpass, old_nt_hash);
2094 E_md4hash(newpass, new_nt_hash);
2096 E_deshash(oldpass, old_lm_hash);
2097 E_deshash(newpass, new_lm_hash);
2099 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
2100 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2101 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2103 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2104 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2105 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2107 r.in.server = &server;
2108 r.in.account = &account;
2109 r.in.nt_password = &nt_pass;
2110 r.in.nt_verifier = &nt_verifier;
2112 r.in.lm_password = &lm_pass;
2113 r.in.lm_verifier = &lm_verifier;
2115 status = dcerpc_samr_ChangePasswordUser2(p, tctx, &r);
2116 if (allow_password_restriction && NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2117 torture_comment(tctx, "ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
2118 } else if (!NT_STATUS_IS_OK(status)) {
2119 torture_warning(tctx, "ChangePasswordUser2 failed - %s\n", nt_errstr(status));
2122 *password = newpass;
2129 bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tctx,
2130 const char *account_string,
2131 int policy_min_pw_len,
2133 const char *newpass,
2134 NTTIME last_password_change,
2135 bool handle_reject_reason)
2138 struct samr_ChangePasswordUser3 r;
2140 struct lsa_String server, account, account_bad;
2141 struct samr_CryptPassword nt_pass, lm_pass;
2142 struct samr_Password nt_verifier, lm_verifier;
2144 uint8_t old_nt_hash[16], new_nt_hash[16];
2145 uint8_t old_lm_hash[16], new_lm_hash[16];
2147 struct samr_DomInfo1 *dominfo = NULL;
2148 struct userPwdChangeFailureInformation *reject = NULL;
2150 torture_comment(tctx, "Testing ChangePasswordUser3\n");
2152 if (newpass == NULL) {
2154 if (policy_min_pw_len == 0) {
2155 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2157 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len);
2159 } while (check_password_quality(newpass) == false);
2161 torture_comment(tctx, "Using password '%s'\n", newpass);
2164 torture_assert(tctx, *password != NULL,
2165 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2167 oldpass = *password;
2168 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2169 init_lsa_String(&account, account_string);
2171 E_md4hash(oldpass, old_nt_hash);
2172 E_md4hash(newpass, new_nt_hash);
2174 E_deshash(oldpass, old_lm_hash);
2175 E_deshash(newpass, new_lm_hash);
2177 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2178 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2179 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2181 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2182 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2183 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2185 /* Break the verification */
2186 nt_verifier.hash[0]++;
2188 r.in.server = &server;
2189 r.in.account = &account;
2190 r.in.nt_password = &nt_pass;
2191 r.in.nt_verifier = &nt_verifier;
2193 r.in.lm_password = &lm_pass;
2194 r.in.lm_verifier = &lm_verifier;
2195 r.in.password3 = NULL;
2196 r.out.dominfo = &dominfo;
2197 r.out.reject = &reject;
2199 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2200 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
2201 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
2202 torture_warning(tctx, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
2207 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2208 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2209 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2211 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2212 /* Break the NT hash */
2214 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2215 /* Unbreak it again */
2217 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2219 r.in.server = &server;
2220 r.in.account = &account;
2221 r.in.nt_password = &nt_pass;
2222 r.in.nt_verifier = &nt_verifier;
2224 r.in.lm_password = &lm_pass;
2225 r.in.lm_verifier = &lm_verifier;
2226 r.in.password3 = NULL;
2227 r.out.dominfo = &dominfo;
2228 r.out.reject = &reject;
2230 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2231 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
2232 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
2233 torture_warning(tctx, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
2238 /* This shouldn't be a valid name */
2239 init_lsa_String(&account_bad, talloc_asprintf(tctx, "%sXX", account_string));
2241 r.in.account = &account_bad;
2242 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2243 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
2244 torture_warning(tctx, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
2249 E_md4hash(oldpass, old_nt_hash);
2250 E_md4hash(newpass, new_nt_hash);
2252 E_deshash(oldpass, old_lm_hash);
2253 E_deshash(newpass, new_lm_hash);
2255 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2256 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2257 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2259 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2260 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2261 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2263 r.in.server = &server;
2264 r.in.account = &account;
2265 r.in.nt_password = &nt_pass;
2266 r.in.nt_verifier = &nt_verifier;
2268 r.in.lm_password = &lm_pass;
2269 r.in.lm_verifier = &lm_verifier;
2270 r.in.password3 = NULL;
2271 r.out.dominfo = &dominfo;
2272 r.out.reject = &reject;
2274 unix_to_nt_time(&t, time(NULL));
2276 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2278 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
2281 && handle_reject_reason
2282 && (!null_nttime(last_password_change) || !dominfo->min_password_age)) {
2283 if (dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
2285 if (reject && (reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR)) {
2286 torture_warning(tctx, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2287 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2292 /* We tested the order of precendence which is as follows:
2301 if ((dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
2302 (last_password_change + dominfo->min_password_age > t)) {
2304 if (reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2305 torture_warning(tctx, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2306 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2310 } else if ((dominfo->min_password_length > 0) &&
2311 (strlen(newpass) < dominfo->min_password_length)) {
2313 if (reject->extendedFailureReason != SAM_PWD_CHANGE_PASSWORD_TOO_SHORT) {
2314 torture_warning(tctx, "expected SAM_PWD_CHANGE_PASSWORD_TOO_SHORT (%d), got %d\n",
2315 SAM_PWD_CHANGE_PASSWORD_TOO_SHORT, reject->extendedFailureReason);
2319 } else if ((dominfo->password_history_length > 0) &&
2320 strequal(oldpass, newpass)) {
2322 if (reject->extendedFailureReason != SAM_PWD_CHANGE_PWD_IN_HISTORY) {
2323 torture_warning(tctx, "expected SAM_PWD_CHANGE_PWD_IN_HISTORY (%d), got %d\n",
2324 SAM_PWD_CHANGE_PWD_IN_HISTORY, reject->extendedFailureReason);
2327 } else if (dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
2329 if (reject->extendedFailureReason != SAM_PWD_CHANGE_NOT_COMPLEX) {
2330 torture_warning(tctx, "expected SAM_PWD_CHANGE_NOT_COMPLEX (%d), got %d\n",
2331 SAM_PWD_CHANGE_NOT_COMPLEX, reject->extendedFailureReason);
2337 if (reject->extendedFailureReason == SAM_PWD_CHANGE_PASSWORD_TOO_SHORT) {
2338 /* retry with adjusted size */
2339 return test_ChangePasswordUser3(p, tctx, account_string,
2340 dominfo->min_password_length,
2341 password, NULL, 0, false);
2345 } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2346 if (reject && reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2347 torture_warning(tctx, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2348 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2351 /* Perhaps the server has a 'min password age' set? */
2354 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3");
2355 *password = talloc_strdup(tctx, newpass);
2361 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_context *tctx,
2362 const char *account_string,
2363 struct policy_handle *handle,
2367 struct samr_ChangePasswordUser3 r;
2368 struct samr_SetUserInfo s;
2369 union samr_UserInfo u;
2370 DATA_BLOB session_key;
2371 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
2372 uint8_t confounder[16];
2373 struct MD5Context ctx;
2376 struct lsa_String server, account;
2377 struct samr_CryptPassword nt_pass;
2378 struct samr_Password nt_verifier;
2379 DATA_BLOB new_random_pass;
2382 uint8_t old_nt_hash[16], new_nt_hash[16];
2384 struct samr_DomInfo1 *dominfo = NULL;
2385 struct userPwdChangeFailureInformation *reject = NULL;
2387 new_random_pass = samr_very_rand_pass(tctx, 128);
2389 torture_assert(tctx, *password != NULL,
2390 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2392 oldpass = *password;
2393 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2394 init_lsa_String(&account, account_string);
2396 s.in.user_handle = handle;
2402 u.info25.info.fields_present = SAMR_FIELD_NT_PASSWORD_PRESENT;
2404 set_pw_in_buffer(u.info25.password.data, &new_random_pass);
2406 status = dcerpc_fetch_session_key(p, &session_key);
2407 if (!NT_STATUS_IS_OK(status)) {
2408 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
2409 s.in.level, nt_errstr(status));
2413 generate_random_buffer((uint8_t *)confounder, 16);
2416 MD5Update(&ctx, confounder, 16);
2417 MD5Update(&ctx, session_key.data, session_key.length);
2418 MD5Final(confounded_session_key.data, &ctx);
2420 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
2421 memcpy(&u.info25.password.data[516], confounder, 16);
2423 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
2425 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
2426 if (!NT_STATUS_IS_OK(status)) {
2427 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
2428 s.in.level, nt_errstr(status));
2432 torture_comment(tctx, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
2434 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2436 new_random_pass = samr_very_rand_pass(tctx, 128);
2438 mdfour(new_nt_hash, new_random_pass.data, new_random_pass.length);
2440 set_pw_in_buffer(nt_pass.data, &new_random_pass);
2441 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2442 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2444 r.in.server = &server;
2445 r.in.account = &account;
2446 r.in.nt_password = &nt_pass;
2447 r.in.nt_verifier = &nt_verifier;
2449 r.in.lm_password = NULL;
2450 r.in.lm_verifier = NULL;
2451 r.in.password3 = NULL;
2452 r.out.dominfo = &dominfo;
2453 r.out.reject = &reject;
2455 unix_to_nt_time(&t, time(NULL));
2457 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2459 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2460 if (reject && reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2461 torture_warning(tctx, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2462 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2465 /* Perhaps the server has a 'min password age' set? */
2467 } else if (!NT_STATUS_IS_OK(status)) {
2468 torture_warning(tctx, "ChangePasswordUser3 failed - %s\n", nt_errstr(status));
2472 newpass = samr_rand_pass(tctx, 128);
2474 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2476 E_md4hash(newpass, new_nt_hash);
2478 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2479 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2480 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2482 r.in.server = &server;
2483 r.in.account = &account;
2484 r.in.nt_password = &nt_pass;
2485 r.in.nt_verifier = &nt_verifier;
2487 r.in.lm_password = NULL;
2488 r.in.lm_verifier = NULL;
2489 r.in.password3 = NULL;
2490 r.out.dominfo = &dominfo;
2491 r.out.reject = &reject;
2493 unix_to_nt_time(&t, time(NULL));
2495 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2497 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2498 if (reject && reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2499 torture_warning(tctx, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2500 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2503 /* Perhaps the server has a 'min password age' set? */
2506 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3 (on second random password)");
2507 *password = talloc_strdup(tctx, newpass);
2514 static bool test_GetMembersInAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2515 struct policy_handle *alias_handle)
2517 struct samr_GetMembersInAlias r;
2518 struct lsa_SidArray sids;
2521 torture_comment(tctx, "Testing GetMembersInAlias\n");
2523 r.in.alias_handle = alias_handle;
2526 status = dcerpc_samr_GetMembersInAlias(p, tctx, &r);
2527 torture_assert_ntstatus_ok(tctx, status, "GetMembersInAlias");
2532 static bool test_AddMemberToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2533 struct policy_handle *alias_handle,
2534 const struct dom_sid *domain_sid)
2536 struct samr_AddAliasMember r;
2537 struct samr_DeleteAliasMember d;
2539 struct dom_sid *sid;
2541 sid = dom_sid_add_rid(tctx, domain_sid, 512);
2543 torture_comment(tctx, "testing AddAliasMember\n");
2544 r.in.alias_handle = alias_handle;
2547 status = dcerpc_samr_AddAliasMember(p, tctx, &r);
2548 torture_assert_ntstatus_ok(tctx, status, "AddAliasMember");
2550 d.in.alias_handle = alias_handle;
2553 status = dcerpc_samr_DeleteAliasMember(p, tctx, &d);
2554 torture_assert_ntstatus_ok(tctx, status, "DelAliasMember");
2559 static bool test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2560 struct policy_handle *alias_handle)
2562 struct samr_AddMultipleMembersToAlias a;
2563 struct samr_RemoveMultipleMembersFromAlias r;
2565 struct lsa_SidArray sids;
2567 torture_comment(tctx, "testing AddMultipleMembersToAlias\n");
2568 a.in.alias_handle = alias_handle;
2572 sids.sids = talloc_array(tctx, struct lsa_SidPtr, 3);
2574 sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2575 sids.sids[1].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-2");
2576 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-3");
2578 status = dcerpc_samr_AddMultipleMembersToAlias(p, tctx, &a);
2579 torture_assert_ntstatus_ok(tctx, status, "AddMultipleMembersToAlias");
2582 torture_comment(tctx, "testing RemoveMultipleMembersFromAlias\n");
2583 r.in.alias_handle = alias_handle;
2586 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2587 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2589 /* strange! removing twice doesn't give any error */
2590 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2591 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2593 /* but removing an alias that isn't there does */
2594 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-4");
2596 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2597 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, "RemoveMultipleMembersFromAlias");
2602 static bool test_GetAliasMembership(struct dcerpc_pipe *p,
2603 struct torture_context *tctx,
2604 struct policy_handle *domain_handle)
2606 struct samr_GetAliasMembership r;
2607 struct lsa_SidArray sids;
2608 struct samr_Ids rids;
2611 torture_comment(tctx, "Testing GetAliasMembership\n");
2613 if (torture_setting_bool(tctx, "samba4", false)) {
2614 torture_skip(tctx, "skipping GetAliasMembership against s4");
2617 r.in.domain_handle = domain_handle;
2622 sids.sids = talloc_zero_array(tctx, struct lsa_SidPtr, sids.num_sids);
2624 status = dcerpc_samr_GetAliasMembership(p, tctx, &r);
2625 torture_assert_ntstatus_ok(tctx, status,
2626 "samr_GetAliasMembership failed");
2628 torture_assert_int_equal(tctx, sids.num_sids, rids.count,
2629 "protocol misbehaviour");
2632 sids.sids = talloc_zero_array(tctx, struct lsa_SidPtr, sids.num_sids);
2633 sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2635 status = dcerpc_samr_GetAliasMembership(p, tctx, &r);
2636 torture_assert_ntstatus_ok(tctx, status,
2637 "samr_GetAliasMembership failed");
2640 /* only true for w2k8 it seems
2641 * win7, xp, w2k3 will return a 0 length array pointer */
2643 if (rids.ids && (rids.count == 0)) {
2644 torture_fail(tctx, "samr_GetAliasMembership returned 0 count and a rids array");
2647 if (!rids.ids && rids.count) {
2648 torture_fail(tctx, "samr_GetAliasMembership returned non-0 count but no rids");
2654 static bool test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2655 struct policy_handle *user_handle)
2657 struct samr_TestPrivateFunctionsUser r;
2660 torture_comment(tctx, "Testing TestPrivateFunctionsUser\n");
2662 r.in.user_handle = user_handle;
2664 status = dcerpc_samr_TestPrivateFunctionsUser(p, tctx, &r);
2665 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsUser");
2670 static bool test_QueryUserInfo_pwdlastset(struct dcerpc_pipe *p,
2671 struct torture_context *tctx,
2672 struct policy_handle *handle,
2677 uint16_t levels[] = { /* 3, */ 5, 21 };
2679 NTTIME pwdlastset3 = 0;
2680 NTTIME pwdlastset5 = 0;
2681 NTTIME pwdlastset21 = 0;
2683 torture_comment(tctx, "Testing QueryUserInfo%s level 5 and 21 call ",
2684 use_info2 ? "2":"");
2686 for (i=0; i<ARRAY_SIZE(levels); i++) {
2688 struct samr_QueryUserInfo r;
2689 struct samr_QueryUserInfo2 r2;
2690 union samr_UserInfo *info;
2693 r2.in.user_handle = handle;
2694 r2.in.level = levels[i];
2695 r2.out.info = &info;
2696 status = dcerpc_samr_QueryUserInfo2(p, tctx, &r2);
2699 r.in.user_handle = handle;
2700 r.in.level = levels[i];
2702 status = dcerpc_samr_QueryUserInfo(p, tctx, &r);
2705 if (!NT_STATUS_IS_OK(status) &&
2706 !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
2707 torture_warning(tctx, "QueryUserInfo%s level %u failed - %s\n",
2708 use_info2 ? "2":"", levels[i], nt_errstr(status));
2712 switch (levels[i]) {
2714 pwdlastset3 = info->info3.last_password_change;
2717 pwdlastset5 = info->info5.last_password_change;
2720 pwdlastset21 = info->info21.last_password_change;
2726 /* torture_assert_int_equal(tctx, pwdlastset3, pwdlastset5,
2727 "pwdlastset mixup"); */
2728 torture_assert_int_equal(tctx, pwdlastset5, pwdlastset21,
2729 "pwdlastset mixup");
2731 *pwdlastset = pwdlastset21;
2733 torture_comment(tctx, "(pwdlastset: %lld)\n", *pwdlastset);
2738 static bool test_SamLogon(struct torture_context *tctx,
2739 struct dcerpc_pipe *p,
2740 struct cli_credentials *test_credentials,
2741 NTSTATUS expected_result,
2745 struct netr_LogonSamLogonEx r;
2746 union netr_LogonLevel logon;
2747 union netr_Validation validation;
2748 uint8_t authoritative;
2749 struct netr_IdentityInfo identity;
2750 struct netr_NetworkInfo ninfo;
2751 struct netr_PasswordInfo pinfo;
2752 DATA_BLOB names_blob, chal, lm_resp, nt_resp;
2753 int flags = CLI_CRED_NTLM_AUTH;
2754 uint32_t samlogon_flags = 0;
2755 struct netlogon_creds_CredentialState *creds;
2756 struct netr_Authenticator a;
2758 torture_assert_ntstatus_ok(tctx, dcerpc_schannel_creds(p->conn->security_state.generic_state, tctx, &creds), "");
2760 if (lp_client_lanman_auth(tctx->lp_ctx)) {
2761 flags |= CLI_CRED_LANMAN_AUTH;
2764 if (lp_client_ntlmv2_auth(tctx->lp_ctx)) {
2765 flags |= CLI_CRED_NTLMv2_AUTH;
2768 cli_credentials_get_ntlm_username_domain(test_credentials, tctx,
2769 &identity.account_name.string,
2770 &identity.domain_name.string);
2772 identity.parameter_control =
2773 MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT |
2774 MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;
2775 identity.logon_id_low = 0;
2776 identity.logon_id_high = 0;
2777 identity.workstation.string = cli_credentials_get_workstation(test_credentials);
2780 netlogon_creds_client_authenticator(creds, &a);
2782 if (!E_deshash(cli_credentials_get_password(test_credentials), pinfo.lmpassword.hash)) {
2783 ZERO_STRUCT(pinfo.lmpassword.hash);
2785 E_md4hash(cli_credentials_get_password(test_credentials), pinfo.ntpassword.hash);
2787 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
2788 netlogon_creds_arcfour_crypt(creds, pinfo.lmpassword.hash, 16);
2789 netlogon_creds_arcfour_crypt(creds, pinfo.ntpassword.hash, 16);
2791 netlogon_creds_des_encrypt(creds, &pinfo.lmpassword);
2792 netlogon_creds_des_encrypt(creds, &pinfo.ntpassword);
2795 pinfo.identity_info = identity;
2796 logon.password = &pinfo;
2798 r.in.logon_level = NetlogonInteractiveInformation;
2800 generate_random_buffer(ninfo.challenge,
2801 sizeof(ninfo.challenge));
2802 chal = data_blob_const(ninfo.challenge,
2803 sizeof(ninfo.challenge));
2805 names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(test_credentials),
2806 cli_credentials_get_domain(test_credentials));
2808 status = cli_credentials_get_ntlm_response(test_credentials, tctx,
2814 torture_assert_ntstatus_ok(tctx, status, "cli_credentials_get_ntlm_response failed");
2816 ninfo.lm.data = lm_resp.data;
2817 ninfo.lm.length = lm_resp.length;
2819 ninfo.nt.data = nt_resp.data;
2820 ninfo.nt.length = nt_resp.length;
2822 ninfo.identity_info = identity;
2823 logon.network = &ninfo;
2825 r.in.logon_level = NetlogonNetworkInformation;
2828 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2829 r.in.computer_name = cli_credentials_get_workstation(test_credentials);
2830 r.in.logon = &logon;
2831 r.in.flags = &samlogon_flags;
2832 r.out.flags = &samlogon_flags;
2833 r.out.validation = &validation;
2834 r.out.authoritative = &authoritative;
2836 torture_comment(tctx, "Testing LogonSamLogon with name %s\n", identity.account_name.string);
2838 r.in.validation_level = 6;
2840 status = dcerpc_netr_LogonSamLogonEx(p, tctx, &r);
2841 if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
2842 r.in.validation_level = 3;
2843 status = dcerpc_netr_LogonSamLogonEx(p, tctx, &r);
2845 if (!NT_STATUS_IS_OK(status)) {
2846 torture_assert_ntstatus_equal(tctx, status, expected_result, "LogonSamLogonEx failed");
2849 torture_assert_ntstatus_ok(tctx, status, "LogonSamLogonEx failed");
2855 static bool test_SamLogon_with_creds(struct torture_context *tctx,
2856 struct dcerpc_pipe *p,
2857 struct cli_credentials *machine_creds,
2858 const char *acct_name,
2860 NTSTATUS expected_samlogon_result,
2864 struct cli_credentials *test_credentials;
2866 test_credentials = cli_credentials_init(tctx);
2868 cli_credentials_set_workstation(test_credentials,
2869 cli_credentials_get_workstation(machine_creds), CRED_SPECIFIED);
2870 cli_credentials_set_domain(test_credentials,
2871 cli_credentials_get_domain(machine_creds), CRED_SPECIFIED);
2872 cli_credentials_set_username(test_credentials,
2873 acct_name, CRED_SPECIFIED);
2874 cli_credentials_set_password(test_credentials,
2875 password, CRED_SPECIFIED);
2877 torture_comment(tctx, "testing samlogon (%s) as %s password: %s\n",
2878 interactive ? "interactive" : "network", acct_name, password);
2880 if (!test_SamLogon(tctx, p, test_credentials,
2881 expected_samlogon_result, interactive)) {
2882 torture_warning(tctx, "new password did not work\n");
2889 static bool test_SetPassword_level(struct dcerpc_pipe *p,
2890 struct dcerpc_pipe *np,
2891 struct torture_context *tctx,
2892 struct policy_handle *handle,
2894 uint32_t fields_present,
2895 uint8_t password_expired,
2896 bool *matched_expected_error,
2898 const char *acct_name,
2900 struct cli_credentials *machine_creds,
2901 bool use_queryinfo2,
2903 NTSTATUS expected_samlogon_result)
2905 const char *fields = NULL;
2912 fields = talloc_asprintf(tctx, "(fields_present: 0x%08x)",
2919 torture_comment(tctx, "Testing SetUserInfo%s level %d call "
2920 "(password_expired: %d) %s\n",
2921 use_setinfo2 ? "2":"", level, password_expired,
2922 fields ? fields : "");
2924 if (!test_SetUserPass_level_ex(p, tctx, handle, level,
2929 matched_expected_error)) {
2933 if (!test_QueryUserInfo_pwdlastset(p, tctx, handle,
2939 if (*matched_expected_error == true) {
2943 if (!test_SamLogon_with_creds(tctx, np,
2947 expected_samlogon_result,
2955 static bool setup_schannel_netlogon_pipe(struct torture_context *tctx,
2956 struct cli_credentials *credentials,
2957 struct dcerpc_pipe **p)
2959 struct dcerpc_binding *b;
2961 torture_assert_ntstatus_ok(tctx, torture_rpc_binding(tctx, &b),
2962 "failed to get rpc binding");
2964 /* We have to use schannel, otherwise the SamLogonEx fails
2965 * with INTERNAL_ERROR */
2967 b->flags &= ~DCERPC_AUTH_OPTIONS;
2968 b->flags |= DCERPC_SCHANNEL | DCERPC_SIGN | DCERPC_SCHANNEL_128;
2970 torture_assert_ntstatus_ok(tctx,
2971 dcerpc_pipe_connect_b(tctx, p, b, &ndr_table_netlogon,
2972 credentials, tctx->ev, tctx->lp_ctx),
2973 "failed to bind to netlogon");
2978 static bool test_SetPassword_pwdlastset(struct dcerpc_pipe *p,
2979 struct torture_context *tctx,
2980 uint32_t acct_flags,
2981 const char *acct_name,
2982 struct policy_handle *handle,
2984 struct cli_credentials *machine_credentials)
2986 int s = 0, q = 0, f = 0, l = 0, z = 0;
2989 bool set_levels[] = { false, true };
2990 bool query_levels[] = { false, true };
2991 uint32_t levels[] = { 18, 21, 26, 23, 24, 25 }; /* Second half only used when TEST_ALL_LEVELS defined */
2992 uint32_t nonzeros[] = { 1, 24 };
2993 uint32_t fields_present[] = {
2995 SAMR_FIELD_EXPIRED_FLAG,
2996 SAMR_FIELD_LAST_PWD_CHANGE,
2997 SAMR_FIELD_EXPIRED_FLAG | SAMR_FIELD_LAST_PWD_CHANGE,
2999 SAMR_FIELD_NT_PASSWORD_PRESENT,
3000 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
3001 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
3002 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
3003 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
3004 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
3005 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE | SAMR_FIELD_EXPIRED_FLAG
3007 struct dcerpc_pipe *np = NULL;
3009 if (torture_setting_bool(tctx, "samba3", false)) {
3011 torture_comment(tctx, "Samba3 has second granularity, setting delay to: %d\n",
3015 torture_assert(tctx, setup_schannel_netlogon_pipe(tctx, machine_credentials, &np), "");
3017 /* set to 1 to enable testing for all possible opcode
3018 (SetUserInfo, SetUserInfo2, QueryUserInfo, QueryUserInfo2)
3021 #define TEST_ALL_LEVELS 1
3022 #define TEST_SET_LEVELS 1
3023 #define TEST_QUERY_LEVELS 1
3025 #ifdef TEST_ALL_LEVELS
3026 for (l=0; l<ARRAY_SIZE(levels); l++) {
3028 for (l=0; l<(ARRAY_SIZE(levels))/2; l++) {
3030 for (z=0; z<ARRAY_SIZE(nonzeros); z++) {
3031 for (f=0; f<ARRAY_SIZE(fields_present); f++) {
3032 #ifdef TEST_SET_LEVELS
3033 for (s=0; s<ARRAY_SIZE(set_levels); s++) {
3035 #ifdef TEST_QUERY_LEVELS
3036 for (q=0; q<ARRAY_SIZE(query_levels); q++) {
3038 NTTIME pwdlastset_old = 0;
3039 NTTIME pwdlastset_new = 0;
3040 bool matched_expected_error = false;
3041 NTSTATUS expected_samlogon_result = NT_STATUS_ACCOUNT_DISABLED;
3043 torture_comment(tctx, "------------------------------\n"
3044 "Testing pwdLastSet attribute for flags: 0x%08x "
3045 "(s: %d (l: %d), q: %d)\n",
3046 acct_flags, s, levels[l], q);
3048 switch (levels[l]) {
3052 if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3053 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT))) {
3054 expected_samlogon_result = NT_STATUS_WRONG_PASSWORD;
3062 /* set a password and force password change (pwdlastset 0) by
3063 * setting the password expired flag to a non-0 value */
3065 if (!test_SetPassword_level(p, np, tctx, handle,
3069 &matched_expected_error,
3073 machine_credentials,
3076 expected_samlogon_result)) {
3080 if (matched_expected_error == true) {
3081 /* skipping on expected failure */
3085 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3086 * set without the SAMR_FIELD_EXPIRED_FLAG */
3088 switch (levels[l]) {
3092 if ((pwdlastset_new != 0) &&
3093 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
3094 torture_comment(tctx, "not considering a non-0 "
3095 "pwdLastSet as a an error as the "
3096 "SAMR_FIELD_EXPIRED_FLAG has not "
3101 if (pwdlastset_new != 0) {
3102 torture_warning(tctx, "pwdLastSet test failed: "
3103 "expected pwdLastSet 0 but got %lld\n",
3110 switch (levels[l]) {
3114 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3115 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3116 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3117 (pwdlastset_old >= pwdlastset_new)) {
3118 torture_warning(tctx, "pwdlastset not increasing\n");
3123 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3124 (pwdlastset_old >= pwdlastset_new)) {
3125 torture_warning(tctx, "pwdlastset not increasing\n");
3135 /* set a password, pwdlastset needs to get updated (increased
3136 * value), password_expired value used here is 0 */
3138 if (!test_SetPassword_level(p, np, tctx, handle,
3142 &matched_expected_error,
3146 machine_credentials,
3149 expected_samlogon_result)) {
3153 /* when a password has been changed, pwdlastset must not be 0 afterwards
3154 * and must be larger then the old value */
3156 switch (levels[l]) {
3161 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3162 * password has been changed, old and new pwdlastset
3163 * need to be the same value */
3165 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3166 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3167 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3169 torture_assert_int_equal(tctx, pwdlastset_old,
3170 pwdlastset_new, "pwdlastset must be equal");
3174 if (pwdlastset_old >= pwdlastset_new) {
3175 torture_warning(tctx, "pwdLastSet test failed: "
3176 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
3177 pwdlastset_old, pwdlastset_new);
3180 if (pwdlastset_new == 0) {
3181 torture_warning(tctx, "pwdLastSet test failed: "
3182 "expected non-0 pwdlastset, got: %lld\n",
3188 switch (levels[l]) {
3192 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3193 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3194 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3195 (pwdlastset_old >= pwdlastset_new)) {
3196 torture_warning(tctx, "pwdlastset not increasing\n");
3201 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3202 (pwdlastset_old >= pwdlastset_new)) {
3203 torture_warning(tctx, "pwdlastset not increasing\n");
3209 pwdlastset_old = pwdlastset_new;
3215 /* set a password, pwdlastset needs to get updated (increased
3216 * value), password_expired value used here is 0 */
3218 if (!test_SetPassword_level(p, np, tctx, handle,