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,2009
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"
39 #define TEST_ACCOUNT_NAME "samrtorturetest"
40 #define TEST_ACCOUNT_NAME_PWD "samrpwdlastset"
41 #define TEST_ALIASNAME "samrtorturetestalias"
42 #define TEST_GROUPNAME "samrtorturetestgroup"
43 #define TEST_MACHINENAME "samrtestmach$"
44 #define TEST_DOMAINNAME "samrtestdom$"
46 enum torture_samr_choice {
47 TORTURE_SAMR_PASSWORDS,
48 TORTURE_SAMR_PASSWORDS_PWDLASTSET,
49 TORTURE_SAMR_USER_ATTRIBUTES,
50 TORTURE_SAMR_USER_PRIVILEGES,
52 TORTURE_SAMR_MANY_ACCOUNTS,
53 TORTURE_SAMR_MANY_GROUPS,
54 TORTURE_SAMR_MANY_ALIASES
57 struct torture_samr_context {
58 struct policy_handle handle;
59 struct cli_credentials *machine_credentials;
60 enum torture_samr_choice choice;
61 uint32_t num_objects_large_dc;
64 static bool test_QueryUserInfo(struct dcerpc_pipe *p,
65 struct torture_context *tctx,
66 struct policy_handle *handle);
68 static bool test_QueryUserInfo2(struct dcerpc_pipe *p,
69 struct torture_context *tctx,
70 struct policy_handle *handle);
72 static bool test_QueryAliasInfo(struct dcerpc_pipe *p,
73 struct torture_context *tctx,
74 struct policy_handle *handle);
76 static bool test_ChangePassword(struct dcerpc_pipe *p,
77 struct torture_context *tctx,
78 const char *acct_name,
79 struct policy_handle *domain_handle, char **password);
81 static void init_lsa_String(struct lsa_String *string, const char *s)
86 static void init_lsa_StringLarge(struct lsa_StringLarge *string, const char *s)
91 static void init_lsa_BinaryString(struct lsa_BinaryString *string, const char *s, uint32_t length)
93 string->length = length;
94 string->size = length;
95 string->array = (uint16_t *)discard_const(s);
98 bool test_samr_handle_Close(struct dcerpc_pipe *p, struct torture_context *tctx,
99 struct policy_handle *handle)
104 r.in.handle = handle;
105 r.out.handle = handle;
107 status = dcerpc_samr_Close(p, tctx, &r);
108 torture_assert_ntstatus_ok(tctx, status, "Close");
113 static bool test_Shutdown(struct dcerpc_pipe *p, struct torture_context *tctx,
114 struct policy_handle *handle)
117 struct samr_Shutdown r;
119 if (!torture_setting_bool(tctx, "dangerous", false)) {
120 torture_skip(tctx, "samr_Shutdown disabled - enable dangerous tests to use\n");
124 r.in.connect_handle = handle;
126 torture_comment(tctx, "testing samr_Shutdown\n");
128 status = dcerpc_samr_Shutdown(p, tctx, &r);
129 torture_assert_ntstatus_ok(tctx, status, "samr_Shutdown");
134 static bool test_SetDsrmPassword(struct dcerpc_pipe *p, struct torture_context *tctx,
135 struct policy_handle *handle)
138 struct samr_SetDsrmPassword r;
139 struct lsa_String string;
140 struct samr_Password hash;
142 if (!torture_setting_bool(tctx, "dangerous", false)) {
143 torture_skip(tctx, "samr_SetDsrmPassword disabled - enable dangerous tests to use");
146 E_md4hash("TeSTDSRM123", hash.hash);
148 init_lsa_String(&string, "Administrator");
154 torture_comment(tctx, "testing samr_SetDsrmPassword\n");
156 status = dcerpc_samr_SetDsrmPassword(p, tctx, &r);
157 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_SUPPORTED, "samr_SetDsrmPassword");
163 static bool test_QuerySecurity(struct dcerpc_pipe *p,
164 struct torture_context *tctx,
165 struct policy_handle *handle)
168 struct samr_QuerySecurity r;
169 struct samr_SetSecurity s;
170 struct sec_desc_buf *sdbuf = NULL;
172 r.in.handle = handle;
174 r.out.sdbuf = &sdbuf;
176 status = dcerpc_samr_QuerySecurity(p, tctx, &r);
177 torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
179 torture_assert(tctx, sdbuf != NULL, "sdbuf is NULL");
181 s.in.handle = handle;
185 if (torture_setting_bool(tctx, "samba4", false)) {
186 torture_skip(tctx, "skipping SetSecurity test against Samba4\n");
189 status = dcerpc_samr_SetSecurity(p, tctx, &s);
190 torture_assert_ntstatus_ok(tctx, status, "SetSecurity");
192 status = dcerpc_samr_QuerySecurity(p, tctx, &r);
193 torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
199 static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
200 struct policy_handle *handle, uint32_t base_acct_flags,
201 const char *base_account_name)
204 struct samr_SetUserInfo s;
205 struct samr_SetUserInfo2 s2;
206 struct samr_QueryUserInfo q;
207 struct samr_QueryUserInfo q0;
208 union samr_UserInfo u;
209 union samr_UserInfo *info;
211 const char *test_account_name;
213 uint32_t user_extra_flags = 0;
215 if (!torture_setting_bool(tctx, "samba3", false)) {
216 if (base_acct_flags == ACB_NORMAL) {
217 /* When created, accounts are expired by default */
218 user_extra_flags = ACB_PW_EXPIRED;
222 s.in.user_handle = handle;
225 s2.in.user_handle = handle;
228 q.in.user_handle = handle;
232 #define TESTCALL(call, r) \
233 status = dcerpc_samr_ ##call(p, tctx, &r); \
234 if (!NT_STATUS_IS_OK(status)) { \
235 torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
236 r.in.level, nt_errstr(status), __location__); \
241 #define STRING_EQUAL(s1, s2, field) \
242 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
243 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
244 #field, s2, __location__); \
249 #define MEM_EQUAL(s1, s2, length, field) \
250 if ((s1 && !s2) || (s2 && !s1) || memcmp(s1, s2, length)) { \
251 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
252 #field, (const char *)s2, __location__); \
257 #define INT_EQUAL(i1, i2, field) \
259 torture_comment(tctx, "Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \
260 #field, (unsigned long long)i2, (unsigned long long)i1, __location__); \
265 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
266 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
268 TESTCALL(QueryUserInfo, q) \
270 s2.in.level = lvl1; \
273 ZERO_STRUCT(u.info21); \
274 u.info21.fields_present = fpval; \
276 init_lsa_String(&u.info ## lvl1.field1, value); \
277 TESTCALL(SetUserInfo, s) \
278 TESTCALL(SetUserInfo2, s2) \
279 init_lsa_String(&u.info ## lvl1.field1, ""); \
280 TESTCALL(QueryUserInfo, q); \
282 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
284 TESTCALL(QueryUserInfo, q) \
286 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
289 #define TEST_USERINFO_BINARYSTRING(lvl1, field1, lvl2, field2, value, fpval) do { \
290 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
292 TESTCALL(QueryUserInfo, q) \
294 s2.in.level = lvl1; \
297 ZERO_STRUCT(u.info21); \
298 u.info21.fields_present = fpval; \
300 init_lsa_BinaryString(&u.info ## lvl1.field1, value, strlen(value)); \
301 TESTCALL(SetUserInfo, s) \
302 TESTCALL(SetUserInfo2, s2) \
303 init_lsa_BinaryString(&u.info ## lvl1.field1, "", 1); \
304 TESTCALL(QueryUserInfo, q); \
306 MEM_EQUAL(u.info ## lvl1.field1.array, value, strlen(value), field1); \
308 TESTCALL(QueryUserInfo, q) \
310 MEM_EQUAL(u.info ## lvl2.field2.array, value, strlen(value), field2); \
313 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
314 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
316 TESTCALL(QueryUserInfo, q) \
318 s2.in.level = lvl1; \
321 uint8_t *bits = u.info21.logon_hours.bits; \
322 ZERO_STRUCT(u.info21); \
323 if (fpval == SAMR_FIELD_LOGON_HOURS) { \
324 u.info21.logon_hours.units_per_week = 168; \
325 u.info21.logon_hours.bits = bits; \
327 u.info21.fields_present = fpval; \
329 u.info ## lvl1.field1 = value; \
330 TESTCALL(SetUserInfo, s) \
331 TESTCALL(SetUserInfo2, s2) \
332 u.info ## lvl1.field1 = 0; \
333 TESTCALL(QueryUserInfo, q); \
335 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
337 TESTCALL(QueryUserInfo, q) \
339 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
342 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
343 TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
347 do { TESTCALL(QueryUserInfo, q0) } while (0);
349 TEST_USERINFO_STRING(2, comment, 1, comment, "xx2-1 comment", 0);
350 TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
351 TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment",
354 test_account_name = talloc_asprintf(tctx, "%sxx7-1", base_account_name);
355 TEST_USERINFO_STRING(7, account_name, 1, account_name, base_account_name, 0);
356 test_account_name = talloc_asprintf(tctx, "%sxx7-3", base_account_name);
357 TEST_USERINFO_STRING(7, account_name, 3, account_name, base_account_name, 0);
358 test_account_name = talloc_asprintf(tctx, "%sxx7-5", base_account_name);
359 TEST_USERINFO_STRING(7, account_name, 5, account_name, base_account_name, 0);
360 test_account_name = talloc_asprintf(tctx, "%sxx7-6", base_account_name);
361 TEST_USERINFO_STRING(7, account_name, 6, account_name, base_account_name, 0);
362 test_account_name = talloc_asprintf(tctx, "%sxx7-7", base_account_name);
363 TEST_USERINFO_STRING(7, account_name, 7, account_name, base_account_name, 0);
364 test_account_name = talloc_asprintf(tctx, "%sxx7-21", base_account_name);
365 TEST_USERINFO_STRING(7, account_name, 21, account_name, base_account_name, 0);
366 test_account_name = base_account_name;
367 TEST_USERINFO_STRING(21, account_name, 21, account_name, base_account_name,
368 SAMR_FIELD_ACCOUNT_NAME);
370 TEST_USERINFO_STRING(6, full_name, 1, full_name, "xx6-1 full_name", 0);
371 TEST_USERINFO_STRING(6, full_name, 3, full_name, "xx6-3 full_name", 0);
372 TEST_USERINFO_STRING(6, full_name, 5, full_name, "xx6-5 full_name", 0);
373 TEST_USERINFO_STRING(6, full_name, 6, full_name, "xx6-6 full_name", 0);
374 TEST_USERINFO_STRING(6, full_name, 8, full_name, "xx6-8 full_name", 0);
375 TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
376 TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
377 TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name",
378 SAMR_FIELD_FULL_NAME);
380 TEST_USERINFO_STRING(6, full_name, 1, full_name, "", 0);
381 TEST_USERINFO_STRING(6, full_name, 3, full_name, "", 0);
382 TEST_USERINFO_STRING(6, full_name, 5, full_name, "", 0);
383 TEST_USERINFO_STRING(6, full_name, 6, full_name, "", 0);
384 TEST_USERINFO_STRING(6, full_name, 8, full_name, "", 0);
385 TEST_USERINFO_STRING(6, full_name, 21, full_name, "", 0);
386 TEST_USERINFO_STRING(8, full_name, 21, full_name, "", 0);
387 TEST_USERINFO_STRING(21, full_name, 21, full_name, "",
388 SAMR_FIELD_FULL_NAME);
390 TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
391 TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
392 TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
393 TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script",
394 SAMR_FIELD_LOGON_SCRIPT);
396 TEST_USERINFO_STRING(12, profile_path, 3, profile_path, "xx12-3 profile_path", 0);
397 TEST_USERINFO_STRING(12, profile_path, 5, profile_path, "xx12-5 profile_path", 0);
398 TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
399 TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path",
400 SAMR_FIELD_PROFILE_PATH);
402 TEST_USERINFO_STRING(10, home_directory, 3, home_directory, "xx10-3 home_directory", 0);
403 TEST_USERINFO_STRING(10, home_directory, 5, home_directory, "xx10-5 home_directory", 0);
404 TEST_USERINFO_STRING(10, home_directory, 21, home_directory, "xx10-21 home_directory", 0);
405 TEST_USERINFO_STRING(21, home_directory, 21, home_directory, "xx21-21 home_directory",
406 SAMR_FIELD_HOME_DIRECTORY);
407 TEST_USERINFO_STRING(21, home_directory, 10, home_directory, "xx21-10 home_directory",
408 SAMR_FIELD_HOME_DIRECTORY);
410 TEST_USERINFO_STRING(10, home_drive, 3, home_drive, "xx10-3 home_drive", 0);
411 TEST_USERINFO_STRING(10, home_drive, 5, home_drive, "xx10-5 home_drive", 0);
412 TEST_USERINFO_STRING(10, home_drive, 21, home_drive, "xx10-21 home_drive", 0);
413 TEST_USERINFO_STRING(21, home_drive, 21, home_drive, "xx21-21 home_drive",
414 SAMR_FIELD_HOME_DRIVE);
415 TEST_USERINFO_STRING(21, home_drive, 10, home_drive, "xx21-10 home_drive",
416 SAMR_FIELD_HOME_DRIVE);
418 TEST_USERINFO_STRING(13, description, 1, description, "xx13-1 description", 0);
419 TEST_USERINFO_STRING(13, description, 5, description, "xx13-5 description", 0);
420 TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
421 TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description",
422 SAMR_FIELD_DESCRIPTION);
424 TEST_USERINFO_STRING(14, workstations, 3, workstations, "14workstation3", 0);
425 TEST_USERINFO_STRING(14, workstations, 5, workstations, "14workstation4", 0);
426 TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
427 TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21",
428 SAMR_FIELD_WORKSTATIONS);
429 TEST_USERINFO_STRING(21, workstations, 3, workstations, "21workstation3",
430 SAMR_FIELD_WORKSTATIONS);
431 TEST_USERINFO_STRING(21, workstations, 5, workstations, "21workstation5",
432 SAMR_FIELD_WORKSTATIONS);
433 TEST_USERINFO_STRING(21, workstations, 14, workstations, "21workstation14",
434 SAMR_FIELD_WORKSTATIONS);
436 TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
437 TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "xx21-21 parameters",
438 SAMR_FIELD_PARAMETERS);
439 TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "xx21-20 parameters",
440 SAMR_FIELD_PARAMETERS);
441 /* also empty user parameters are allowed */
442 TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "", 0);
443 TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "",
444 SAMR_FIELD_PARAMETERS);
445 TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "",
446 SAMR_FIELD_PARAMETERS);
448 /* Samba 3 cannot store country_code and copy_page atm. - gd */
449 if (!torture_setting_bool(tctx, "samba3", false)) {
450 TEST_USERINFO_INT(2, country_code, 2, country_code, __LINE__, 0);
451 TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
452 TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__,
453 SAMR_FIELD_COUNTRY_CODE);
454 TEST_USERINFO_INT(21, country_code, 2, country_code, __LINE__,
455 SAMR_FIELD_COUNTRY_CODE);
457 TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
458 TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__,
459 SAMR_FIELD_CODE_PAGE);
460 TEST_USERINFO_INT(21, code_page, 2, code_page, __LINE__,
461 SAMR_FIELD_CODE_PAGE);
464 if (!torture_setting_bool(tctx, "samba3", false)) {
465 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, __LINE__, 0);
466 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, __LINE__, 0);
467 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, __LINE__,
468 SAMR_FIELD_ACCT_EXPIRY);
469 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, __LINE__,
470 SAMR_FIELD_ACCT_EXPIRY);
471 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, __LINE__,
472 SAMR_FIELD_ACCT_EXPIRY);
474 /* Samba 3 can only store seconds / time_t in passdb - gd */
476 unix_to_nt_time(&nt, time(NULL) + __LINE__);
477 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, nt, 0);
478 unix_to_nt_time(&nt, time(NULL) + __LINE__);
479 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, nt, 0);
480 unix_to_nt_time(&nt, time(NULL) + __LINE__);
481 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
482 unix_to_nt_time(&nt, time(NULL) + __LINE__);
483 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
484 unix_to_nt_time(&nt, time(NULL) + __LINE__);
485 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
488 TEST_USERINFO_INT(4, logon_hours.bits[3], 3, logon_hours.bits[3], 1, 0);
489 TEST_USERINFO_INT(4, logon_hours.bits[3], 5, logon_hours.bits[3], 2, 0);
490 TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
491 TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4,
492 SAMR_FIELD_LOGON_HOURS);
494 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
495 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
496 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
498 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
499 (base_acct_flags | ACB_DISABLED),
500 (base_acct_flags | ACB_DISABLED | user_extra_flags),
503 /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
504 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
505 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
506 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
508 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
509 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
510 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
514 /* The 'autolock' flag doesn't stick - check this */
515 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
516 (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK),
517 (base_acct_flags | ACB_DISABLED | user_extra_flags),
520 /* Removing the 'disabled' flag doesn't stick - check this */
521 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
523 (base_acct_flags | ACB_DISABLED | user_extra_flags),
527 /* Samba3 cannot store these atm */
528 if (!torture_setting_bool(tctx, "samba3", false)) {
529 /* The 'store plaintext' flag does stick */
530 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
531 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED),
532 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags),
534 /* The 'use DES' flag does stick */
535 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
536 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY),
537 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags),
539 /* The 'don't require kerberos pre-authentication flag does stick */
540 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
541 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH),
542 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags),
544 /* The 'no kerberos PAC required' flag sticks */
545 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
546 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD),
547 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags),
550 TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags,
551 (base_acct_flags | ACB_DISABLED),
552 (base_acct_flags | ACB_DISABLED | user_extra_flags),
553 SAMR_FIELD_ACCT_FLAGS);
556 /* these fail with win2003 - it appears you can't set the primary gid?
557 the set succeeds, but the gid isn't changed. Very weird! */
558 TEST_USERINFO_INT(9, primary_gid, 1, primary_gid, 513);
559 TEST_USERINFO_INT(9, primary_gid, 3, primary_gid, 513);
560 TEST_USERINFO_INT(9, primary_gid, 5, primary_gid, 513);
561 TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
568 generate a random password for password change tests
570 static char *samr_rand_pass_silent(TALLOC_CTX *mem_ctx, int min_len)
572 size_t len = MAX(8, min_len) + (random() % 6);
573 char *s = generate_random_str(mem_ctx, len);
577 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
579 char *s = samr_rand_pass_silent(mem_ctx, min_len);
580 printf("Generated password '%s'\n", s);
586 generate a random password for password change tests
588 static DATA_BLOB samr_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
591 DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
592 generate_random_buffer(password.data, password.length);
594 for (i=0; i < len; i++) {
595 if (((uint16_t *)password.data)[i] == 0) {
596 ((uint16_t *)password.data)[i] = 1;
604 generate a random password for password change tests (fixed length)
606 static char *samr_rand_pass_fixed_len(TALLOC_CTX *mem_ctx, int len)
608 char *s = generate_random_str(mem_ctx, len);
609 printf("Generated password '%s'\n", s);
613 static bool test_SetUserPass(struct dcerpc_pipe *p, struct torture_context *tctx,
614 struct policy_handle *handle, char **password)
617 struct samr_SetUserInfo s;
618 union samr_UserInfo u;
620 DATA_BLOB session_key;
622 struct samr_GetUserPwInfo pwp;
623 struct samr_PwInfo info;
624 int policy_min_pw_len = 0;
625 pwp.in.user_handle = handle;
626 pwp.out.info = &info;
628 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
629 if (NT_STATUS_IS_OK(status)) {
630 policy_min_pw_len = pwp.out.info->min_password_length;
632 newpass = samr_rand_pass(tctx, policy_min_pw_len);
634 s.in.user_handle = handle;
638 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
639 u.info24.password_expired = 0;
641 status = dcerpc_fetch_session_key(p, &session_key);
642 if (!NT_STATUS_IS_OK(status)) {
643 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
644 s.in.level, nt_errstr(status));
648 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
650 torture_comment(tctx, "Testing SetUserInfo level 24 (set password)\n");
652 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
653 if (!NT_STATUS_IS_OK(status)) {
654 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
655 s.in.level, nt_errstr(status));
665 static bool test_SetUserPass_23(struct dcerpc_pipe *p, struct torture_context *tctx,
666 struct policy_handle *handle, uint32_t fields_present,
670 struct samr_SetUserInfo s;
671 union samr_UserInfo u;
673 DATA_BLOB session_key;
675 struct samr_GetUserPwInfo pwp;
676 struct samr_PwInfo info;
677 int policy_min_pw_len = 0;
678 pwp.in.user_handle = handle;
679 pwp.out.info = &info;
681 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
682 if (NT_STATUS_IS_OK(status)) {
683 policy_min_pw_len = pwp.out.info->min_password_length;
685 newpass = samr_rand_pass(tctx, policy_min_pw_len);
687 s.in.user_handle = handle;
693 u.info23.info.fields_present = fields_present;
695 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
697 status = dcerpc_fetch_session_key(p, &session_key);
698 if (!NT_STATUS_IS_OK(status)) {
699 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
700 s.in.level, nt_errstr(status));
704 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
706 torture_comment(tctx, "Testing SetUserInfo level 23 (set password)\n");
708 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
709 if (!NT_STATUS_IS_OK(status)) {
710 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
711 s.in.level, nt_errstr(status));
717 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
719 status = dcerpc_fetch_session_key(p, &session_key);
720 if (!NT_STATUS_IS_OK(status)) {
721 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
722 s.in.level, nt_errstr(status));
726 /* This should break the key nicely */
727 session_key.length--;
728 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
730 torture_comment(tctx, "Testing SetUserInfo level 23 (set password) with wrong password\n");
732 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
733 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
734 torture_warning(tctx, "SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
735 s.in.level, nt_errstr(status));
743 static bool test_SetUserPassEx(struct dcerpc_pipe *p, struct torture_context *tctx,
744 struct policy_handle *handle, bool makeshort,
748 struct samr_SetUserInfo s;
749 union samr_UserInfo u;
751 DATA_BLOB session_key;
752 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
753 uint8_t confounder[16];
755 struct MD5Context ctx;
756 struct samr_GetUserPwInfo pwp;
757 struct samr_PwInfo info;
758 int policy_min_pw_len = 0;
759 pwp.in.user_handle = handle;
760 pwp.out.info = &info;
762 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
763 if (NT_STATUS_IS_OK(status)) {
764 policy_min_pw_len = pwp.out.info->min_password_length;
766 if (makeshort && policy_min_pw_len) {
767 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len - 1);
769 newpass = samr_rand_pass(tctx, policy_min_pw_len);
772 s.in.user_handle = handle;
776 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
777 u.info26.password_expired = 0;
779 status = dcerpc_fetch_session_key(p, &session_key);
780 if (!NT_STATUS_IS_OK(status)) {
781 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
782 s.in.level, nt_errstr(status));
786 generate_random_buffer((uint8_t *)confounder, 16);
789 MD5Update(&ctx, confounder, 16);
790 MD5Update(&ctx, session_key.data, session_key.length);
791 MD5Final(confounded_session_key.data, &ctx);
793 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
794 memcpy(&u.info26.password.data[516], confounder, 16);
796 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex)\n");
798 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
799 if (!NT_STATUS_IS_OK(status)) {
800 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
801 s.in.level, nt_errstr(status));
807 /* This should break the key nicely */
808 confounded_session_key.data[0]++;
810 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
811 memcpy(&u.info26.password.data[516], confounder, 16);
813 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
815 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
816 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
817 torture_warning(tctx, "SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
818 s.in.level, nt_errstr(status));
827 static bool test_SetUserPass_25(struct dcerpc_pipe *p, struct torture_context *tctx,
828 struct policy_handle *handle, uint32_t fields_present,
832 struct samr_SetUserInfo s;
833 union samr_UserInfo u;
835 DATA_BLOB session_key;
836 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
837 struct MD5Context ctx;
838 uint8_t confounder[16];
840 struct samr_GetUserPwInfo pwp;
841 struct samr_PwInfo info;
842 int policy_min_pw_len = 0;
843 pwp.in.user_handle = handle;
844 pwp.out.info = &info;
846 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
847 if (NT_STATUS_IS_OK(status)) {
848 policy_min_pw_len = pwp.out.info->min_password_length;
850 newpass = samr_rand_pass(tctx, policy_min_pw_len);
852 s.in.user_handle = handle;
858 u.info25.info.fields_present = fields_present;
860 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
862 status = dcerpc_fetch_session_key(p, &session_key);
863 if (!NT_STATUS_IS_OK(status)) {
864 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
865 s.in.level, nt_errstr(status));
869 generate_random_buffer((uint8_t *)confounder, 16);
872 MD5Update(&ctx, confounder, 16);
873 MD5Update(&ctx, session_key.data, session_key.length);
874 MD5Final(confounded_session_key.data, &ctx);
876 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
877 memcpy(&u.info25.password.data[516], confounder, 16);
879 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex)\n");
881 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
882 if (!NT_STATUS_IS_OK(status)) {
883 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
884 s.in.level, nt_errstr(status));
890 /* This should break the key nicely */
891 confounded_session_key.data[0]++;
893 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
894 memcpy(&u.info25.password.data[516], confounder, 16);
896 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
898 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
899 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
900 torture_warning(tctx, "SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
901 s.in.level, nt_errstr(status));
908 static bool test_SetUserPass_18(struct dcerpc_pipe *p, struct torture_context *tctx,
909 struct policy_handle *handle, char **password)
912 struct samr_SetUserInfo s;
913 union samr_UserInfo u;
915 DATA_BLOB session_key;
917 struct samr_GetUserPwInfo pwp;
918 struct samr_PwInfo info;
919 int policy_min_pw_len = 0;
920 uint8_t lm_hash[16], nt_hash[16];
922 pwp.in.user_handle = handle;
923 pwp.out.info = &info;
925 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
926 if (NT_STATUS_IS_OK(status)) {
927 policy_min_pw_len = pwp.out.info->min_password_length;
929 newpass = samr_rand_pass(tctx, policy_min_pw_len);
931 s.in.user_handle = handle;
937 u.info18.nt_pwd_active = true;
938 u.info18.lm_pwd_active = true;
940 E_md4hash(newpass, nt_hash);
941 E_deshash(newpass, lm_hash);
943 status = dcerpc_fetch_session_key(p, &session_key);
944 if (!NT_STATUS_IS_OK(status)) {
945 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
946 s.in.level, nt_errstr(status));
952 in = data_blob_const(nt_hash, 16);
953 out = data_blob_talloc_zero(tctx, 16);
954 sess_crypt_blob(&out, &in, &session_key, true);
955 memcpy(u.info18.nt_pwd.hash, out.data, out.length);
959 in = data_blob_const(lm_hash, 16);
960 out = data_blob_talloc_zero(tctx, 16);
961 sess_crypt_blob(&out, &in, &session_key, true);
962 memcpy(u.info18.lm_pwd.hash, out.data, out.length);
965 torture_comment(tctx, "Testing SetUserInfo level 18 (set password hash)\n");
967 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
968 if (!NT_STATUS_IS_OK(status)) {
969 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
970 s.in.level, nt_errstr(status));
979 static bool test_SetUserPass_21(struct dcerpc_pipe *p, struct torture_context *tctx,
980 struct policy_handle *handle, uint32_t fields_present,
984 struct samr_SetUserInfo s;
985 union samr_UserInfo u;
987 DATA_BLOB session_key;
989 struct samr_GetUserPwInfo pwp;
990 struct samr_PwInfo info;
991 int policy_min_pw_len = 0;
992 uint8_t lm_hash[16], nt_hash[16];
994 pwp.in.user_handle = handle;
995 pwp.out.info = &info;
997 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
998 if (NT_STATUS_IS_OK(status)) {
999 policy_min_pw_len = pwp.out.info->min_password_length;
1001 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1003 s.in.user_handle = handle;
1007 E_md4hash(newpass, nt_hash);
1008 E_deshash(newpass, lm_hash);
1012 u.info21.fields_present = fields_present;
1014 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1015 u.info21.lm_owf_password.length = 16;
1016 u.info21.lm_owf_password.size = 16;
1017 u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
1018 u.info21.lm_password_set = true;
1021 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1022 u.info21.nt_owf_password.length = 16;
1023 u.info21.nt_owf_password.size = 16;
1024 u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
1025 u.info21.nt_password_set = true;
1028 status = dcerpc_fetch_session_key(p, &session_key);
1029 if (!NT_STATUS_IS_OK(status)) {
1030 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
1031 s.in.level, nt_errstr(status));
1035 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1037 in = data_blob_const(u.info21.lm_owf_password.array,
1038 u.info21.lm_owf_password.length);
1039 out = data_blob_talloc_zero(tctx, 16);
1040 sess_crypt_blob(&out, &in, &session_key, true);
1041 u.info21.lm_owf_password.array = (uint16_t *)out.data;
1044 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1046 in = data_blob_const(u.info21.nt_owf_password.array,
1047 u.info21.nt_owf_password.length);
1048 out = data_blob_talloc_zero(tctx, 16);
1049 sess_crypt_blob(&out, &in, &session_key, true);
1050 u.info21.nt_owf_password.array = (uint16_t *)out.data;
1053 torture_comment(tctx, "Testing SetUserInfo level 21 (set password hash)\n");
1055 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1056 if (!NT_STATUS_IS_OK(status)) {
1057 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
1058 s.in.level, nt_errstr(status));
1061 *password = newpass;
1064 /* try invalid length */
1065 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1067 u.info21.nt_owf_password.length++;
1069 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1071 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1072 torture_warning(tctx, "SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1073 s.in.level, nt_errstr(status));
1078 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1080 u.info21.lm_owf_password.length++;
1082 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1084 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1085 torture_warning(tctx, "SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1086 s.in.level, nt_errstr(status));
1094 static bool test_SetUserPass_level_ex(struct dcerpc_pipe *p,
1095 struct torture_context *tctx,
1096 struct policy_handle *handle,
1098 uint32_t fields_present,
1099 char **password, uint8_t password_expired,
1101 bool *matched_expected_error)
1104 NTSTATUS expected_error = NT_STATUS_OK;
1105 struct samr_SetUserInfo s;
1106 struct samr_SetUserInfo2 s2;
1107 union samr_UserInfo u;
1109 DATA_BLOB session_key;
1110 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
1111 struct MD5Context ctx;
1112 uint8_t confounder[16];
1114 struct samr_GetUserPwInfo pwp;
1115 struct samr_PwInfo info;
1116 int policy_min_pw_len = 0;
1117 const char *comment = NULL;
1118 uint8_t lm_hash[16], nt_hash[16];
1120 pwp.in.user_handle = handle;
1121 pwp.out.info = &info;
1123 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1124 if (NT_STATUS_IS_OK(status)) {
1125 policy_min_pw_len = pwp.out.info->min_password_length;
1127 newpass = samr_rand_pass_silent(tctx, policy_min_pw_len);
1130 s2.in.user_handle = handle;
1132 s2.in.level = level;
1134 s.in.user_handle = handle;
1139 if (fields_present & SAMR_FIELD_COMMENT) {
1140 comment = talloc_asprintf(tctx, "comment: %ld\n", time(NULL));
1147 E_md4hash(newpass, nt_hash);
1148 E_deshash(newpass, lm_hash);
1150 u.info18.nt_pwd_active = true;
1151 u.info18.lm_pwd_active = true;
1152 u.info18.password_expired = password_expired;
1154 memcpy(u.info18.lm_pwd.hash, lm_hash, 16);
1155 memcpy(u.info18.nt_pwd.hash, nt_hash, 16);
1159 E_md4hash(newpass, nt_hash);
1160 E_deshash(newpass, lm_hash);
1162 u.info21.fields_present = fields_present;
1163 u.info21.password_expired = password_expired;
1164 u.info21.comment.string = comment;
1166 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1167 u.info21.lm_owf_password.length = 16;
1168 u.info21.lm_owf_password.size = 16;
1169 u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
1170 u.info21.lm_password_set = true;
1173 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1174 u.info21.nt_owf_password.length = 16;
1175 u.info21.nt_owf_password.size = 16;
1176 u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
1177 u.info21.nt_password_set = true;
1182 u.info23.info.fields_present = fields_present;
1183 u.info23.info.password_expired = password_expired;
1184 u.info23.info.comment.string = comment;
1186 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
1190 u.info24.password_expired = password_expired;
1192 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
1196 u.info25.info.fields_present = fields_present;
1197 u.info25.info.password_expired = password_expired;
1198 u.info25.info.comment.string = comment;
1200 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
1204 u.info26.password_expired = password_expired;
1206 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
1211 status = dcerpc_fetch_session_key(p, &session_key);
1212 if (!NT_STATUS_IS_OK(status)) {
1213 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
1214 s.in.level, nt_errstr(status));
1218 generate_random_buffer((uint8_t *)confounder, 16);
1221 MD5Update(&ctx, confounder, 16);
1222 MD5Update(&ctx, session_key.data, session_key.length);
1223 MD5Final(confounded_session_key.data, &ctx);
1229 in = data_blob_const(u.info18.nt_pwd.hash, 16);
1230 out = data_blob_talloc_zero(tctx, 16);
1231 sess_crypt_blob(&out, &in, &session_key, true);
1232 memcpy(u.info18.nt_pwd.hash, out.data, out.length);
1236 in = data_blob_const(u.info18.lm_pwd.hash, 16);
1237 out = data_blob_talloc_zero(tctx, 16);
1238 sess_crypt_blob(&out, &in, &session_key, true);
1239 memcpy(u.info18.lm_pwd.hash, out.data, out.length);
1244 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1246 in = data_blob_const(u.info21.lm_owf_password.array,
1247 u.info21.lm_owf_password.length);
1248 out = data_blob_talloc_zero(tctx, 16);
1249 sess_crypt_blob(&out, &in, &session_key, true);
1250 u.info21.lm_owf_password.array = (uint16_t *)out.data;
1252 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1254 in = data_blob_const(u.info21.nt_owf_password.array,
1255 u.info21.nt_owf_password.length);
1256 out = data_blob_talloc_zero(tctx, 16);
1257 sess_crypt_blob(&out, &in, &session_key, true);
1258 u.info21.nt_owf_password.array = (uint16_t *)out.data;
1262 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
1265 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
1268 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
1269 memcpy(&u.info25.password.data[516], confounder, 16);
1272 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
1273 memcpy(&u.info26.password.data[516], confounder, 16);
1278 status = dcerpc_samr_SetUserInfo2(p, tctx, &s2);
1280 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1283 if (!NT_STATUS_IS_OK(status)) {
1284 if (fields_present == 0) {
1285 expected_error = NT_STATUS_INVALID_PARAMETER;
1287 if (fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
1288 expected_error = NT_STATUS_ACCESS_DENIED;
1292 if (!NT_STATUS_IS_OK(expected_error)) {
1294 torture_assert_ntstatus_equal(tctx,
1296 expected_error, "SetUserInfo2 failed");
1298 torture_assert_ntstatus_equal(tctx,
1300 expected_error, "SetUserInfo failed");
1302 *matched_expected_error = true;
1306 if (!NT_STATUS_IS_OK(status)) {
1307 torture_warning(tctx, "SetUserInfo%s level %u failed - %s\n",
1308 use_setinfo2 ? "2":"", level, nt_errstr(status));
1311 *password = newpass;
1317 static bool test_SetAliasInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1318 struct policy_handle *handle)
1321 struct samr_SetAliasInfo r;
1322 struct samr_QueryAliasInfo q;
1323 union samr_AliasInfo *info;
1324 uint16_t levels[] = {2, 3};
1328 /* Ignoring switch level 1, as that includes the number of members for the alias
1329 * and setting this to a wrong value might have negative consequences
1332 for (i=0;i<ARRAY_SIZE(levels);i++) {
1333 torture_comment(tctx, "Testing SetAliasInfo level %u\n", levels[i]);
1335 r.in.alias_handle = handle;
1336 r.in.level = levels[i];
1337 r.in.info = talloc(tctx, union samr_AliasInfo);
1338 switch (r.in.level) {
1339 case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
1340 case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
1341 "Test Description, should test I18N as well"); break;
1342 case ALIASINFOALL: torture_comment(tctx, "ALIASINFOALL ignored\n"); break;
1345 status = dcerpc_samr_SetAliasInfo(p, tctx, &r);
1346 if (!NT_STATUS_IS_OK(status)) {
1347 torture_warning(tctx, "SetAliasInfo level %u failed - %s\n",
1348 levels[i], nt_errstr(status));
1352 q.in.alias_handle = handle;
1353 q.in.level = levels[i];
1356 status = dcerpc_samr_QueryAliasInfo(p, tctx, &q);
1357 if (!NT_STATUS_IS_OK(status)) {
1358 torture_warning(tctx, "QueryAliasInfo level %u failed - %s\n",
1359 levels[i], nt_errstr(status));
1367 static bool test_GetGroupsForUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1368 struct policy_handle *user_handle)
1370 struct samr_GetGroupsForUser r;
1371 struct samr_RidWithAttributeArray *rids = NULL;
1374 torture_comment(tctx, "testing GetGroupsForUser\n");
1376 r.in.user_handle = user_handle;
1379 status = dcerpc_samr_GetGroupsForUser(p, tctx, &r);
1380 torture_assert_ntstatus_ok(tctx, status, "GetGroupsForUser");
1386 static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1387 struct lsa_String *domain_name)
1390 struct samr_GetDomPwInfo r;
1391 struct samr_PwInfo info;
1393 r.in.domain_name = domain_name;
1396 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1398 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1399 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1401 r.in.domain_name->string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
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 = "\\\\__NONAME__";
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 = "\\\\Builtin";
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");
1422 static bool test_GetUserPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1423 struct policy_handle *handle)
1426 struct samr_GetUserPwInfo r;
1427 struct samr_PwInfo info;
1429 torture_comment(tctx, "Testing GetUserPwInfo\n");
1431 r.in.user_handle = handle;
1434 status = dcerpc_samr_GetUserPwInfo(p, tctx, &r);
1435 torture_assert_ntstatus_ok(tctx, status, "GetUserPwInfo");
1440 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, struct torture_context *tctx,
1441 struct policy_handle *domain_handle, const char *name,
1445 struct samr_LookupNames n;
1446 struct lsa_String sname[2];
1447 struct samr_Ids rids, types;
1449 init_lsa_String(&sname[0], name);
1451 n.in.domain_handle = domain_handle;
1455 n.out.types = &types;
1456 status = dcerpc_samr_LookupNames(p, tctx, &n);
1457 if (NT_STATUS_IS_OK(status)) {
1458 *rid = n.out.rids->ids[0];
1463 init_lsa_String(&sname[1], "xxNONAMExx");
1465 status = dcerpc_samr_LookupNames(p, tctx, &n);
1466 if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
1467 torture_warning(tctx, "LookupNames[2] failed - %s\n", nt_errstr(status));
1468 if (NT_STATUS_IS_OK(status)) {
1469 return NT_STATUS_UNSUCCESSFUL;
1475 status = dcerpc_samr_LookupNames(p, tctx, &n);
1476 if (!NT_STATUS_IS_OK(status)) {
1477 torture_warning(tctx, "LookupNames[0] failed - %s\n", nt_errstr(status));
1481 init_lsa_String(&sname[0], "xxNONAMExx");
1483 status = dcerpc_samr_LookupNames(p, tctx, &n);
1484 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1485 torture_warning(tctx, "LookupNames[1 bad name] failed - %s\n", nt_errstr(status));
1486 if (NT_STATUS_IS_OK(status)) {
1487 return NT_STATUS_UNSUCCESSFUL;
1492 init_lsa_String(&sname[0], "xxNONAMExx");
1493 init_lsa_String(&sname[1], "xxNONAME2xx");
1495 status = dcerpc_samr_LookupNames(p, tctx, &n);
1496 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1497 torture_warning(tctx, "LookupNames[2 bad names] failed - %s\n", nt_errstr(status));
1498 if (NT_STATUS_IS_OK(status)) {
1499 return NT_STATUS_UNSUCCESSFUL;
1504 return NT_STATUS_OK;
1507 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p,
1508 struct torture_context *tctx,
1509 struct policy_handle *domain_handle,
1510 const char *name, struct policy_handle *user_handle)
1513 struct samr_OpenUser r;
1516 status = test_LookupName(p, tctx, domain_handle, name, &rid);
1517 if (!NT_STATUS_IS_OK(status)) {
1521 r.in.domain_handle = domain_handle;
1522 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1524 r.out.user_handle = user_handle;
1525 status = dcerpc_samr_OpenUser(p, tctx, &r);
1526 if (!NT_STATUS_IS_OK(status)) {
1527 torture_warning(tctx, "OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(status));
1534 static bool test_ChangePasswordNT3(struct dcerpc_pipe *p,
1535 struct torture_context *tctx,
1536 struct policy_handle *handle)
1539 struct samr_ChangePasswordUser r;
1541 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1542 struct policy_handle user_handle;
1543 char *oldpass = "test";
1544 char *newpass = "test2";
1545 uint8_t old_nt_hash[16], new_nt_hash[16];
1546 uint8_t old_lm_hash[16], new_lm_hash[16];
1548 status = test_OpenUser_byname(p, tctx, handle, "testuser", &user_handle);
1549 if (!NT_STATUS_IS_OK(status)) {
1553 torture_comment(tctx, "Testing ChangePasswordUser for user 'testuser'\n");
1555 torture_comment(tctx, "old password: %s\n", oldpass);
1556 torture_comment(tctx, "new password: %s\n", newpass);
1558 E_md4hash(oldpass, old_nt_hash);
1559 E_md4hash(newpass, new_nt_hash);
1560 E_deshash(oldpass, old_lm_hash);
1561 E_deshash(newpass, new_lm_hash);
1563 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1564 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1565 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1566 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1567 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1568 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1570 r.in.handle = &user_handle;
1571 r.in.lm_present = 1;
1572 r.in.old_lm_crypted = &hash1;
1573 r.in.new_lm_crypted = &hash2;
1574 r.in.nt_present = 1;
1575 r.in.old_nt_crypted = &hash3;
1576 r.in.new_nt_crypted = &hash4;
1577 r.in.cross1_present = 1;
1578 r.in.nt_cross = &hash5;
1579 r.in.cross2_present = 1;
1580 r.in.lm_cross = &hash6;
1582 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1583 if (!NT_STATUS_IS_OK(status)) {
1584 torture_warning(tctx, "ChangePasswordUser failed - %s\n", nt_errstr(status));
1588 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
1596 static bool test_ChangePasswordUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1597 const char *acct_name,
1598 struct policy_handle *handle, char **password)
1601 struct samr_ChangePasswordUser r;
1603 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1604 struct policy_handle user_handle;
1606 uint8_t old_nt_hash[16], new_nt_hash[16];
1607 uint8_t old_lm_hash[16], new_lm_hash[16];
1608 bool changed = true;
1611 struct samr_GetUserPwInfo pwp;
1612 struct samr_PwInfo info;
1613 int policy_min_pw_len = 0;
1615 status = test_OpenUser_byname(p, tctx, handle, acct_name, &user_handle);
1616 if (!NT_STATUS_IS_OK(status)) {
1619 pwp.in.user_handle = &user_handle;
1620 pwp.out.info = &info;
1622 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1623 if (NT_STATUS_IS_OK(status)) {
1624 policy_min_pw_len = pwp.out.info->min_password_length;
1626 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1628 torture_comment(tctx, "Testing ChangePasswordUser\n");
1630 torture_assert(tctx, *password != NULL,
1631 "Failing ChangePasswordUser as old password was NULL. Previous test failed?");
1633 oldpass = *password;
1635 E_md4hash(oldpass, old_nt_hash);
1636 E_md4hash(newpass, new_nt_hash);
1637 E_deshash(oldpass, old_lm_hash);
1638 E_deshash(newpass, new_lm_hash);
1640 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1641 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1642 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1643 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1644 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1645 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1647 r.in.user_handle = &user_handle;
1648 r.in.lm_present = 1;
1649 /* Break the LM hash */
1651 r.in.old_lm_crypted = &hash1;
1652 r.in.new_lm_crypted = &hash2;
1653 r.in.nt_present = 1;
1654 r.in.old_nt_crypted = &hash3;
1655 r.in.new_nt_crypted = &hash4;
1656 r.in.cross1_present = 1;
1657 r.in.nt_cross = &hash5;
1658 r.in.cross2_present = 1;
1659 r.in.lm_cross = &hash6;
1661 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1662 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1663 "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash");
1665 /* Unbreak the LM hash */
1668 r.in.user_handle = &user_handle;
1669 r.in.lm_present = 1;
1670 r.in.old_lm_crypted = &hash1;
1671 r.in.new_lm_crypted = &hash2;
1672 /* Break the NT hash */
1674 r.in.nt_present = 1;
1675 r.in.old_nt_crypted = &hash3;
1676 r.in.new_nt_crypted = &hash4;
1677 r.in.cross1_present = 1;
1678 r.in.nt_cross = &hash5;
1679 r.in.cross2_present = 1;
1680 r.in.lm_cross = &hash6;
1682 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1683 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1684 "expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash");
1686 /* Unbreak the NT hash */
1689 r.in.user_handle = &user_handle;
1690 r.in.lm_present = 1;
1691 r.in.old_lm_crypted = &hash1;
1692 r.in.new_lm_crypted = &hash2;
1693 r.in.nt_present = 1;
1694 r.in.old_nt_crypted = &hash3;
1695 r.in.new_nt_crypted = &hash4;
1696 r.in.cross1_present = 1;
1697 r.in.nt_cross = &hash5;
1698 r.in.cross2_present = 1;
1699 /* Break the LM cross */
1701 r.in.lm_cross = &hash6;
1703 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1704 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1705 torture_warning(tctx, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status));
1709 /* Unbreak the LM cross */
1712 r.in.user_handle = &user_handle;
1713 r.in.lm_present = 1;
1714 r.in.old_lm_crypted = &hash1;
1715 r.in.new_lm_crypted = &hash2;
1716 r.in.nt_present = 1;
1717 r.in.old_nt_crypted = &hash3;
1718 r.in.new_nt_crypted = &hash4;
1719 r.in.cross1_present = 1;
1720 /* Break the NT cross */
1722 r.in.nt_cross = &hash5;
1723 r.in.cross2_present = 1;
1724 r.in.lm_cross = &hash6;
1726 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1727 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1728 torture_warning(tctx, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status));
1732 /* Unbreak the NT cross */
1736 /* Reset the hashes to not broken values */
1737 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1738 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1739 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1740 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1741 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1742 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1744 r.in.user_handle = &user_handle;
1745 r.in.lm_present = 1;
1746 r.in.old_lm_crypted = &hash1;
1747 r.in.new_lm_crypted = &hash2;
1748 r.in.nt_present = 1;
1749 r.in.old_nt_crypted = &hash3;
1750 r.in.new_nt_crypted = &hash4;
1751 r.in.cross1_present = 1;
1752 r.in.nt_cross = &hash5;
1753 r.in.cross2_present = 0;
1754 r.in.lm_cross = NULL;
1756 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1757 if (NT_STATUS_IS_OK(status)) {
1759 *password = newpass;
1760 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1761 torture_warning(tctx, "ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(status));
1766 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1768 E_md4hash(oldpass, old_nt_hash);
1769 E_md4hash(newpass, new_nt_hash);
1770 E_deshash(oldpass, old_lm_hash);
1771 E_deshash(newpass, new_lm_hash);
1774 /* Reset the hashes to not broken values */
1775 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1776 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1777 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1778 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1779 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1780 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1782 r.in.user_handle = &user_handle;
1783 r.in.lm_present = 1;
1784 r.in.old_lm_crypted = &hash1;
1785 r.in.new_lm_crypted = &hash2;
1786 r.in.nt_present = 1;
1787 r.in.old_nt_crypted = &hash3;
1788 r.in.new_nt_crypted = &hash4;
1789 r.in.cross1_present = 0;
1790 r.in.nt_cross = NULL;
1791 r.in.cross2_present = 1;
1792 r.in.lm_cross = &hash6;
1794 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1795 if (NT_STATUS_IS_OK(status)) {
1797 *password = newpass;
1798 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1799 torture_warning(tctx, "ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status));
1804 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1806 E_md4hash(oldpass, old_nt_hash);
1807 E_md4hash(newpass, new_nt_hash);
1808 E_deshash(oldpass, old_lm_hash);
1809 E_deshash(newpass, new_lm_hash);
1812 /* Reset the hashes to not broken values */
1813 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1814 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1815 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1816 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1817 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1818 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1820 r.in.user_handle = &user_handle;
1821 r.in.lm_present = 1;
1822 r.in.old_lm_crypted = &hash1;
1823 r.in.new_lm_crypted = &hash2;
1824 r.in.nt_present = 1;
1825 r.in.old_nt_crypted = &hash3;
1826 r.in.new_nt_crypted = &hash4;
1827 r.in.cross1_present = 1;
1828 r.in.nt_cross = &hash5;
1829 r.in.cross2_present = 1;
1830 r.in.lm_cross = &hash6;
1832 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1833 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1834 torture_comment(tctx, "ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1835 } else if (!NT_STATUS_IS_OK(status)) {
1836 torture_warning(tctx, "ChangePasswordUser failed - %s\n", nt_errstr(status));
1840 *password = newpass;
1843 r.in.user_handle = &user_handle;
1844 r.in.lm_present = 1;
1845 r.in.old_lm_crypted = &hash1;
1846 r.in.new_lm_crypted = &hash2;
1847 r.in.nt_present = 1;
1848 r.in.old_nt_crypted = &hash3;
1849 r.in.new_nt_crypted = &hash4;
1850 r.in.cross1_present = 1;
1851 r.in.nt_cross = &hash5;
1852 r.in.cross2_present = 1;
1853 r.in.lm_cross = &hash6;
1856 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1857 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1858 torture_comment(tctx, "ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1859 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1860 torture_warning(tctx, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status));
1866 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
1874 static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
1875 const char *acct_name,
1876 struct policy_handle *handle, char **password)
1879 struct samr_OemChangePasswordUser2 r;
1881 struct samr_Password lm_verifier;
1882 struct samr_CryptPassword lm_pass;
1883 struct lsa_AsciiString server, account, account_bad;
1886 uint8_t old_lm_hash[16], new_lm_hash[16];
1888 struct samr_GetDomPwInfo dom_pw_info;
1889 struct samr_PwInfo info;
1890 int policy_min_pw_len = 0;
1892 struct lsa_String domain_name;
1894 domain_name.string = "";
1895 dom_pw_info.in.domain_name = &domain_name;
1896 dom_pw_info.out.info = &info;
1898 torture_comment(tctx, "Testing OemChangePasswordUser2\n");
1900 torture_assert(tctx, *password != NULL,
1901 "Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?");
1903 oldpass = *password;
1905 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
1906 if (NT_STATUS_IS_OK(status)) {
1907 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
1910 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1912 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1913 account.string = acct_name;
1915 E_deshash(oldpass, old_lm_hash);
1916 E_deshash(newpass, new_lm_hash);
1918 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1919 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1920 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1922 r.in.server = &server;
1923 r.in.account = &account;
1924 r.in.password = &lm_pass;
1925 r.in.hash = &lm_verifier;
1927 /* Break the verification */
1928 lm_verifier.hash[0]++;
1930 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1932 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1933 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1934 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1939 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1940 /* Break the old password */
1942 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1943 /* unbreak it for the next operation */
1945 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1947 r.in.server = &server;
1948 r.in.account = &account;
1949 r.in.password = &lm_pass;
1950 r.in.hash = &lm_verifier;
1952 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1954 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1955 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1956 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1961 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1962 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1964 r.in.server = &server;
1965 r.in.account = &account;
1966 r.in.password = &lm_pass;
1969 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1971 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1972 && !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1973 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
1978 /* This shouldn't be a valid name */
1979 account_bad.string = TEST_ACCOUNT_NAME "XX";
1980 r.in.account = &account_bad;
1982 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1984 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1985 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
1990 /* This shouldn't be a valid name */
1991 account_bad.string = TEST_ACCOUNT_NAME "XX";
1992 r.in.account = &account_bad;
1993 r.in.password = &lm_pass;
1994 r.in.hash = &lm_verifier;
1996 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1998 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1999 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
2004 /* This shouldn't be a valid name */
2005 account_bad.string = TEST_ACCOUNT_NAME "XX";
2006 r.in.account = &account_bad;
2007 r.in.password = NULL;
2008 r.in.hash = &lm_verifier;
2010 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
2012 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
2013 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
2018 E_deshash(oldpass, old_lm_hash);
2019 E_deshash(newpass, new_lm_hash);
2021 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
2022 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2023 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
2025 r.in.server = &server;
2026 r.in.account = &account;
2027 r.in.password = &lm_pass;
2028 r.in.hash = &lm_verifier;
2030 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
2031 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2032 torture_comment(tctx, "OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
2033 } else if (!NT_STATUS_IS_OK(status)) {
2034 torture_warning(tctx, "OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
2037 *password = newpass;
2044 static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
2045 const char *acct_name,
2047 char *newpass, bool allow_password_restriction)
2050 struct samr_ChangePasswordUser2 r;
2052 struct lsa_String server, account;
2053 struct samr_CryptPassword nt_pass, lm_pass;
2054 struct samr_Password nt_verifier, lm_verifier;
2056 uint8_t old_nt_hash[16], new_nt_hash[16];
2057 uint8_t old_lm_hash[16], new_lm_hash[16];
2059 struct samr_GetDomPwInfo dom_pw_info;
2060 struct samr_PwInfo info;
2062 struct lsa_String domain_name;
2064 domain_name.string = "";
2065 dom_pw_info.in.domain_name = &domain_name;
2066 dom_pw_info.out.info = &info;
2068 torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name);
2070 torture_assert(tctx, *password != NULL,
2071 "Failing ChangePasswordUser2 as old password was NULL. Previous test failed?");
2072 oldpass = *password;
2075 int policy_min_pw_len = 0;
2076 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
2077 if (NT_STATUS_IS_OK(status)) {
2078 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
2081 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2084 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2085 init_lsa_String(&account, acct_name);
2087 E_md4hash(oldpass, old_nt_hash);
2088 E_md4hash(newpass, new_nt_hash);
2090 E_deshash(oldpass, old_lm_hash);
2091 E_deshash(newpass, new_lm_hash);
2093 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
2094 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2095 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2097 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2098 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2099 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2101 r.in.server = &server;
2102 r.in.account = &account;
2103 r.in.nt_password = &nt_pass;
2104 r.in.nt_verifier = &nt_verifier;
2106 r.in.lm_password = &lm_pass;
2107 r.in.lm_verifier = &lm_verifier;
2109 status = dcerpc_samr_ChangePasswordUser2(p, tctx, &r);
2110 if (allow_password_restriction && NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2111 torture_comment(tctx, "ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
2112 } else if (!NT_STATUS_IS_OK(status)) {
2113 torture_warning(tctx, "ChangePasswordUser2 failed - %s\n", nt_errstr(status));
2116 *password = newpass;
2123 bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tctx,
2124 const char *account_string,
2125 int policy_min_pw_len,
2127 const char *newpass,
2128 NTTIME last_password_change,
2129 bool handle_reject_reason)
2132 struct samr_ChangePasswordUser3 r;
2134 struct lsa_String server, account, account_bad;
2135 struct samr_CryptPassword nt_pass, lm_pass;
2136 struct samr_Password nt_verifier, lm_verifier;
2138 uint8_t old_nt_hash[16], new_nt_hash[16];
2139 uint8_t old_lm_hash[16], new_lm_hash[16];
2141 struct samr_DomInfo1 *dominfo = NULL;
2142 struct userPwdChangeFailureInformation *reject = NULL;
2144 torture_comment(tctx, "Testing ChangePasswordUser3\n");
2146 if (newpass == NULL) {
2148 if (policy_min_pw_len == 0) {
2149 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2151 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len);
2153 } while (check_password_quality(newpass) == false);
2155 torture_comment(tctx, "Using password '%s'\n", newpass);
2158 torture_assert(tctx, *password != NULL,
2159 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2161 oldpass = *password;
2162 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2163 init_lsa_String(&account, account_string);
2165 E_md4hash(oldpass, old_nt_hash);
2166 E_md4hash(newpass, new_nt_hash);
2168 E_deshash(oldpass, old_lm_hash);
2169 E_deshash(newpass, new_lm_hash);
2171 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2172 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2173 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2175 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2176 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2177 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2179 /* Break the verification */
2180 nt_verifier.hash[0]++;
2182 r.in.server = &server;
2183 r.in.account = &account;
2184 r.in.nt_password = &nt_pass;
2185 r.in.nt_verifier = &nt_verifier;
2187 r.in.lm_password = &lm_pass;
2188 r.in.lm_verifier = &lm_verifier;
2189 r.in.password3 = NULL;
2190 r.out.dominfo = &dominfo;
2191 r.out.reject = &reject;
2193 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2194 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
2195 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
2196 torture_warning(tctx, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
2201 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2202 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2203 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2205 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2206 /* Break the NT hash */
2208 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2209 /* Unbreak it again */
2211 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2213 r.in.server = &server;
2214 r.in.account = &account;
2215 r.in.nt_password = &nt_pass;
2216 r.in.nt_verifier = &nt_verifier;
2218 r.in.lm_password = &lm_pass;
2219 r.in.lm_verifier = &lm_verifier;
2220 r.in.password3 = NULL;
2221 r.out.dominfo = &dominfo;
2222 r.out.reject = &reject;
2224 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2225 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
2226 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
2227 torture_warning(tctx, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
2232 /* This shouldn't be a valid name */
2233 init_lsa_String(&account_bad, talloc_asprintf(tctx, "%sXX", account_string));
2235 r.in.account = &account_bad;
2236 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2237 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
2238 torture_warning(tctx, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
2243 E_md4hash(oldpass, old_nt_hash);
2244 E_md4hash(newpass, new_nt_hash);
2246 E_deshash(oldpass, old_lm_hash);
2247 E_deshash(newpass, new_lm_hash);
2249 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2250 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2251 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2253 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2254 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2255 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2257 r.in.server = &server;
2258 r.in.account = &account;
2259 r.in.nt_password = &nt_pass;
2260 r.in.nt_verifier = &nt_verifier;
2262 r.in.lm_password = &lm_pass;
2263 r.in.lm_verifier = &lm_verifier;
2264 r.in.password3 = NULL;
2265 r.out.dominfo = &dominfo;
2266 r.out.reject = &reject;
2268 unix_to_nt_time(&t, time(NULL));
2270 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2272 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
2275 && handle_reject_reason
2276 && (!null_nttime(last_password_change) || !dominfo->min_password_age)) {
2277 if (dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
2279 if (reject && (reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR)) {
2280 torture_warning(tctx, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2281 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2286 /* We tested the order of precendence which is as follows:
2295 if ((dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
2296 (last_password_change + dominfo->min_password_age > t)) {
2298 if (reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2299 torture_warning(tctx, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2300 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2304 } else if ((dominfo->min_password_length > 0) &&
2305 (strlen(newpass) < dominfo->min_password_length)) {
2307 if (reject->extendedFailureReason != SAM_PWD_CHANGE_PASSWORD_TOO_SHORT) {
2308 torture_warning(tctx, "expected SAM_PWD_CHANGE_PASSWORD_TOO_SHORT (%d), got %d\n",
2309 SAM_PWD_CHANGE_PASSWORD_TOO_SHORT, reject->extendedFailureReason);
2313 } else if ((dominfo->password_history_length > 0) &&
2314 strequal(oldpass, newpass)) {
2316 if (reject->extendedFailureReason != SAM_PWD_CHANGE_PWD_IN_HISTORY) {
2317 torture_warning(tctx, "expected SAM_PWD_CHANGE_PWD_IN_HISTORY (%d), got %d\n",
2318 SAM_PWD_CHANGE_PWD_IN_HISTORY, reject->extendedFailureReason);
2321 } else if (dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
2323 if (reject->extendedFailureReason != SAM_PWD_CHANGE_NOT_COMPLEX) {
2324 torture_warning(tctx, "expected SAM_PWD_CHANGE_NOT_COMPLEX (%d), got %d\n",
2325 SAM_PWD_CHANGE_NOT_COMPLEX, reject->extendedFailureReason);
2331 if (reject->extendedFailureReason == SAM_PWD_CHANGE_PASSWORD_TOO_SHORT) {
2332 /* retry with adjusted size */
2333 return test_ChangePasswordUser3(p, tctx, account_string,
2334 dominfo->min_password_length,
2335 password, NULL, 0, false);
2339 } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2340 if (reject && reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2341 torture_warning(tctx, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2342 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2345 /* Perhaps the server has a 'min password age' set? */
2348 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3");
2349 *password = talloc_strdup(tctx, newpass);
2355 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_context *tctx,
2356 const char *account_string,
2357 struct policy_handle *handle,
2361 struct samr_ChangePasswordUser3 r;
2362 struct samr_SetUserInfo s;
2363 union samr_UserInfo u;
2364 DATA_BLOB session_key;
2365 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
2366 uint8_t confounder[16];
2367 struct MD5Context ctx;
2370 struct lsa_String server, account;
2371 struct samr_CryptPassword nt_pass;
2372 struct samr_Password nt_verifier;
2373 DATA_BLOB new_random_pass;
2376 uint8_t old_nt_hash[16], new_nt_hash[16];
2378 struct samr_DomInfo1 *dominfo = NULL;
2379 struct userPwdChangeFailureInformation *reject = NULL;
2381 new_random_pass = samr_very_rand_pass(tctx, 128);
2383 torture_assert(tctx, *password != NULL,
2384 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2386 oldpass = *password;
2387 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2388 init_lsa_String(&account, account_string);
2390 s.in.user_handle = handle;
2396 u.info25.info.fields_present = SAMR_FIELD_NT_PASSWORD_PRESENT;
2398 set_pw_in_buffer(u.info25.password.data, &new_random_pass);
2400 status = dcerpc_fetch_session_key(p, &session_key);
2401 if (!NT_STATUS_IS_OK(status)) {
2402 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
2403 s.in.level, nt_errstr(status));
2407 generate_random_buffer((uint8_t *)confounder, 16);
2410 MD5Update(&ctx, confounder, 16);
2411 MD5Update(&ctx, session_key.data, session_key.length);
2412 MD5Final(confounded_session_key.data, &ctx);
2414 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
2415 memcpy(&u.info25.password.data[516], confounder, 16);
2417 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
2419 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
2420 if (!NT_STATUS_IS_OK(status)) {
2421 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
2422 s.in.level, nt_errstr(status));
2426 torture_comment(tctx, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
2428 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2430 new_random_pass = samr_very_rand_pass(tctx, 128);
2432 mdfour(new_nt_hash, new_random_pass.data, new_random_pass.length);
2434 set_pw_in_buffer(nt_pass.data, &new_random_pass);
2435 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2436 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2438 r.in.server = &server;
2439 r.in.account = &account;
2440 r.in.nt_password = &nt_pass;
2441 r.in.nt_verifier = &nt_verifier;
2443 r.in.lm_password = NULL;
2444 r.in.lm_verifier = NULL;
2445 r.in.password3 = NULL;
2446 r.out.dominfo = &dominfo;
2447 r.out.reject = &reject;
2449 unix_to_nt_time(&t, time(NULL));
2451 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2453 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2454 if (reject && reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2455 torture_warning(tctx, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2456 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2459 /* Perhaps the server has a 'min password age' set? */
2461 } else if (!NT_STATUS_IS_OK(status)) {
2462 torture_warning(tctx, "ChangePasswordUser3 failed - %s\n", nt_errstr(status));
2466 newpass = samr_rand_pass(tctx, 128);
2468 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2470 E_md4hash(newpass, new_nt_hash);
2472 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2473 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2474 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2476 r.in.server = &server;
2477 r.in.account = &account;
2478 r.in.nt_password = &nt_pass;
2479 r.in.nt_verifier = &nt_verifier;
2481 r.in.lm_password = NULL;
2482 r.in.lm_verifier = NULL;
2483 r.in.password3 = NULL;
2484 r.out.dominfo = &dominfo;
2485 r.out.reject = &reject;
2487 unix_to_nt_time(&t, time(NULL));
2489 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2491 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2492 if (reject && reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2493 torture_warning(tctx, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2494 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2497 /* Perhaps the server has a 'min password age' set? */
2500 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3 (on second random password)");
2501 *password = talloc_strdup(tctx, newpass);
2508 static bool test_GetMembersInAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2509 struct policy_handle *alias_handle)
2511 struct samr_GetMembersInAlias r;
2512 struct lsa_SidArray sids;
2515 torture_comment(tctx, "Testing GetMembersInAlias\n");
2517 r.in.alias_handle = alias_handle;
2520 status = dcerpc_samr_GetMembersInAlias(p, tctx, &r);
2521 torture_assert_ntstatus_ok(tctx, status, "GetMembersInAlias");
2526 static bool test_AddMemberToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2527 struct policy_handle *alias_handle,
2528 const struct dom_sid *domain_sid)
2530 struct samr_AddAliasMember r;
2531 struct samr_DeleteAliasMember d;
2533 struct dom_sid *sid;
2535 sid = dom_sid_add_rid(tctx, domain_sid, 512);
2537 torture_comment(tctx, "testing AddAliasMember\n");
2538 r.in.alias_handle = alias_handle;
2541 status = dcerpc_samr_AddAliasMember(p, tctx, &r);
2542 torture_assert_ntstatus_ok(tctx, status, "AddAliasMember");
2544 d.in.alias_handle = alias_handle;
2547 status = dcerpc_samr_DeleteAliasMember(p, tctx, &d);
2548 torture_assert_ntstatus_ok(tctx, status, "DelAliasMember");
2553 static bool test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2554 struct policy_handle *alias_handle)
2556 struct samr_AddMultipleMembersToAlias a;
2557 struct samr_RemoveMultipleMembersFromAlias r;
2559 struct lsa_SidArray sids;
2561 torture_comment(tctx, "testing AddMultipleMembersToAlias\n");
2562 a.in.alias_handle = alias_handle;
2566 sids.sids = talloc_array(tctx, struct lsa_SidPtr, 3);
2568 sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2569 sids.sids[1].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-2");
2570 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-3");
2572 status = dcerpc_samr_AddMultipleMembersToAlias(p, tctx, &a);
2573 torture_assert_ntstatus_ok(tctx, status, "AddMultipleMembersToAlias");
2576 torture_comment(tctx, "testing RemoveMultipleMembersFromAlias\n");
2577 r.in.alias_handle = alias_handle;
2580 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2581 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2583 /* strange! removing twice doesn't give any error */
2584 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2585 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2587 /* but removing an alias that isn't there does */
2588 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-4");
2590 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2591 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, "RemoveMultipleMembersFromAlias");
2596 static bool test_GetAliasMembership(struct dcerpc_pipe *p,
2597 struct torture_context *tctx,
2598 struct policy_handle *domain_handle)
2600 struct samr_GetAliasMembership r;
2601 struct lsa_SidArray sids;
2602 struct samr_Ids rids;
2605 torture_comment(tctx, "Testing GetAliasMembership\n");
2607 if (torture_setting_bool(tctx, "samba4", false)) {
2608 torture_skip(tctx, "skipping GetAliasMembership against s4");
2611 r.in.domain_handle = domain_handle;
2616 sids.sids = talloc_zero_array(tctx, struct lsa_SidPtr, sids.num_sids);
2618 status = dcerpc_samr_GetAliasMembership(p, tctx, &r);
2619 torture_assert_ntstatus_ok(tctx, status,
2620 "samr_GetAliasMembership failed");
2622 torture_assert_int_equal(tctx, sids.num_sids, rids.count,
2623 "protocol misbehaviour");
2626 sids.sids = talloc_zero_array(tctx, struct lsa_SidPtr, sids.num_sids);
2627 sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2629 status = dcerpc_samr_GetAliasMembership(p, tctx, &r);
2630 torture_assert_ntstatus_ok(tctx, status,
2631 "samr_GetAliasMembership failed");
2634 /* only true for w2k8 it seems
2635 * win7, xp, w2k3 will return a 0 length array pointer */
2637 torture_assert(tctx, (rids.ids && !rids.count),
2638 "samr_GetAliasMembership protocol misbehaviour");
2640 torture_assert(tctx, (!rids.ids && rids.count),
2641 "samr_GetAliasMembership protocol misbehaviour");
2646 static bool test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2647 struct policy_handle *user_handle)
2649 struct samr_TestPrivateFunctionsUser r;
2652 torture_comment(tctx, "Testing TestPrivateFunctionsUser\n");
2654 r.in.user_handle = user_handle;
2656 status = dcerpc_samr_TestPrivateFunctionsUser(p, tctx, &r);
2657 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsUser");
2662 static bool test_QueryUserInfo_pwdlastset(struct dcerpc_pipe *p,
2663 struct torture_context *tctx,
2664 struct policy_handle *handle,
2669 uint16_t levels[] = { /* 3, */ 5, 21 };
2671 NTTIME pwdlastset3 = 0;
2672 NTTIME pwdlastset5 = 0;
2673 NTTIME pwdlastset21 = 0;
2675 torture_comment(tctx, "Testing QueryUserInfo%s level 5 and 21 call ",
2676 use_info2 ? "2":"");
2678 for (i=0; i<ARRAY_SIZE(levels); i++) {
2680 struct samr_QueryUserInfo r;
2681 struct samr_QueryUserInfo2 r2;
2682 union samr_UserInfo *info;
2685 r2.in.user_handle = handle;
2686 r2.in.level = levels[i];
2687 r2.out.info = &info;
2688 status = dcerpc_samr_QueryUserInfo2(p, tctx, &r2);
2691 r.in.user_handle = handle;
2692 r.in.level = levels[i];
2694 status = dcerpc_samr_QueryUserInfo(p, tctx, &r);
2697 if (!NT_STATUS_IS_OK(status) &&
2698 !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
2699 torture_warning(tctx, "QueryUserInfo%s level %u failed - %s\n",
2700 use_info2 ? "2":"", levels[i], nt_errstr(status));
2704 switch (levels[i]) {
2706 pwdlastset3 = info->info3.last_password_change;
2709 pwdlastset5 = info->info5.last_password_change;
2712 pwdlastset21 = info->info21.last_password_change;
2718 /* torture_assert_int_equal(tctx, pwdlastset3, pwdlastset5,
2719 "pwdlastset mixup"); */
2720 torture_assert_int_equal(tctx, pwdlastset5, pwdlastset21,
2721 "pwdlastset mixup");
2723 *pwdlastset = pwdlastset21;
2725 torture_comment(tctx, "(pwdlastset: %lld)\n", *pwdlastset);
2730 static bool test_SamLogon(struct torture_context *tctx,
2731 struct dcerpc_pipe *p,
2732 struct cli_credentials *test_credentials,
2733 NTSTATUS expected_result)
2736 struct netr_LogonSamLogonEx r;
2737 union netr_LogonLevel logon;
2738 union netr_Validation validation;
2739 uint8_t authoritative;
2740 struct netr_NetworkInfo ninfo;
2741 DATA_BLOB names_blob, chal, lm_resp, nt_resp;
2742 int flags = CLI_CRED_NTLM_AUTH;
2743 uint32_t samlogon_flags = 0;
2745 if (lp_client_lanman_auth(tctx->lp_ctx)) {
2746 flags |= CLI_CRED_LANMAN_AUTH;
2749 if (lp_client_ntlmv2_auth(tctx->lp_ctx)) {
2750 flags |= CLI_CRED_NTLMv2_AUTH;
2753 cli_credentials_get_ntlm_username_domain(test_credentials, tctx,
2754 &ninfo.identity_info.account_name.string,
2755 &ninfo.identity_info.domain_name.string);
2757 generate_random_buffer(ninfo.challenge,
2758 sizeof(ninfo.challenge));
2759 chal = data_blob_const(ninfo.challenge,
2760 sizeof(ninfo.challenge));
2762 names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(test_credentials),
2763 cli_credentials_get_domain(test_credentials));
2765 status = cli_credentials_get_ntlm_response(test_credentials, tctx,
2771 torture_assert_ntstatus_ok(tctx, status, "cli_credentials_get_ntlm_response failed");
2773 ninfo.lm.data = lm_resp.data;
2774 ninfo.lm.length = lm_resp.length;
2776 ninfo.nt.data = nt_resp.data;
2777 ninfo.nt.length = nt_resp.length;
2779 ninfo.identity_info.parameter_control =
2780 MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT |
2781 MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;
2782 ninfo.identity_info.logon_id_low = 0;
2783 ninfo.identity_info.logon_id_high = 0;
2784 ninfo.identity_info.workstation.string = cli_credentials_get_workstation(test_credentials);
2786 logon.network = &ninfo;
2788 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2789 r.in.computer_name = cli_credentials_get_workstation(test_credentials);
2790 r.in.logon_level = NetlogonNetworkInformation;
2791 r.in.logon = &logon;
2792 r.in.flags = &samlogon_flags;
2793 r.out.flags = &samlogon_flags;
2794 r.out.validation = &validation;
2795 r.out.authoritative = &authoritative;
2797 torture_comment(tctx, "Testing LogonSamLogon with name %s\n", ninfo.identity_info.account_name.string);
2799 r.in.validation_level = 6;
2801 status = dcerpc_netr_LogonSamLogonEx(p, tctx, &r);
2802 if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
2803 r.in.validation_level = 3;
2804 status = dcerpc_netr_LogonSamLogonEx(p, tctx, &r);
2806 if (!NT_STATUS_IS_OK(status)) {
2807 torture_assert_ntstatus_equal(tctx, status, expected_result, "LogonSamLogonEx failed");
2810 torture_assert_ntstatus_ok(tctx, status, "LogonSamLogonEx failed");
2816 static bool test_SamLogon_with_creds(struct torture_context *tctx,
2817 struct dcerpc_pipe *p,
2818 struct cli_credentials *machine_creds,
2819 const char *acct_name,
2821 NTSTATUS expected_samlogon_result)
2824 struct cli_credentials *test_credentials;
2826 test_credentials = cli_credentials_init(tctx);
2828 cli_credentials_set_workstation(test_credentials,
2829 cli_credentials_get_workstation(machine_creds), CRED_SPECIFIED);
2830 cli_credentials_set_domain(test_credentials,
2831 cli_credentials_get_domain(machine_creds), CRED_SPECIFIED);
2832 cli_credentials_set_username(test_credentials,
2833 acct_name, CRED_SPECIFIED);
2834 cli_credentials_set_password(test_credentials,
2835 password, CRED_SPECIFIED);
2837 torture_comment(tctx, "testing samlogon as %s password: %s\n",
2838 acct_name, password);
2840 if (!test_SamLogon(tctx, p, test_credentials,
2841 expected_samlogon_result)) {
2842 torture_warning(tctx, "new password did not work\n");
2849 static bool test_SetPassword_level(struct dcerpc_pipe *p,
2850 struct dcerpc_pipe *np,
2851 struct torture_context *tctx,
2852 struct policy_handle *handle,
2854 uint32_t fields_present,
2855 uint8_t password_expired,
2856 bool *matched_expected_error,
2858 const char *acct_name,
2860 struct cli_credentials *machine_creds,
2861 bool use_queryinfo2,
2863 NTSTATUS expected_samlogon_result)
2865 const char *fields = NULL;
2872 fields = talloc_asprintf(tctx, "(fields_present: 0x%08x)",
2879 torture_comment(tctx, "Testing SetUserInfo%s level %d call "
2880 "(password_expired: %d) %s\n",
2881 use_setinfo2 ? "2":"", level, password_expired,
2882 fields ? fields : "");
2884 if (!test_SetUserPass_level_ex(p, tctx, handle, level,
2889 matched_expected_error)) {
2893 if (!test_QueryUserInfo_pwdlastset(p, tctx, handle,
2899 if (*matched_expected_error == true) {
2903 if (!test_SamLogon_with_creds(tctx, np,
2907 expected_samlogon_result)) {
2914 static bool test_SetPassword_pwdlastset(struct dcerpc_pipe *p,
2915 struct torture_context *tctx,
2916 uint32_t acct_flags,
2917 const char *acct_name,
2918 struct policy_handle *handle,
2920 struct cli_credentials *machine_credentials)
2922 int s = 0, q = 0, f = 0, l = 0, z = 0;
2923 struct dcerpc_binding *b;
2926 bool set_levels[] = { false, true };
2927 bool query_levels[] = { false, true };
2928 uint32_t levels[] = { 18, 21, 26, 23, 24, 25 }; /* Second half only used when TEST_ALL_LEVELS defined */
2929 uint32_t nonzeros[] = { 1, 24 };
2930 uint32_t fields_present[] = {
2932 SAMR_FIELD_EXPIRED_FLAG,
2933 SAMR_FIELD_LAST_PWD_CHANGE,
2934 SAMR_FIELD_EXPIRED_FLAG | SAMR_FIELD_LAST_PWD_CHANGE,
2936 SAMR_FIELD_NT_PASSWORD_PRESENT,
2937 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
2938 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
2939 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
2940 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
2941 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
2942 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE | SAMR_FIELD_EXPIRED_FLAG
2945 struct dcerpc_pipe *np = NULL;
2947 if (torture_setting_bool(tctx, "samba3", false)) {
2949 torture_comment(tctx, "Samba3 has second granularity, setting delay to: %d\n",
2953 status = torture_rpc_binding(tctx, &b);
2954 if (!NT_STATUS_IS_OK(status)) {
2959 /* We have to use schannel, otherwise the SamLogonEx fails
2960 * with INTERNAL_ERROR */
2962 b->flags &= ~DCERPC_AUTH_OPTIONS;
2963 b->flags |= DCERPC_SCHANNEL | DCERPC_SIGN | DCERPC_SCHANNEL_128;
2965 status = dcerpc_pipe_connect_b(tctx, &np, b,
2966 &ndr_table_netlogon,
2967 machine_credentials, tctx->ev, tctx->lp_ctx);
2969 if (!NT_STATUS_IS_OK(status)) {
2970 torture_warning(tctx, "RPC pipe connect as domain member failed: %s\n", nt_errstr(status));
2975 /* set to 1 to enable testing for all possible opcode
2976 (SetUserInfo, SetUserInfo2, QueryUserInfo, QueryUserInfo2)
2979 #define TEST_ALL_LEVELS 1
2980 #define TEST_SET_LEVELS 1
2981 #define TEST_QUERY_LEVELS 1
2983 #ifdef TEST_ALL_LEVELS
2984 for (l=0; l<ARRAY_SIZE(levels); l++) {
2986 for (l=0; l<(ARRAY_SIZE(levels))/2; l++) {
2988 for (z=0; z<ARRAY_SIZE(nonzeros); z++) {
2989 for (f=0; f<ARRAY_SIZE(fields_present); f++) {
2990 #ifdef TEST_SET_LEVELS
2991 for (s=0; s<ARRAY_SIZE(set_levels); s++) {
2993 #ifdef TEST_QUERY_LEVELS
2994 for (q=0; q<ARRAY_SIZE(query_levels); q++) {
2996 NTTIME pwdlastset_old = 0;
2997 NTTIME pwdlastset_new = 0;
2998 bool matched_expected_error = false;
2999 NTSTATUS expected_samlogon_result = NT_STATUS_ACCOUNT_DISABLED;
3001 torture_comment(tctx, "------------------------------\n"
3002 "Testing pwdLastSet attribute for flags: 0x%08x "
3003 "(s: %d (l: %d), q: %d)\n",
3004 acct_flags, s, levels[l], q);
3006 switch (levels[l]) {
3010 if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3011 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT))) {
3012 expected_samlogon_result = NT_STATUS_WRONG_PASSWORD;
3020 /* set a password and force password change (pwdlastset 0) by
3021 * setting the password expired flag to a non-0 value */
3023 if (!test_SetPassword_level(p, np, tctx, handle,
3027 &matched_expected_error,
3031 machine_credentials,
3034 expected_samlogon_result)) {
3038 if (matched_expected_error == true) {
3039 /* skipping on expected failure */
3043 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3044 * set without the SAMR_FIELD_EXPIRED_FLAG */
3046 switch (levels[l]) {
3050 if ((pwdlastset_new != 0) &&
3051 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
3052 torture_comment(tctx, "not considering a non-0 "
3053 "pwdLastSet as a an error as the "
3054 "SAMR_FIELD_EXPIRED_FLAG has not "
3059 if (pwdlastset_new != 0) {
3060 torture_warning(tctx, "pwdLastSet test failed: "
3061 "expected pwdLastSet 0 but got %lld\n",
3068 switch (levels[l]) {
3072 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3073 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3074 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3075 (pwdlastset_old >= pwdlastset_new)) {
3076 torture_warning(tctx, "pwdlastset not increasing\n");
3081 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3082 (pwdlastset_old >= pwdlastset_new)) {
3083 torture_warning(tctx, "pwdlastset not increasing\n");
3093 /* set a password, pwdlastset needs to get updated (increased
3094 * value), password_expired value used here is 0 */
3096 if (!test_SetPassword_level(p, np, tctx, handle,
3100 &matched_expected_error,
3104 machine_credentials,
3107 expected_samlogon_result)) {
3111 /* when a password has been changed, pwdlastset must not be 0 afterwards
3112 * and must be larger then the old value */
3114 switch (levels[l]) {
3119 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3120 * password has been changed, old and new pwdlastset
3121 * need to be the same value */
3123 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3124 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3125 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3127 torture_assert_int_equal(tctx, pwdlastset_old,
3128 pwdlastset_new, "pwdlastset must be equal");
3132 if (pwdlastset_old >= pwdlastset_new) {
3133 torture_warning(tctx, "pwdLastSet test failed: "
3134 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
3135 pwdlastset_old, pwdlastset_new);
3138 if (pwdlastset_new == 0) {
3139 torture_warning(tctx, "pwdLastSet test failed: "
3140 "expected non-0 pwdlastset, got: %lld\n",
3146 switch (levels[l]) {
3150 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3151 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3152 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3153 (pwdlastset_old >= pwdlastset_new)) {
3154 torture_warning(tctx, "pwdlastset not increasing\n");
3159 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3160 (pwdlastset_old >= pwdlastset_new)) {
3161 torture_warning(tctx, "pwdlastset not increasing\n");
3167 pwdlastset_old = pwdlastset_new;
3173 /* set a password, pwdlastset needs to get updated (increased
3174 * value), password_expired value used here is 0 */
3176 if (!test_SetPassword_level(p, np, tctx, handle,
3180 &matched_expected_error,
3184 machine_credentials,
3187 expected_samlogon_result)) {
3191 /* when a password has been changed, pwdlastset must not be 0 afterwards
3192 * and must be larger then the old value */
3194 switch (levels[l]) {
3199 /* if no password has been changed, old and new pwdlastset
3200 * need to be the same value */
3202 if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3203 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3205 torture_assert_int_equal(tctx, pwdlastset_old,
3206 pwdlastset_new, "pwdlastset must be equal");
3210 if (pwdlastset_old >= pwdlastset_new) {
3211 torture_warning(tctx, "pwdLastSet test failed: "
3212 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
3213 pwdlastset_old, pwdlastset_new);
3216 if (pwdlastset_new == 0) {
3217 torture_warning(tctx, "pwdLastSet test failed: "
3218 "expected non-0 pwdlastset, got: %lld\n",
3226 /* set a password and force password change (pwdlastset 0) by
3227 * setting the password expired flag to a non-0 value */
3229 if (!test_SetPassword_level(p, np, tctx, handle,
3233 &matched_expected_error,
3237 machine_credentials,
3240 expected_samlogon_result)) {
3244 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3245 * set without the SAMR_FIELD_EXPIRED_FLAG */
3247 switch (levels[l]) {
3251 if ((pwdlastset_new != 0) &&
3252 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
3253 torture_comment(tctx, "not considering a non-0 "
3254 "pwdLastSet as a an error as the "
3255 "SAMR_FIELD_EXPIRED_FLAG has not "
3260 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3261 * password has been changed, old and new pwdlastset
3262 * need to be the same value */
3264 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3265 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3266 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3268 torture_assert_int_equal(tctx, pwdlastset_old,
3269 pwdlastset_new, "pwdlastset must be equal");
3274 if (pwdlastset_old == pwdlastset_new) {
3275 torture_warning(tctx, "pwdLastSet test failed: "
3276 "expected last pwdlastset (%lld) != new pwdlastset (%lld)\n",
3277 pwdlastset_old, pwdlastset_new);
3281 if (pwdlastset_new != 0) {
3282 torture_warning(tctx, "pwdLastSet test failed: "
3283 "expected pwdLastSet 0, got %lld\n",
3290 switch (levels[l]) {
3294 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3295 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3296 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3297 (pwdlastset_old >= pwdlastset_new)) {
3298 torture_warning(tctx, "pwdlastset not increasing\n");
3303 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3304 (pwdlastset_old >= pwdlastset_new)) {
3305 torture_warning(tctx, "pwdlastset not increasing\n");
3311 /* if the level we are testing does not have a fields_present
3312 * field, skip all fields present tests by setting f to to
3314 switch (levels[l]) {
3318 f = ARRAY_SIZE(fields_present);
3322 #ifdef TEST_QUERY_LEVELS
3325 #ifdef TEST_SET_LEVELS
3328 } /* fields present */
3332 #undef TEST_SET_LEVELS
3333 #undef TEST_QUERY_LEVELS
3340 static bool test_DeleteUser_with_privs(struct dcerpc_pipe *p,
3341 struct dcerpc_pipe *lp,
3342 struct torture_context *tctx,
3343 struct policy_handle *domain_handle,
3344 struct policy_handle *lsa_handle,
3345 struct policy_handle *user_handle,
3346 const struct dom_sid *domain_sid,
3348 struct cli_credentials *machine_credentials)
3353 struct policy_handle lsa_acct_handle;
3354 struct dom_sid *user_sid;
3356 user_sid = dom_sid_add_rid(tctx, domain_sid, rid);
3359 struct lsa_EnumAccountRights r;
3360 struct lsa_RightSet rights;
3362 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
3364 r.in.handle = lsa_handle;
3365 r.in.sid = user_sid;
3366 r.out.rights = &rights;
3368 status = dcerpc_lsa_EnumAccountRights(lp, tctx, &r);
3369 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3370 "Expected enum rights for account to fail");
3374 struct lsa_RightSet rights;
3375 struct lsa_StringLarge names[2];
3376 struct lsa_AddAccountRights r;
3378 torture_comment(tctx, "Testing LSA AddAccountRights\n");
3380 init_lsa_StringLarge(&names[0], "SeMachineAccountPrivilege");
3381 init_lsa_StringLarge(&names[1], NULL);
3384 rights.names = names;
3386 r.in.handle = lsa_handle;
3387 r.in.sid = user_sid;
3388 r.in.rights = &rights;
3390 status = dcerpc_lsa_AddAccountRights(lp, tctx, &r);
3391 torture_assert_ntstatus_ok(tctx, status,
3392 "Failed to add privileges");
3396 struct lsa_EnumAccounts r;
3397 uint32_t resume_handle = 0;
3398 struct lsa_SidArray lsa_sid_array;
3400 bool found_sid = false;
3402 torture_comment(tctx, "Testing LSA EnumAccounts\n");
3404 r.in.handle = lsa_handle;
3405 r.in.num_entries = 0x1000;
3406 r.in.resume_handle = &resume_handle;
3407 r.out.sids = &lsa_sid_array;
3408 r.out.resume_handle = &resume_handle;
3410 status = dcerpc_lsa_EnumAccounts(lp, tctx, &r);
3411 torture_assert_ntstatus_ok(tctx, status,
3412 "Failed to enum accounts");
3414 for (i=0; i < lsa_sid_array.num_sids; i++) {
3415 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
3420 torture_assert(tctx, found_sid,
3421 "failed to list privileged account");
3425 struct lsa_EnumAccountRights r;
3426 struct lsa_RightSet user_rights;
3428 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
3430 r.in.handle = lsa_handle;
3431 r.in.sid = user_sid;
3432 r.out.rights = &user_rights;
3434 status = dcerpc_lsa_EnumAccountRights(lp, tctx, &r);
3435 torture_assert_ntstatus_ok(tctx, status,
3436 "Failed to enum rights for account");
3438 if (user_rights.count < 1) {
3439 torture_warning(tctx, "failed to find newly added rights");
3445 struct lsa_OpenAccount r;
3447 torture_comment(tctx, "Testing LSA OpenAccount\n");
3449 r.in.handle = lsa_handle;
3450 r.in.sid = user_sid;
3451 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3452 r.out.acct_handle = &lsa_acct_handle;
3454 status = dcerpc_lsa_OpenAccount(lp, tctx, &r);
3455 torture_assert_ntstatus_ok(tctx, status,
3456 "Failed to open lsa account");
3460 struct lsa_GetSystemAccessAccount r;
3461 uint32_t access_mask;
3463 torture_comment(tctx, "Testing LSA GetSystemAccessAccount\n");
3465 r.in.handle = &lsa_acct_handle;
3466 r.out.access_mask = &access_mask;
3468 status = dcerpc_lsa_GetSystemAccessAccount(lp, tctx, &r);
3469 torture_assert_ntstatus_ok(tctx, status,
3470 "Failed to get lsa system access account");
3476 torture_comment(tctx, "Testing LSA Close\n");
3478 r.in.handle = &lsa_acct_handle;
3479 r.out.handle = &lsa_acct_handle;
3481 status = dcerpc_lsa_Close(lp, tctx, &r);
3482 torture_assert_ntstatus_ok(tctx, status,
3483 "Failed to close lsa");
3487 struct samr_DeleteUser r;
3489 torture_comment(tctx, "Testing SAMR DeleteUser\n");
3491 r.in.user_handle = user_handle;
3492 r.out.user_handle = user_handle;
3494 status = dcerpc_samr_DeleteUser(p, tctx, &r);
3495 torture_assert_ntstatus_ok(tctx, status, "Delete User failed");
3499 struct lsa_EnumAccounts r;
3500 uint32_t resume_handle = 0;
3501 struct lsa_SidArray lsa_sid_array;
3503 bool found_sid = false;
3505 torture_comment(tctx, "Testing LSA EnumAccounts\n");
3507 r.in.handle = lsa_handle;
3508 r.in.num_entries = 0x1000;
3509 r.in.resume_handle = &resume_handle;
3510 r.out.sids = &lsa_sid_array;
3511 r.out.resume_handle = &resume_handle;
3513 status = dcerpc_lsa_EnumAccounts(lp, tctx, &r);
3514 torture_assert_ntstatus_ok(tctx, status,
3515 "Failed to enum accounts");
3517 for (i=0; i < lsa_sid_array.num_sids; i++) {
3518 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
3523 torture_assert(tctx, found_sid,
3524 "failed to list privileged account");
3528 struct lsa_EnumAccountRights r;
3529 struct lsa_RightSet user_rights;
3531 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
3533 r.in.handle = lsa_handle;
3534 r.in.sid = user_sid;
3535 r.out.rights = &user_rights;
3537 status = dcerpc_lsa_EnumAccountRights(lp, tctx, &r);
3538 torture_assert_ntstatus_ok(tctx, status,
3539 "Failed to enum rights for account");
3541 if (user_rights.count < 1) {
3542 torture_warning(tctx, "failed to find newly added rights");
3548 struct lsa_OpenAccount r;
3550 torture_comment(tctx, "Testing LSA OpenAccount\n");
3552 r.in.handle = lsa_handle;
3553 r.in.sid = user_sid;
3554 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3555 r.out.acct_handle = &lsa_acct_handle;
3557 status = dcerpc_lsa_OpenAccount(lp, tctx, &r);
3558 torture_assert_ntstatus_ok(tctx, status,
3559 "Failed to open lsa account");
3563 struct lsa_GetSystemAccessAccount r;
3564 uint32_t access_mask;
3566 torture_comment(tctx, "Testing LSA GetSystemAccessAccount\n");
3568 r.in.handle = &lsa_acct_handle;
3569 r.out.access_mask = &access_mask;
3571 status = dcerpc_lsa_GetSystemAccessAccount(lp, tctx, &r);
3572 torture_assert_ntstatus_ok(tctx, status,
3573 "Failed to get lsa system access account");
3577 struct lsa_DeleteObject r;
3579 torture_comment(tctx, "Testing LSA DeleteObject\n");
3581 r.in.handle = &lsa_acct_handle;
3582 r.out.handle = &lsa_acct_handle;
3584 status = dcerpc_lsa_DeleteObject(lp, tctx, &r);
3585 torture_assert_ntstatus_ok(tctx, status,
3586 "Failed to delete object");
3590 struct lsa_EnumAccounts r;
3591 uint32_t resume_handle = 0;
3592 struct lsa_SidArray lsa_sid_array;
3594 bool found_sid = false;
3596 torture_comment(tctx, "Testing LSA EnumAccounts\n");
3598 r.in.handle = lsa_handle;
3599 r.in.num_entries = 0x1000;
3600 r.in.resume_handle = &resume_handle;
3601 r.out.sids = &lsa_sid_array;
3602 r.out.resume_handle = &resume_handle;
3604 status = dcerpc_lsa_EnumAccounts(lp, tctx, &r);
3605 torture_assert_ntstatus_ok(tctx, status,
3606 "Failed to enum accounts");
3608 for (i=0; i < lsa_sid_array.num_sids; i++) {
3609 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
3614 torture_assert(tctx, !found_sid,
3615 "should not have listed privileged account");
3619 struct lsa_EnumAccountRights r;
3620 struct lsa_RightSet user_rights;
3622 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
3624 r.in.handle = lsa_handle;
3625 r.in.sid = user_sid;
3626 r.out.rights = &user_rights;
3628 status = dcerpc_lsa_EnumAccountRights(lp, tctx, &r);
3629 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3630 "Failed to enum rights for account");