2 Unix SMB/CIFS implementation.
3 test suite for samr rpc operations
5 Copyright (C) Andrew Tridgell 2003
6 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "torture/torture.h"
24 #include "system/time.h"
25 #include "librpc/gen_ndr/lsa.h"
26 #include "librpc/gen_ndr/ndr_netlogon.h"
27 #include "librpc/gen_ndr/ndr_netlogon_c.h"
28 #include "librpc/gen_ndr/ndr_samr_c.h"
29 #include "../lib/crypto/crypto.h"
30 #include "libcli/auth/libcli_auth.h"
31 #include "libcli/security/security.h"
32 #include "torture/rpc/rpc.h"
33 #include "param/param.h"
37 #define TEST_ACCOUNT_NAME "samrtorturetest"
38 #define TEST_ACCOUNT_NAME_PWD "samrpwdlastset"
39 #define TEST_ALIASNAME "samrtorturetestalias"
40 #define TEST_GROUPNAME "samrtorturetestgroup"
41 #define TEST_MACHINENAME "samrtestmach$"
42 #define TEST_DOMAINNAME "samrtestdom$"
44 enum torture_samr_choice {
45 TORTURE_SAMR_PASSWORDS,
46 TORTURE_SAMR_PASSWORDS_PWDLASTSET,
47 TORTURE_SAMR_USER_ATTRIBUTES,
51 static bool test_QueryUserInfo(struct dcerpc_pipe *p,
52 struct torture_context *tctx,
53 struct policy_handle *handle);
55 static bool test_QueryUserInfo2(struct dcerpc_pipe *p,
56 struct torture_context *tctx,
57 struct policy_handle *handle);
59 static bool test_QueryAliasInfo(struct dcerpc_pipe *p,
60 struct torture_context *tctx,
61 struct policy_handle *handle);
63 static bool test_ChangePassword(struct dcerpc_pipe *p,
64 struct torture_context *tctx,
65 const char *acct_name,
66 struct policy_handle *domain_handle, char **password);
68 static void init_lsa_String(struct lsa_String *string, const char *s)
73 static void init_lsa_BinaryString(struct lsa_BinaryString *string, const char *s, uint32_t length)
75 string->length = length;
76 string->size = length;
77 string->array = (uint16_t *)discard_const(s);
80 bool test_samr_handle_Close(struct dcerpc_pipe *p, struct torture_context *tctx,
81 struct policy_handle *handle)
87 r.out.handle = handle;
89 status = dcerpc_samr_Close(p, tctx, &r);
90 torture_assert_ntstatus_ok(tctx, status, "Close");
95 static bool test_Shutdown(struct dcerpc_pipe *p, struct torture_context *tctx,
96 struct policy_handle *handle)
99 struct samr_Shutdown r;
101 if (!torture_setting_bool(tctx, "dangerous", false)) {
102 torture_skip(tctx, "samr_Shutdown disabled - enable dangerous tests to use\n");
106 r.in.connect_handle = handle;
108 torture_comment(tctx, "testing samr_Shutdown\n");
110 status = dcerpc_samr_Shutdown(p, tctx, &r);
111 torture_assert_ntstatus_ok(tctx, status, "samr_Shutdown");
116 static bool test_SetDsrmPassword(struct dcerpc_pipe *p, struct torture_context *tctx,
117 struct policy_handle *handle)
120 struct samr_SetDsrmPassword r;
121 struct lsa_String string;
122 struct samr_Password hash;
124 if (!torture_setting_bool(tctx, "dangerous", false)) {
125 torture_skip(tctx, "samr_SetDsrmPassword disabled - enable dangerous tests to use");
128 E_md4hash("TeSTDSRM123", hash.hash);
130 init_lsa_String(&string, "Administrator");
136 torture_comment(tctx, "testing samr_SetDsrmPassword\n");
138 status = dcerpc_samr_SetDsrmPassword(p, tctx, &r);
139 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_SUPPORTED, "samr_SetDsrmPassword");
145 static bool test_QuerySecurity(struct dcerpc_pipe *p,
146 struct torture_context *tctx,
147 struct policy_handle *handle)
150 struct samr_QuerySecurity r;
151 struct samr_SetSecurity s;
152 struct sec_desc_buf *sdbuf = NULL;
154 r.in.handle = handle;
156 r.out.sdbuf = &sdbuf;
158 status = dcerpc_samr_QuerySecurity(p, tctx, &r);
159 torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
161 torture_assert(tctx, sdbuf != NULL, "sdbuf is NULL");
163 s.in.handle = handle;
167 if (torture_setting_bool(tctx, "samba4", false)) {
168 torture_skip(tctx, "skipping SetSecurity test against Samba4\n");
171 status = dcerpc_samr_SetSecurity(p, tctx, &s);
172 torture_assert_ntstatus_ok(tctx, status, "SetSecurity");
174 status = dcerpc_samr_QuerySecurity(p, tctx, &r);
175 torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
181 static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
182 struct policy_handle *handle, uint32_t base_acct_flags,
183 const char *base_account_name)
186 struct samr_SetUserInfo s;
187 struct samr_SetUserInfo2 s2;
188 struct samr_QueryUserInfo q;
189 struct samr_QueryUserInfo q0;
190 union samr_UserInfo u;
191 union samr_UserInfo *info;
193 const char *test_account_name;
195 uint32_t user_extra_flags = 0;
197 if (!torture_setting_bool(tctx, "samba3", false)) {
198 if (base_acct_flags == ACB_NORMAL) {
199 /* When created, accounts are expired by default */
200 user_extra_flags = ACB_PW_EXPIRED;
204 s.in.user_handle = handle;
207 s2.in.user_handle = handle;
210 q.in.user_handle = handle;
214 #define TESTCALL(call, r) \
215 status = dcerpc_samr_ ##call(p, tctx, &r); \
216 if (!NT_STATUS_IS_OK(status)) { \
217 torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
218 r.in.level, nt_errstr(status), __location__); \
223 #define STRING_EQUAL(s1, s2, field) \
224 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
225 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
226 #field, s2, __location__); \
231 #define MEM_EQUAL(s1, s2, length, field) \
232 if ((s1 && !s2) || (s2 && !s1) || memcmp(s1, s2, length)) { \
233 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
234 #field, (const char *)s2, __location__); \
239 #define INT_EQUAL(i1, i2, field) \
241 torture_comment(tctx, "Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \
242 #field, (unsigned long long)i2, (unsigned long long)i1, __location__); \
247 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
248 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
250 TESTCALL(QueryUserInfo, q) \
252 s2.in.level = lvl1; \
255 ZERO_STRUCT(u.info21); \
256 u.info21.fields_present = fpval; \
258 init_lsa_String(&u.info ## lvl1.field1, value); \
259 TESTCALL(SetUserInfo, s) \
260 TESTCALL(SetUserInfo2, s2) \
261 init_lsa_String(&u.info ## lvl1.field1, ""); \
262 TESTCALL(QueryUserInfo, q); \
264 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
266 TESTCALL(QueryUserInfo, q) \
268 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
271 #define TEST_USERINFO_BINARYSTRING(lvl1, field1, lvl2, field2, value, fpval) do { \
272 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
274 TESTCALL(QueryUserInfo, q) \
276 s2.in.level = lvl1; \
279 ZERO_STRUCT(u.info21); \
280 u.info21.fields_present = fpval; \
282 init_lsa_BinaryString(&u.info ## lvl1.field1, value, strlen(value)); \
283 TESTCALL(SetUserInfo, s) \
284 TESTCALL(SetUserInfo2, s2) \
285 init_lsa_BinaryString(&u.info ## lvl1.field1, "", 1); \
286 TESTCALL(QueryUserInfo, q); \
288 MEM_EQUAL(u.info ## lvl1.field1.array, value, strlen(value), field1); \
290 TESTCALL(QueryUserInfo, q) \
292 MEM_EQUAL(u.info ## lvl2.field2.array, value, strlen(value), field2); \
295 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
296 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
298 TESTCALL(QueryUserInfo, q) \
300 s2.in.level = lvl1; \
303 uint8_t *bits = u.info21.logon_hours.bits; \
304 ZERO_STRUCT(u.info21); \
305 if (fpval == SAMR_FIELD_LOGON_HOURS) { \
306 u.info21.logon_hours.units_per_week = 168; \
307 u.info21.logon_hours.bits = bits; \
309 u.info21.fields_present = fpval; \
311 u.info ## lvl1.field1 = value; \
312 TESTCALL(SetUserInfo, s) \
313 TESTCALL(SetUserInfo2, s2) \
314 u.info ## lvl1.field1 = 0; \
315 TESTCALL(QueryUserInfo, q); \
317 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
319 TESTCALL(QueryUserInfo, q) \
321 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
324 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
325 TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
329 do { TESTCALL(QueryUserInfo, q0) } while (0);
331 /* Samba 3 cannot store comment fields atm. - gd */
332 if (!torture_setting_bool(tctx, "samba3", false)) {
333 TEST_USERINFO_STRING(2, comment, 1, comment, "xx2-1 comment", 0);
334 TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
335 TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment",
339 test_account_name = talloc_asprintf(tctx, "%sxx7-1", base_account_name);
340 TEST_USERINFO_STRING(7, account_name, 1, account_name, base_account_name, 0);
341 test_account_name = talloc_asprintf(tctx, "%sxx7-3", base_account_name);
342 TEST_USERINFO_STRING(7, account_name, 3, account_name, base_account_name, 0);
343 test_account_name = talloc_asprintf(tctx, "%sxx7-5", base_account_name);
344 TEST_USERINFO_STRING(7, account_name, 5, account_name, base_account_name, 0);
345 test_account_name = talloc_asprintf(tctx, "%sxx7-6", base_account_name);
346 TEST_USERINFO_STRING(7, account_name, 6, account_name, base_account_name, 0);
347 test_account_name = talloc_asprintf(tctx, "%sxx7-7", base_account_name);
348 TEST_USERINFO_STRING(7, account_name, 7, account_name, base_account_name, 0);
349 test_account_name = talloc_asprintf(tctx, "%sxx7-21", base_account_name);
350 TEST_USERINFO_STRING(7, account_name, 21, account_name, base_account_name, 0);
351 test_account_name = base_account_name;
352 TEST_USERINFO_STRING(21, account_name, 21, account_name, base_account_name,
353 SAMR_FIELD_ACCOUNT_NAME);
355 TEST_USERINFO_STRING(6, full_name, 1, full_name, "xx6-1 full_name", 0);
356 TEST_USERINFO_STRING(6, full_name, 3, full_name, "xx6-3 full_name", 0);
357 TEST_USERINFO_STRING(6, full_name, 5, full_name, "xx6-5 full_name", 0);
358 TEST_USERINFO_STRING(6, full_name, 6, full_name, "xx6-6 full_name", 0);
359 TEST_USERINFO_STRING(6, full_name, 8, full_name, "xx6-8 full_name", 0);
360 TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
361 TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
362 TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name",
363 SAMR_FIELD_FULL_NAME);
365 TEST_USERINFO_STRING(6, full_name, 1, full_name, "", 0);
366 TEST_USERINFO_STRING(6, full_name, 3, full_name, "", 0);
367 TEST_USERINFO_STRING(6, full_name, 5, full_name, "", 0);
368 TEST_USERINFO_STRING(6, full_name, 6, full_name, "", 0);
369 TEST_USERINFO_STRING(6, full_name, 8, full_name, "", 0);
370 TEST_USERINFO_STRING(6, full_name, 21, full_name, "", 0);
371 TEST_USERINFO_STRING(8, full_name, 21, full_name, "", 0);
372 TEST_USERINFO_STRING(21, full_name, 21, full_name, "",
373 SAMR_FIELD_FULL_NAME);
375 TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
376 TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
377 TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
378 TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script",
379 SAMR_FIELD_LOGON_SCRIPT);
381 TEST_USERINFO_STRING(12, profile_path, 3, profile_path, "xx12-3 profile_path", 0);
382 TEST_USERINFO_STRING(12, profile_path, 5, profile_path, "xx12-5 profile_path", 0);
383 TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
384 TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path",
385 SAMR_FIELD_PROFILE_PATH);
387 TEST_USERINFO_STRING(10, home_directory, 3, home_directory, "xx10-3 home_directory", 0);
388 TEST_USERINFO_STRING(10, home_directory, 5, home_directory, "xx10-5 home_directory", 0);
389 TEST_USERINFO_STRING(10, home_directory, 21, home_directory, "xx10-21 home_directory", 0);
390 TEST_USERINFO_STRING(21, home_directory, 21, home_directory, "xx21-21 home_directory",
391 SAMR_FIELD_HOME_DIRECTORY);
392 TEST_USERINFO_STRING(21, home_directory, 10, home_directory, "xx21-10 home_directory",
393 SAMR_FIELD_HOME_DIRECTORY);
395 TEST_USERINFO_STRING(10, home_drive, 3, home_drive, "xx10-3 home_drive", 0);
396 TEST_USERINFO_STRING(10, home_drive, 5, home_drive, "xx10-5 home_drive", 0);
397 TEST_USERINFO_STRING(10, home_drive, 21, home_drive, "xx10-21 home_drive", 0);
398 TEST_USERINFO_STRING(21, home_drive, 21, home_drive, "xx21-21 home_drive",
399 SAMR_FIELD_HOME_DRIVE);
400 TEST_USERINFO_STRING(21, home_drive, 10, home_drive, "xx21-10 home_drive",
401 SAMR_FIELD_HOME_DRIVE);
403 TEST_USERINFO_STRING(13, description, 1, description, "xx13-1 description", 0);
404 TEST_USERINFO_STRING(13, description, 5, description, "xx13-5 description", 0);
405 TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
406 TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description",
407 SAMR_FIELD_DESCRIPTION);
409 TEST_USERINFO_STRING(14, workstations, 3, workstations, "14workstation3", 0);
410 TEST_USERINFO_STRING(14, workstations, 5, workstations, "14workstation4", 0);
411 TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
412 TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21",
413 SAMR_FIELD_WORKSTATIONS);
414 TEST_USERINFO_STRING(21, workstations, 3, workstations, "21workstation3",
415 SAMR_FIELD_WORKSTATIONS);
416 TEST_USERINFO_STRING(21, workstations, 5, workstations, "21workstation5",
417 SAMR_FIELD_WORKSTATIONS);
418 TEST_USERINFO_STRING(21, workstations, 14, workstations, "21workstation14",
419 SAMR_FIELD_WORKSTATIONS);
421 TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
422 TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "xx21-21 parameters",
423 SAMR_FIELD_PARAMETERS);
424 TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "xx21-20 parameters",
425 SAMR_FIELD_PARAMETERS);
426 /* also empty user parameters are allowed */
427 TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "", 0);
428 TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "",
429 SAMR_FIELD_PARAMETERS);
430 TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "",
431 SAMR_FIELD_PARAMETERS);
433 /* Samba 3 cannot store country_code and copy_page atm. - gd */
434 if (!torture_setting_bool(tctx, "samba3", false)) {
435 TEST_USERINFO_INT(2, country_code, 2, country_code, __LINE__, 0);
436 TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
437 TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__,
438 SAMR_FIELD_COUNTRY_CODE);
439 TEST_USERINFO_INT(21, country_code, 2, country_code, __LINE__,
440 SAMR_FIELD_COUNTRY_CODE);
442 TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
443 TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__,
444 SAMR_FIELD_CODE_PAGE);
445 TEST_USERINFO_INT(21, code_page, 2, code_page, __LINE__,
446 SAMR_FIELD_CODE_PAGE);
449 if (!torture_setting_bool(tctx, "samba3", false)) {
450 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, __LINE__, 0);
451 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, __LINE__, 0);
452 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, __LINE__,
453 SAMR_FIELD_ACCT_EXPIRY);
454 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, __LINE__,
455 SAMR_FIELD_ACCT_EXPIRY);
456 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, __LINE__,
457 SAMR_FIELD_ACCT_EXPIRY);
459 /* Samba 3 can only store seconds / time_t in passdb - gd */
461 unix_to_nt_time(&nt, time(NULL) + __LINE__);
462 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, nt, 0);
463 unix_to_nt_time(&nt, time(NULL) + __LINE__);
464 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, nt, 0);
465 unix_to_nt_time(&nt, time(NULL) + __LINE__);
466 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
467 unix_to_nt_time(&nt, time(NULL) + __LINE__);
468 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
469 unix_to_nt_time(&nt, time(NULL) + __LINE__);
470 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
473 TEST_USERINFO_INT(4, logon_hours.bits[3], 3, logon_hours.bits[3], 1, 0);
474 TEST_USERINFO_INT(4, logon_hours.bits[3], 5, logon_hours.bits[3], 2, 0);
475 TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
476 TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4,
477 SAMR_FIELD_LOGON_HOURS);
479 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
480 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
481 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
483 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
484 (base_acct_flags | ACB_DISABLED),
485 (base_acct_flags | ACB_DISABLED | user_extra_flags),
488 /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
489 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
490 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
491 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
493 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
494 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
495 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
499 /* The 'autolock' flag doesn't stick - check this */
500 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
501 (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK),
502 (base_acct_flags | ACB_DISABLED | user_extra_flags),
505 /* Removing the 'disabled' flag doesn't stick - check this */
506 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
508 (base_acct_flags | ACB_DISABLED | user_extra_flags),
512 /* Samba3 cannot store these atm */
513 if (!torture_setting_bool(tctx, "samba3", false)) {
514 /* The 'store plaintext' flag does stick */
515 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
516 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED),
517 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags),
519 /* The 'use DES' flag does stick */
520 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
521 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY),
522 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags),
524 /* The 'don't require kerberos pre-authentication flag does stick */
525 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
526 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH),
527 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags),
529 /* The 'no kerberos PAC required' flag sticks */
530 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
531 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD),
532 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags),
535 TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags,
536 (base_acct_flags | ACB_DISABLED),
537 (base_acct_flags | ACB_DISABLED | user_extra_flags),
538 SAMR_FIELD_ACCT_FLAGS);
541 /* these fail with win2003 - it appears you can't set the primary gid?
542 the set succeeds, but the gid isn't changed. Very weird! */
543 TEST_USERINFO_INT(9, primary_gid, 1, primary_gid, 513);
544 TEST_USERINFO_INT(9, primary_gid, 3, primary_gid, 513);
545 TEST_USERINFO_INT(9, primary_gid, 5, primary_gid, 513);
546 TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
553 generate a random password for password change tests
555 static char *samr_rand_pass_silent(TALLOC_CTX *mem_ctx, int min_len)
557 size_t len = MAX(8, min_len) + (random() % 6);
558 char *s = generate_random_str(mem_ctx, len);
562 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
564 char *s = samr_rand_pass_silent(mem_ctx, min_len);
565 printf("Generated password '%s'\n", s);
571 generate a random password for password change tests
573 static DATA_BLOB samr_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
576 DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
577 generate_random_buffer(password.data, password.length);
579 for (i=0; i < len; i++) {
580 if (((uint16_t *)password.data)[i] == 0) {
581 ((uint16_t *)password.data)[i] = 1;
589 generate a random password for password change tests (fixed length)
591 static char *samr_rand_pass_fixed_len(TALLOC_CTX *mem_ctx, int len)
593 char *s = generate_random_str(mem_ctx, len);
594 printf("Generated password '%s'\n", s);
598 static bool test_SetUserPass(struct dcerpc_pipe *p, struct torture_context *tctx,
599 struct policy_handle *handle, char **password)
602 struct samr_SetUserInfo s;
603 union samr_UserInfo u;
605 DATA_BLOB session_key;
607 struct samr_GetUserPwInfo pwp;
608 struct samr_PwInfo info;
609 int policy_min_pw_len = 0;
610 pwp.in.user_handle = handle;
611 pwp.out.info = &info;
613 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
614 if (NT_STATUS_IS_OK(status)) {
615 policy_min_pw_len = pwp.out.info->min_password_length;
617 newpass = samr_rand_pass(tctx, policy_min_pw_len);
619 s.in.user_handle = handle;
623 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
624 u.info24.password_expired = 0;
626 status = dcerpc_fetch_session_key(p, &session_key);
627 if (!NT_STATUS_IS_OK(status)) {
628 printf("SetUserInfo level %u - no session key - %s\n",
629 s.in.level, nt_errstr(status));
633 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
635 torture_comment(tctx, "Testing SetUserInfo level 24 (set password)\n");
637 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
638 if (!NT_STATUS_IS_OK(status)) {
639 printf("SetUserInfo level %u failed - %s\n",
640 s.in.level, nt_errstr(status));
650 static bool test_SetUserPass_23(struct dcerpc_pipe *p, struct torture_context *tctx,
651 struct policy_handle *handle, uint32_t fields_present,
655 struct samr_SetUserInfo s;
656 union samr_UserInfo u;
658 DATA_BLOB session_key;
660 struct samr_GetUserPwInfo pwp;
661 struct samr_PwInfo info;
662 int policy_min_pw_len = 0;
663 pwp.in.user_handle = handle;
664 pwp.out.info = &info;
666 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
667 if (NT_STATUS_IS_OK(status)) {
668 policy_min_pw_len = pwp.out.info->min_password_length;
670 newpass = samr_rand_pass(tctx, policy_min_pw_len);
672 s.in.user_handle = handle;
678 u.info23.info.fields_present = fields_present;
680 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
682 status = dcerpc_fetch_session_key(p, &session_key);
683 if (!NT_STATUS_IS_OK(status)) {
684 printf("SetUserInfo level %u - no session key - %s\n",
685 s.in.level, nt_errstr(status));
689 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
691 torture_comment(tctx, "Testing SetUserInfo level 23 (set password)\n");
693 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
694 if (!NT_STATUS_IS_OK(status)) {
695 printf("SetUserInfo level %u failed - %s\n",
696 s.in.level, nt_errstr(status));
702 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
704 status = dcerpc_fetch_session_key(p, &session_key);
705 if (!NT_STATUS_IS_OK(status)) {
706 printf("SetUserInfo level %u - no session key - %s\n",
707 s.in.level, nt_errstr(status));
711 /* This should break the key nicely */
712 session_key.length--;
713 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
715 torture_comment(tctx, "Testing SetUserInfo level 23 (set password) with wrong password\n");
717 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
718 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
719 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
720 s.in.level, nt_errstr(status));
728 static bool test_SetUserPassEx(struct dcerpc_pipe *p, struct torture_context *tctx,
729 struct policy_handle *handle, bool makeshort,
733 struct samr_SetUserInfo s;
734 union samr_UserInfo u;
736 DATA_BLOB session_key;
737 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
738 uint8_t confounder[16];
740 struct MD5Context ctx;
741 struct samr_GetUserPwInfo pwp;
742 struct samr_PwInfo info;
743 int policy_min_pw_len = 0;
744 pwp.in.user_handle = handle;
745 pwp.out.info = &info;
747 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
748 if (NT_STATUS_IS_OK(status)) {
749 policy_min_pw_len = pwp.out.info->min_password_length;
751 if (makeshort && policy_min_pw_len) {
752 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len - 1);
754 newpass = samr_rand_pass(tctx, policy_min_pw_len);
757 s.in.user_handle = handle;
761 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
762 u.info26.password_expired = 0;
764 status = dcerpc_fetch_session_key(p, &session_key);
765 if (!NT_STATUS_IS_OK(status)) {
766 printf("SetUserInfo level %u - no session key - %s\n",
767 s.in.level, nt_errstr(status));
771 generate_random_buffer((uint8_t *)confounder, 16);
774 MD5Update(&ctx, confounder, 16);
775 MD5Update(&ctx, session_key.data, session_key.length);
776 MD5Final(confounded_session_key.data, &ctx);
778 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
779 memcpy(&u.info26.password.data[516], confounder, 16);
781 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex)\n");
783 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
784 if (!NT_STATUS_IS_OK(status)) {
785 printf("SetUserInfo level %u failed - %s\n",
786 s.in.level, nt_errstr(status));
792 /* This should break the key nicely */
793 confounded_session_key.data[0]++;
795 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
796 memcpy(&u.info26.password.data[516], confounder, 16);
798 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
800 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
801 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
802 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
803 s.in.level, nt_errstr(status));
812 static bool test_SetUserPass_25(struct dcerpc_pipe *p, struct torture_context *tctx,
813 struct policy_handle *handle, uint32_t fields_present,
817 struct samr_SetUserInfo s;
818 union samr_UserInfo u;
820 DATA_BLOB session_key;
821 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
822 struct MD5Context ctx;
823 uint8_t confounder[16];
825 struct samr_GetUserPwInfo pwp;
826 struct samr_PwInfo info;
827 int policy_min_pw_len = 0;
828 pwp.in.user_handle = handle;
829 pwp.out.info = &info;
831 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
832 if (NT_STATUS_IS_OK(status)) {
833 policy_min_pw_len = pwp.out.info->min_password_length;
835 newpass = samr_rand_pass(tctx, policy_min_pw_len);
837 s.in.user_handle = handle;
843 u.info25.info.fields_present = fields_present;
845 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
847 status = dcerpc_fetch_session_key(p, &session_key);
848 if (!NT_STATUS_IS_OK(status)) {
849 printf("SetUserInfo level %u - no session key - %s\n",
850 s.in.level, nt_errstr(status));
854 generate_random_buffer((uint8_t *)confounder, 16);
857 MD5Update(&ctx, confounder, 16);
858 MD5Update(&ctx, session_key.data, session_key.length);
859 MD5Final(confounded_session_key.data, &ctx);
861 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
862 memcpy(&u.info25.password.data[516], confounder, 16);
864 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex)\n");
866 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
867 if (!NT_STATUS_IS_OK(status)) {
868 printf("SetUserInfo level %u failed - %s\n",
869 s.in.level, nt_errstr(status));
875 /* This should break the key nicely */
876 confounded_session_key.data[0]++;
878 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
879 memcpy(&u.info25.password.data[516], confounder, 16);
881 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
883 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
884 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
885 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
886 s.in.level, nt_errstr(status));
893 static bool test_SetUserPass_18(struct dcerpc_pipe *p, struct torture_context *tctx,
894 struct policy_handle *handle, char **password)
897 struct samr_SetUserInfo s;
898 union samr_UserInfo u;
900 DATA_BLOB session_key;
902 struct samr_GetUserPwInfo pwp;
903 struct samr_PwInfo info;
904 int policy_min_pw_len = 0;
905 uint8_t lm_hash[16], nt_hash[16];
907 pwp.in.user_handle = handle;
908 pwp.out.info = &info;
910 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
911 if (NT_STATUS_IS_OK(status)) {
912 policy_min_pw_len = pwp.out.info->min_password_length;
914 newpass = samr_rand_pass(tctx, policy_min_pw_len);
916 s.in.user_handle = handle;
922 u.info18.nt_pwd_active = true;
923 u.info18.lm_pwd_active = true;
925 E_md4hash(newpass, nt_hash);
926 E_deshash(newpass, lm_hash);
928 status = dcerpc_fetch_session_key(p, &session_key);
929 if (!NT_STATUS_IS_OK(status)) {
930 printf("SetUserInfo level %u - no session key - %s\n",
931 s.in.level, nt_errstr(status));
937 in = data_blob_const(nt_hash, 16);
938 out = data_blob_talloc_zero(tctx, 16);
939 sess_crypt_blob(&out, &in, &session_key, true);
940 memcpy(u.info18.nt_pwd.hash, out.data, out.length);
944 in = data_blob_const(lm_hash, 16);
945 out = data_blob_talloc_zero(tctx, 16);
946 sess_crypt_blob(&out, &in, &session_key, true);
947 memcpy(u.info18.lm_pwd.hash, out.data, out.length);
950 torture_comment(tctx, "Testing SetUserInfo level 18 (set password hash)\n");
952 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
953 if (!NT_STATUS_IS_OK(status)) {
954 printf("SetUserInfo level %u failed - %s\n",
955 s.in.level, nt_errstr(status));
964 static bool test_SetUserPass_21(struct dcerpc_pipe *p, struct torture_context *tctx,
965 struct policy_handle *handle, uint32_t fields_present,
969 struct samr_SetUserInfo s;
970 union samr_UserInfo u;
972 DATA_BLOB session_key;
974 struct samr_GetUserPwInfo pwp;
975 struct samr_PwInfo info;
976 int policy_min_pw_len = 0;
977 uint8_t lm_hash[16], nt_hash[16];
979 pwp.in.user_handle = handle;
980 pwp.out.info = &info;
982 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
983 if (NT_STATUS_IS_OK(status)) {
984 policy_min_pw_len = pwp.out.info->min_password_length;
986 newpass = samr_rand_pass(tctx, policy_min_pw_len);
988 s.in.user_handle = handle;
992 E_md4hash(newpass, nt_hash);
993 E_deshash(newpass, lm_hash);
997 u.info21.fields_present = fields_present;
999 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1000 u.info21.lm_owf_password.length = 16;
1001 u.info21.lm_owf_password.size = 16;
1002 u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
1003 u.info21.lm_password_set = true;
1006 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1007 u.info21.nt_owf_password.length = 16;
1008 u.info21.nt_owf_password.size = 16;
1009 u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
1010 u.info21.nt_password_set = true;
1013 status = dcerpc_fetch_session_key(p, &session_key);
1014 if (!NT_STATUS_IS_OK(status)) {
1015 printf("SetUserInfo level %u - no session key - %s\n",
1016 s.in.level, nt_errstr(status));
1020 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1022 in = data_blob_const(u.info21.lm_owf_password.array,
1023 u.info21.lm_owf_password.length);
1024 out = data_blob_talloc_zero(tctx, 16);
1025 sess_crypt_blob(&out, &in, &session_key, true);
1026 u.info21.lm_owf_password.array = (uint16_t *)out.data;
1029 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1031 in = data_blob_const(u.info21.nt_owf_password.array,
1032 u.info21.nt_owf_password.length);
1033 out = data_blob_talloc_zero(tctx, 16);
1034 sess_crypt_blob(&out, &in, &session_key, true);
1035 u.info21.nt_owf_password.array = (uint16_t *)out.data;
1038 torture_comment(tctx, "Testing SetUserInfo level 21 (set password hash)\n");
1040 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1041 if (!NT_STATUS_IS_OK(status)) {
1042 printf("SetUserInfo level %u failed - %s\n",
1043 s.in.level, nt_errstr(status));
1046 *password = newpass;
1049 /* try invalid length */
1050 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1052 u.info21.nt_owf_password.length++;
1054 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1056 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1057 printf("SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1058 s.in.level, nt_errstr(status));
1063 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1065 u.info21.lm_owf_password.length++;
1067 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1069 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1070 printf("SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1071 s.in.level, nt_errstr(status));
1079 static bool test_SetUserPass_level_ex(struct dcerpc_pipe *p,
1080 struct torture_context *tctx,
1081 struct policy_handle *handle,
1083 uint32_t fields_present,
1084 char **password, uint8_t password_expired,
1086 bool *matched_expected_error)
1089 NTSTATUS expected_error = NT_STATUS_OK;
1090 struct samr_SetUserInfo s;
1091 struct samr_SetUserInfo2 s2;
1092 union samr_UserInfo u;
1094 DATA_BLOB session_key;
1095 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
1096 struct MD5Context ctx;
1097 uint8_t confounder[16];
1099 struct samr_GetUserPwInfo pwp;
1100 struct samr_PwInfo info;
1101 int policy_min_pw_len = 0;
1102 const char *comment = NULL;
1103 uint8_t lm_hash[16], nt_hash[16];
1105 pwp.in.user_handle = handle;
1106 pwp.out.info = &info;
1108 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1109 if (NT_STATUS_IS_OK(status)) {
1110 policy_min_pw_len = pwp.out.info->min_password_length;
1112 newpass = samr_rand_pass_silent(tctx, policy_min_pw_len);
1115 s2.in.user_handle = handle;
1117 s2.in.level = level;
1119 s.in.user_handle = handle;
1124 if (fields_present & SAMR_FIELD_COMMENT) {
1125 comment = talloc_asprintf(tctx, "comment: %ld\n", time(NULL));
1132 E_md4hash(newpass, nt_hash);
1133 E_deshash(newpass, lm_hash);
1135 u.info18.nt_pwd_active = true;
1136 u.info18.lm_pwd_active = true;
1137 u.info18.password_expired = password_expired;
1139 memcpy(u.info18.lm_pwd.hash, lm_hash, 16);
1140 memcpy(u.info18.nt_pwd.hash, nt_hash, 16);
1144 E_md4hash(newpass, nt_hash);
1145 E_deshash(newpass, lm_hash);
1147 u.info21.fields_present = fields_present;
1148 u.info21.password_expired = password_expired;
1149 u.info21.comment.string = comment;
1151 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1152 u.info21.lm_owf_password.length = 16;
1153 u.info21.lm_owf_password.size = 16;
1154 u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
1155 u.info21.lm_password_set = true;
1158 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1159 u.info21.nt_owf_password.length = 16;
1160 u.info21.nt_owf_password.size = 16;
1161 u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
1162 u.info21.nt_password_set = true;
1167 u.info23.info.fields_present = fields_present;
1168 u.info23.info.password_expired = password_expired;
1169 u.info23.info.comment.string = comment;
1171 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
1175 u.info24.password_expired = password_expired;
1177 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
1181 u.info25.info.fields_present = fields_present;
1182 u.info25.info.password_expired = password_expired;
1183 u.info25.info.comment.string = comment;
1185 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
1189 u.info26.password_expired = password_expired;
1191 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
1196 status = dcerpc_fetch_session_key(p, &session_key);
1197 if (!NT_STATUS_IS_OK(status)) {
1198 printf("SetUserInfo level %u - no session key - %s\n",
1199 s.in.level, nt_errstr(status));
1203 generate_random_buffer((uint8_t *)confounder, 16);
1206 MD5Update(&ctx, confounder, 16);
1207 MD5Update(&ctx, session_key.data, session_key.length);
1208 MD5Final(confounded_session_key.data, &ctx);
1214 in = data_blob_const(u.info18.nt_pwd.hash, 16);
1215 out = data_blob_talloc_zero(tctx, 16);
1216 sess_crypt_blob(&out, &in, &session_key, true);
1217 memcpy(u.info18.nt_pwd.hash, out.data, out.length);
1221 in = data_blob_const(u.info18.lm_pwd.hash, 16);
1222 out = data_blob_talloc_zero(tctx, 16);
1223 sess_crypt_blob(&out, &in, &session_key, true);
1224 memcpy(u.info18.lm_pwd.hash, out.data, out.length);
1229 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1231 in = data_blob_const(u.info21.lm_owf_password.array,
1232 u.info21.lm_owf_password.length);
1233 out = data_blob_talloc_zero(tctx, 16);
1234 sess_crypt_blob(&out, &in, &session_key, true);
1235 u.info21.lm_owf_password.array = (uint16_t *)out.data;
1237 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1239 in = data_blob_const(u.info21.nt_owf_password.array,
1240 u.info21.nt_owf_password.length);
1241 out = data_blob_talloc_zero(tctx, 16);
1242 sess_crypt_blob(&out, &in, &session_key, true);
1243 u.info21.nt_owf_password.array = (uint16_t *)out.data;
1247 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
1250 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
1253 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
1254 memcpy(&u.info25.password.data[516], confounder, 16);
1257 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
1258 memcpy(&u.info26.password.data[516], confounder, 16);
1263 status = dcerpc_samr_SetUserInfo2(p, tctx, &s2);
1265 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1268 if (!NT_STATUS_IS_OK(status)) {
1269 if (fields_present == 0) {
1270 expected_error = NT_STATUS_INVALID_PARAMETER;
1272 if (fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
1273 expected_error = NT_STATUS_ACCESS_DENIED;
1277 if (!NT_STATUS_IS_OK(expected_error)) {
1279 torture_assert_ntstatus_equal(tctx,
1281 expected_error, "SetUserInfo2 failed");
1283 torture_assert_ntstatus_equal(tctx,
1285 expected_error, "SetUserInfo failed");
1287 *matched_expected_error = true;
1291 if (!NT_STATUS_IS_OK(status)) {
1292 printf("SetUserInfo%s level %u failed - %s\n",
1293 use_setinfo2 ? "2":"", level, nt_errstr(status));
1296 *password = newpass;
1302 static bool test_SetAliasInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1303 struct policy_handle *handle)
1306 struct samr_SetAliasInfo r;
1307 struct samr_QueryAliasInfo q;
1308 union samr_AliasInfo *info;
1309 uint16_t levels[] = {2, 3};
1313 /* Ignoring switch level 1, as that includes the number of members for the alias
1314 * and setting this to a wrong value might have negative consequences
1317 for (i=0;i<ARRAY_SIZE(levels);i++) {
1318 torture_comment(tctx, "Testing SetAliasInfo level %u\n", levels[i]);
1320 r.in.alias_handle = handle;
1321 r.in.level = levels[i];
1322 r.in.info = talloc(tctx, union samr_AliasInfo);
1323 switch (r.in.level) {
1324 case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
1325 case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
1326 "Test Description, should test I18N as well"); break;
1327 case ALIASINFOALL: printf("ALIASINFOALL ignored\n"); break;
1330 status = dcerpc_samr_SetAliasInfo(p, tctx, &r);
1331 if (!NT_STATUS_IS_OK(status)) {
1332 printf("SetAliasInfo level %u failed - %s\n",
1333 levels[i], nt_errstr(status));
1337 q.in.alias_handle = handle;
1338 q.in.level = levels[i];
1341 status = dcerpc_samr_QueryAliasInfo(p, tctx, &q);
1342 if (!NT_STATUS_IS_OK(status)) {
1343 printf("QueryAliasInfo level %u failed - %s\n",
1344 levels[i], nt_errstr(status));
1352 static bool test_GetGroupsForUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1353 struct policy_handle *user_handle)
1355 struct samr_GetGroupsForUser r;
1356 struct samr_RidWithAttributeArray *rids = NULL;
1359 torture_comment(tctx, "testing GetGroupsForUser\n");
1361 r.in.user_handle = user_handle;
1364 status = dcerpc_samr_GetGroupsForUser(p, tctx, &r);
1365 torture_assert_ntstatus_ok(tctx, status, "GetGroupsForUser");
1371 static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1372 struct lsa_String *domain_name)
1375 struct samr_GetDomPwInfo r;
1376 struct samr_PwInfo info;
1378 r.in.domain_name = domain_name;
1381 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1383 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1384 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1386 r.in.domain_name->string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1387 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1389 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1390 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1392 r.in.domain_name->string = "\\\\__NONAME__";
1393 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1395 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1396 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1398 r.in.domain_name->string = "\\\\Builtin";
1399 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1401 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1402 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1407 static bool test_GetUserPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1408 struct policy_handle *handle)
1411 struct samr_GetUserPwInfo r;
1412 struct samr_PwInfo info;
1414 torture_comment(tctx, "Testing GetUserPwInfo\n");
1416 r.in.user_handle = handle;
1419 status = dcerpc_samr_GetUserPwInfo(p, tctx, &r);
1420 torture_assert_ntstatus_ok(tctx, status, "GetUserPwInfo");
1425 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, struct torture_context *tctx,
1426 struct policy_handle *domain_handle, const char *name,
1430 struct samr_LookupNames n;
1431 struct lsa_String sname[2];
1432 struct samr_Ids rids, types;
1434 init_lsa_String(&sname[0], name);
1436 n.in.domain_handle = domain_handle;
1440 n.out.types = &types;
1441 status = dcerpc_samr_LookupNames(p, tctx, &n);
1442 if (NT_STATUS_IS_OK(status)) {
1443 *rid = n.out.rids->ids[0];
1448 init_lsa_String(&sname[1], "xxNONAMExx");
1450 status = dcerpc_samr_LookupNames(p, tctx, &n);
1451 if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
1452 printf("LookupNames[2] failed - %s\n", nt_errstr(status));
1453 if (NT_STATUS_IS_OK(status)) {
1454 return NT_STATUS_UNSUCCESSFUL;
1460 status = dcerpc_samr_LookupNames(p, tctx, &n);
1461 if (!NT_STATUS_IS_OK(status)) {
1462 printf("LookupNames[0] failed - %s\n", nt_errstr(status));
1466 init_lsa_String(&sname[0], "xxNONAMExx");
1468 status = dcerpc_samr_LookupNames(p, tctx, &n);
1469 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1470 printf("LookupNames[1 bad name] failed - %s\n", nt_errstr(status));
1471 if (NT_STATUS_IS_OK(status)) {
1472 return NT_STATUS_UNSUCCESSFUL;
1477 init_lsa_String(&sname[0], "xxNONAMExx");
1478 init_lsa_String(&sname[1], "xxNONAME2xx");
1480 status = dcerpc_samr_LookupNames(p, tctx, &n);
1481 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1482 printf("LookupNames[2 bad names] failed - %s\n", nt_errstr(status));
1483 if (NT_STATUS_IS_OK(status)) {
1484 return NT_STATUS_UNSUCCESSFUL;
1489 return NT_STATUS_OK;
1492 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p,
1493 struct torture_context *tctx,
1494 struct policy_handle *domain_handle,
1495 const char *name, struct policy_handle *user_handle)
1498 struct samr_OpenUser r;
1501 status = test_LookupName(p, tctx, domain_handle, name, &rid);
1502 if (!NT_STATUS_IS_OK(status)) {
1506 r.in.domain_handle = domain_handle;
1507 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1509 r.out.user_handle = user_handle;
1510 status = dcerpc_samr_OpenUser(p, tctx, &r);
1511 if (!NT_STATUS_IS_OK(status)) {
1512 printf("OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(status));
1519 static bool test_ChangePasswordNT3(struct dcerpc_pipe *p,
1520 struct torture_context *tctx,
1521 struct policy_handle *handle)
1524 struct samr_ChangePasswordUser r;
1526 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1527 struct policy_handle user_handle;
1528 char *oldpass = "test";
1529 char *newpass = "test2";
1530 uint8_t old_nt_hash[16], new_nt_hash[16];
1531 uint8_t old_lm_hash[16], new_lm_hash[16];
1533 status = test_OpenUser_byname(p, tctx, handle, "testuser", &user_handle);
1534 if (!NT_STATUS_IS_OK(status)) {
1538 printf("Testing ChangePasswordUser for user 'testuser'\n");
1540 printf("old password: %s\n", oldpass);
1541 printf("new password: %s\n", newpass);
1543 E_md4hash(oldpass, old_nt_hash);
1544 E_md4hash(newpass, new_nt_hash);
1545 E_deshash(oldpass, old_lm_hash);
1546 E_deshash(newpass, new_lm_hash);
1548 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1549 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1550 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1551 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1552 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1553 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1555 r.in.handle = &user_handle;
1556 r.in.lm_present = 1;
1557 r.in.old_lm_crypted = &hash1;
1558 r.in.new_lm_crypted = &hash2;
1559 r.in.nt_present = 1;
1560 r.in.old_nt_crypted = &hash3;
1561 r.in.new_nt_crypted = &hash4;
1562 r.in.cross1_present = 1;
1563 r.in.nt_cross = &hash5;
1564 r.in.cross2_present = 1;
1565 r.in.lm_cross = &hash6;
1567 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1568 if (!NT_STATUS_IS_OK(status)) {
1569 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1573 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
1581 static bool test_ChangePasswordUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1582 const char *acct_name,
1583 struct policy_handle *handle, char **password)
1586 struct samr_ChangePasswordUser r;
1588 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1589 struct policy_handle user_handle;
1591 uint8_t old_nt_hash[16], new_nt_hash[16];
1592 uint8_t old_lm_hash[16], new_lm_hash[16];
1593 bool changed = true;
1596 struct samr_GetUserPwInfo pwp;
1597 struct samr_PwInfo info;
1598 int policy_min_pw_len = 0;
1600 status = test_OpenUser_byname(p, tctx, handle, acct_name, &user_handle);
1601 if (!NT_STATUS_IS_OK(status)) {
1604 pwp.in.user_handle = &user_handle;
1605 pwp.out.info = &info;
1607 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1608 if (NT_STATUS_IS_OK(status)) {
1609 policy_min_pw_len = pwp.out.info->min_password_length;
1611 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1613 torture_comment(tctx, "Testing ChangePasswordUser\n");
1615 torture_assert(tctx, *password != NULL,
1616 "Failing ChangePasswordUser as old password was NULL. Previous test failed?");
1618 oldpass = *password;
1620 E_md4hash(oldpass, old_nt_hash);
1621 E_md4hash(newpass, new_nt_hash);
1622 E_deshash(oldpass, old_lm_hash);
1623 E_deshash(newpass, new_lm_hash);
1625 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1626 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1627 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1628 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1629 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1630 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1632 r.in.user_handle = &user_handle;
1633 r.in.lm_present = 1;
1634 /* Break the LM hash */
1636 r.in.old_lm_crypted = &hash1;
1637 r.in.new_lm_crypted = &hash2;
1638 r.in.nt_present = 1;
1639 r.in.old_nt_crypted = &hash3;
1640 r.in.new_nt_crypted = &hash4;
1641 r.in.cross1_present = 1;
1642 r.in.nt_cross = &hash5;
1643 r.in.cross2_present = 1;
1644 r.in.lm_cross = &hash6;
1646 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1647 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1648 "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash");
1650 /* Unbreak the LM hash */
1653 r.in.user_handle = &user_handle;
1654 r.in.lm_present = 1;
1655 r.in.old_lm_crypted = &hash1;
1656 r.in.new_lm_crypted = &hash2;
1657 /* Break the NT hash */
1659 r.in.nt_present = 1;
1660 r.in.old_nt_crypted = &hash3;
1661 r.in.new_nt_crypted = &hash4;
1662 r.in.cross1_present = 1;
1663 r.in.nt_cross = &hash5;
1664 r.in.cross2_present = 1;
1665 r.in.lm_cross = &hash6;
1667 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1668 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1669 "expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash");
1671 /* Unbreak the NT hash */
1674 r.in.user_handle = &user_handle;
1675 r.in.lm_present = 1;
1676 r.in.old_lm_crypted = &hash1;
1677 r.in.new_lm_crypted = &hash2;
1678 r.in.nt_present = 1;
1679 r.in.old_nt_crypted = &hash3;
1680 r.in.new_nt_crypted = &hash4;
1681 r.in.cross1_present = 1;
1682 r.in.nt_cross = &hash5;
1683 r.in.cross2_present = 1;
1684 /* Break the LM cross */
1686 r.in.lm_cross = &hash6;
1688 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1689 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1690 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status));
1694 /* Unbreak the LM cross */
1697 r.in.user_handle = &user_handle;
1698 r.in.lm_present = 1;
1699 r.in.old_lm_crypted = &hash1;
1700 r.in.new_lm_crypted = &hash2;
1701 r.in.nt_present = 1;
1702 r.in.old_nt_crypted = &hash3;
1703 r.in.new_nt_crypted = &hash4;
1704 r.in.cross1_present = 1;
1705 /* Break the NT cross */
1707 r.in.nt_cross = &hash5;
1708 r.in.cross2_present = 1;
1709 r.in.lm_cross = &hash6;
1711 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1712 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1713 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status));
1717 /* Unbreak the NT cross */
1721 /* Reset the hashes to not broken values */
1722 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1723 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1724 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1725 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1726 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1727 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1729 r.in.user_handle = &user_handle;
1730 r.in.lm_present = 1;
1731 r.in.old_lm_crypted = &hash1;
1732 r.in.new_lm_crypted = &hash2;
1733 r.in.nt_present = 1;
1734 r.in.old_nt_crypted = &hash3;
1735 r.in.new_nt_crypted = &hash4;
1736 r.in.cross1_present = 1;
1737 r.in.nt_cross = &hash5;
1738 r.in.cross2_present = 0;
1739 r.in.lm_cross = NULL;
1741 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1742 if (NT_STATUS_IS_OK(status)) {
1744 *password = newpass;
1745 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1746 printf("ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(status));
1751 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1753 E_md4hash(oldpass, old_nt_hash);
1754 E_md4hash(newpass, new_nt_hash);
1755 E_deshash(oldpass, old_lm_hash);
1756 E_deshash(newpass, new_lm_hash);
1759 /* Reset the hashes to not broken values */
1760 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1761 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1762 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1763 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1764 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1765 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1767 r.in.user_handle = &user_handle;
1768 r.in.lm_present = 1;
1769 r.in.old_lm_crypted = &hash1;
1770 r.in.new_lm_crypted = &hash2;
1771 r.in.nt_present = 1;
1772 r.in.old_nt_crypted = &hash3;
1773 r.in.new_nt_crypted = &hash4;
1774 r.in.cross1_present = 0;
1775 r.in.nt_cross = NULL;
1776 r.in.cross2_present = 1;
1777 r.in.lm_cross = &hash6;
1779 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1780 if (NT_STATUS_IS_OK(status)) {
1782 *password = newpass;
1783 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1784 printf("ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status));
1789 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1791 E_md4hash(oldpass, old_nt_hash);
1792 E_md4hash(newpass, new_nt_hash);
1793 E_deshash(oldpass, old_lm_hash);
1794 E_deshash(newpass, new_lm_hash);
1797 /* Reset the hashes to not broken values */
1798 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1799 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1800 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1801 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1802 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1803 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1805 r.in.user_handle = &user_handle;
1806 r.in.lm_present = 1;
1807 r.in.old_lm_crypted = &hash1;
1808 r.in.new_lm_crypted = &hash2;
1809 r.in.nt_present = 1;
1810 r.in.old_nt_crypted = &hash3;
1811 r.in.new_nt_crypted = &hash4;
1812 r.in.cross1_present = 1;
1813 r.in.nt_cross = &hash5;
1814 r.in.cross2_present = 1;
1815 r.in.lm_cross = &hash6;
1817 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1818 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1819 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1820 } else if (!NT_STATUS_IS_OK(status)) {
1821 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1825 *password = newpass;
1828 r.in.user_handle = &user_handle;
1829 r.in.lm_present = 1;
1830 r.in.old_lm_crypted = &hash1;
1831 r.in.new_lm_crypted = &hash2;
1832 r.in.nt_present = 1;
1833 r.in.old_nt_crypted = &hash3;
1834 r.in.new_nt_crypted = &hash4;
1835 r.in.cross1_present = 1;
1836 r.in.nt_cross = &hash5;
1837 r.in.cross2_present = 1;
1838 r.in.lm_cross = &hash6;
1841 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1842 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1843 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1844 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1845 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status));
1851 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
1859 static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
1860 const char *acct_name,
1861 struct policy_handle *handle, char **password)
1864 struct samr_OemChangePasswordUser2 r;
1866 struct samr_Password lm_verifier;
1867 struct samr_CryptPassword lm_pass;
1868 struct lsa_AsciiString server, account, account_bad;
1871 uint8_t old_lm_hash[16], new_lm_hash[16];
1873 struct samr_GetDomPwInfo dom_pw_info;
1874 struct samr_PwInfo info;
1875 int policy_min_pw_len = 0;
1877 struct lsa_String domain_name;
1879 domain_name.string = "";
1880 dom_pw_info.in.domain_name = &domain_name;
1881 dom_pw_info.out.info = &info;
1883 torture_comment(tctx, "Testing OemChangePasswordUser2\n");
1885 torture_assert(tctx, *password != NULL,
1886 "Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?");
1888 oldpass = *password;
1890 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
1891 if (NT_STATUS_IS_OK(status)) {
1892 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
1895 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1897 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1898 account.string = acct_name;
1900 E_deshash(oldpass, old_lm_hash);
1901 E_deshash(newpass, new_lm_hash);
1903 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1904 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1905 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1907 r.in.server = &server;
1908 r.in.account = &account;
1909 r.in.password = &lm_pass;
1910 r.in.hash = &lm_verifier;
1912 /* Break the verification */
1913 lm_verifier.hash[0]++;
1915 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1917 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1918 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1919 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1924 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1925 /* Break the old password */
1927 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1928 /* unbreak it for the next operation */
1930 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1932 r.in.server = &server;
1933 r.in.account = &account;
1934 r.in.password = &lm_pass;
1935 r.in.hash = &lm_verifier;
1937 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1939 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1940 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1941 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1946 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1947 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1949 r.in.server = &server;
1950 r.in.account = &account;
1951 r.in.password = &lm_pass;
1954 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1956 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1957 && !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1958 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
1963 /* This shouldn't be a valid name */
1964 account_bad.string = TEST_ACCOUNT_NAME "XX";
1965 r.in.account = &account_bad;
1967 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1969 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1970 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
1975 /* This shouldn't be a valid name */
1976 account_bad.string = TEST_ACCOUNT_NAME "XX";
1977 r.in.account = &account_bad;
1978 r.in.password = &lm_pass;
1979 r.in.hash = &lm_verifier;
1981 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1983 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1984 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1989 /* This shouldn't be a valid name */
1990 account_bad.string = TEST_ACCOUNT_NAME "XX";
1991 r.in.account = &account_bad;
1992 r.in.password = NULL;
1993 r.in.hash = &lm_verifier;
1995 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1997 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1998 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
2003 E_deshash(oldpass, old_lm_hash);
2004 E_deshash(newpass, new_lm_hash);
2006 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
2007 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2008 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
2010 r.in.server = &server;
2011 r.in.account = &account;
2012 r.in.password = &lm_pass;
2013 r.in.hash = &lm_verifier;
2015 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
2016 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2017 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
2018 } else if (!NT_STATUS_IS_OK(status)) {
2019 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
2022 *password = newpass;
2029 static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
2030 const char *acct_name,
2032 char *newpass, bool allow_password_restriction)
2035 struct samr_ChangePasswordUser2 r;
2037 struct lsa_String server, account;
2038 struct samr_CryptPassword nt_pass, lm_pass;
2039 struct samr_Password nt_verifier, lm_verifier;
2041 uint8_t old_nt_hash[16], new_nt_hash[16];
2042 uint8_t old_lm_hash[16], new_lm_hash[16];
2044 struct samr_GetDomPwInfo dom_pw_info;
2045 struct samr_PwInfo info;
2047 struct lsa_String domain_name;
2049 domain_name.string = "";
2050 dom_pw_info.in.domain_name = &domain_name;
2051 dom_pw_info.out.info = &info;
2053 torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name);
2055 torture_assert(tctx, *password != NULL,
2056 "Failing ChangePasswordUser2 as old password was NULL. Previous test failed?");
2057 oldpass = *password;
2060 int policy_min_pw_len = 0;
2061 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
2062 if (NT_STATUS_IS_OK(status)) {
2063 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
2066 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2069 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2070 init_lsa_String(&account, acct_name);
2072 E_md4hash(oldpass, old_nt_hash);
2073 E_md4hash(newpass, new_nt_hash);
2075 E_deshash(oldpass, old_lm_hash);
2076 E_deshash(newpass, new_lm_hash);
2078 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
2079 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2080 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2082 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2083 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2084 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2086 r.in.server = &server;
2087 r.in.account = &account;
2088 r.in.nt_password = &nt_pass;
2089 r.in.nt_verifier = &nt_verifier;
2091 r.in.lm_password = &lm_pass;
2092 r.in.lm_verifier = &lm_verifier;
2094 status = dcerpc_samr_ChangePasswordUser2(p, tctx, &r);
2095 if (allow_password_restriction && NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2096 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
2097 } else if (!NT_STATUS_IS_OK(status)) {
2098 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
2101 *password = newpass;
2108 bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tctx,
2109 const char *account_string,
2110 int policy_min_pw_len,
2112 const char *newpass,
2113 NTTIME last_password_change,
2114 bool handle_reject_reason)
2117 struct samr_ChangePasswordUser3 r;
2119 struct lsa_String server, account, account_bad;
2120 struct samr_CryptPassword nt_pass, lm_pass;
2121 struct samr_Password nt_verifier, lm_verifier;
2123 uint8_t old_nt_hash[16], new_nt_hash[16];
2124 uint8_t old_lm_hash[16], new_lm_hash[16];
2126 struct samr_DomInfo1 *dominfo = NULL;
2127 struct samr_ChangeReject *reject = NULL;
2129 torture_comment(tctx, "Testing ChangePasswordUser3\n");
2131 if (newpass == NULL) {
2133 if (policy_min_pw_len == 0) {
2134 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2136 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len);
2138 } while (check_password_quality(newpass) == false);
2140 torture_comment(tctx, "Using password '%s'\n", newpass);
2143 torture_assert(tctx, *password != NULL,
2144 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2146 oldpass = *password;
2147 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2148 init_lsa_String(&account, account_string);
2150 E_md4hash(oldpass, old_nt_hash);
2151 E_md4hash(newpass, new_nt_hash);
2153 E_deshash(oldpass, old_lm_hash);
2154 E_deshash(newpass, new_lm_hash);
2156 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2157 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2158 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2160 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2161 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2162 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2164 /* Break the verification */
2165 nt_verifier.hash[0]++;
2167 r.in.server = &server;
2168 r.in.account = &account;
2169 r.in.nt_password = &nt_pass;
2170 r.in.nt_verifier = &nt_verifier;
2172 r.in.lm_password = &lm_pass;
2173 r.in.lm_verifier = &lm_verifier;
2174 r.in.password3 = NULL;
2175 r.out.dominfo = &dominfo;
2176 r.out.reject = &reject;
2178 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2179 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
2180 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
2181 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
2186 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2187 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2188 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2190 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2191 /* Break the NT hash */
2193 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2194 /* Unbreak it again */
2196 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2198 r.in.server = &server;
2199 r.in.account = &account;
2200 r.in.nt_password = &nt_pass;
2201 r.in.nt_verifier = &nt_verifier;
2203 r.in.lm_password = &lm_pass;
2204 r.in.lm_verifier = &lm_verifier;
2205 r.in.password3 = NULL;
2206 r.out.dominfo = &dominfo;
2207 r.out.reject = &reject;
2209 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2210 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
2211 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
2212 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
2217 /* This shouldn't be a valid name */
2218 init_lsa_String(&account_bad, talloc_asprintf(tctx, "%sXX", account_string));
2220 r.in.account = &account_bad;
2221 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2222 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
2223 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
2228 E_md4hash(oldpass, old_nt_hash);
2229 E_md4hash(newpass, new_nt_hash);
2231 E_deshash(oldpass, old_lm_hash);
2232 E_deshash(newpass, new_lm_hash);
2234 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2235 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2236 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2238 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2239 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2240 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2242 r.in.server = &server;
2243 r.in.account = &account;
2244 r.in.nt_password = &nt_pass;
2245 r.in.nt_verifier = &nt_verifier;
2247 r.in.lm_password = &lm_pass;
2248 r.in.lm_verifier = &lm_verifier;
2249 r.in.password3 = NULL;
2250 r.out.dominfo = &dominfo;
2251 r.out.reject = &reject;
2253 unix_to_nt_time(&t, time(NULL));
2255 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2257 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
2260 && handle_reject_reason
2261 && (!null_nttime(last_password_change) || !dominfo->min_password_age)) {
2262 if (dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
2264 if (reject && (reject->reason != SAMR_REJECT_OTHER)) {
2265 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2266 SAMR_REJECT_OTHER, reject->reason);
2271 /* We tested the order of precendence which is as follows:
2280 if ((dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
2281 (last_password_change + dominfo->min_password_age > t)) {
2283 if (reject->reason != SAMR_REJECT_OTHER) {
2284 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2285 SAMR_REJECT_OTHER, reject->reason);
2289 } else if ((dominfo->min_password_length > 0) &&
2290 (strlen(newpass) < dominfo->min_password_length)) {
2292 if (reject->reason != SAMR_REJECT_TOO_SHORT) {
2293 printf("expected SAMR_REJECT_TOO_SHORT (%d), got %d\n",
2294 SAMR_REJECT_TOO_SHORT, reject->reason);
2298 } else if ((dominfo->password_history_length > 0) &&
2299 strequal(oldpass, newpass)) {
2301 if (reject->reason != SAMR_REJECT_IN_HISTORY) {
2302 printf("expected SAMR_REJECT_IN_HISTORY (%d), got %d\n",
2303 SAMR_REJECT_IN_HISTORY, reject->reason);
2306 } else if (dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
2308 if (reject->reason != SAMR_REJECT_COMPLEXITY) {
2309 printf("expected SAMR_REJECT_COMPLEXITY (%d), got %d\n",
2310 SAMR_REJECT_COMPLEXITY, reject->reason);
2316 if (reject->reason == SAMR_REJECT_TOO_SHORT) {
2317 /* retry with adjusted size */
2318 return test_ChangePasswordUser3(p, tctx, account_string,
2319 dominfo->min_password_length,
2320 password, NULL, 0, false);
2324 } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2325 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2326 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2327 SAMR_REJECT_OTHER, reject->reason);
2330 /* Perhaps the server has a 'min password age' set? */
2333 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3");
2334 *password = talloc_strdup(tctx, newpass);
2340 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_context *tctx,
2341 const char *account_string,
2342 struct policy_handle *handle,
2346 struct samr_ChangePasswordUser3 r;
2347 struct samr_SetUserInfo s;
2348 union samr_UserInfo u;
2349 DATA_BLOB session_key;
2350 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
2351 uint8_t confounder[16];
2352 struct MD5Context ctx;
2355 struct lsa_String server, account;
2356 struct samr_CryptPassword nt_pass;
2357 struct samr_Password nt_verifier;
2358 DATA_BLOB new_random_pass;
2361 uint8_t old_nt_hash[16], new_nt_hash[16];
2363 struct samr_DomInfo1 *dominfo = NULL;
2364 struct samr_ChangeReject *reject = NULL;
2366 new_random_pass = samr_very_rand_pass(tctx, 128);
2368 torture_assert(tctx, *password != NULL,
2369 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2371 oldpass = *password;
2372 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2373 init_lsa_String(&account, account_string);
2375 s.in.user_handle = handle;
2381 u.info25.info.fields_present = SAMR_FIELD_NT_PASSWORD_PRESENT;
2383 set_pw_in_buffer(u.info25.password.data, &new_random_pass);
2385 status = dcerpc_fetch_session_key(p, &session_key);
2386 if (!NT_STATUS_IS_OK(status)) {
2387 printf("SetUserInfo level %u - no session key - %s\n",
2388 s.in.level, nt_errstr(status));
2392 generate_random_buffer((uint8_t *)confounder, 16);
2395 MD5Update(&ctx, confounder, 16);
2396 MD5Update(&ctx, session_key.data, session_key.length);
2397 MD5Final(confounded_session_key.data, &ctx);
2399 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
2400 memcpy(&u.info25.password.data[516], confounder, 16);
2402 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
2404 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
2405 if (!NT_STATUS_IS_OK(status)) {
2406 printf("SetUserInfo level %u failed - %s\n",
2407 s.in.level, nt_errstr(status));
2411 torture_comment(tctx, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
2413 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2415 new_random_pass = samr_very_rand_pass(tctx, 128);
2417 mdfour(new_nt_hash, new_random_pass.data, new_random_pass.length);
2419 set_pw_in_buffer(nt_pass.data, &new_random_pass);
2420 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2421 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2423 r.in.server = &server;
2424 r.in.account = &account;
2425 r.in.nt_password = &nt_pass;
2426 r.in.nt_verifier = &nt_verifier;
2428 r.in.lm_password = NULL;
2429 r.in.lm_verifier = NULL;
2430 r.in.password3 = NULL;
2431 r.out.dominfo = &dominfo;
2432 r.out.reject = &reject;
2434 unix_to_nt_time(&t, time(NULL));
2436 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2438 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2439 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2440 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2441 SAMR_REJECT_OTHER, reject->reason);
2444 /* Perhaps the server has a 'min password age' set? */
2446 } else if (!NT_STATUS_IS_OK(status)) {
2447 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
2451 newpass = samr_rand_pass(tctx, 128);
2453 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2455 E_md4hash(newpass, new_nt_hash);
2457 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2458 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2459 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2461 r.in.server = &server;
2462 r.in.account = &account;
2463 r.in.nt_password = &nt_pass;
2464 r.in.nt_verifier = &nt_verifier;
2466 r.in.lm_password = NULL;
2467 r.in.lm_verifier = NULL;
2468 r.in.password3 = NULL;
2469 r.out.dominfo = &dominfo;
2470 r.out.reject = &reject;
2472 unix_to_nt_time(&t, time(NULL));
2474 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2476 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2477 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2478 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2479 SAMR_REJECT_OTHER, reject->reason);
2482 /* Perhaps the server has a 'min password age' set? */
2485 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3 (on second random password)");
2486 *password = talloc_strdup(tctx, newpass);
2493 static bool test_GetMembersInAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2494 struct policy_handle *alias_handle)
2496 struct samr_GetMembersInAlias r;
2497 struct lsa_SidArray sids;
2500 torture_comment(tctx, "Testing GetMembersInAlias\n");
2502 r.in.alias_handle = alias_handle;
2505 status = dcerpc_samr_GetMembersInAlias(p, tctx, &r);
2506 torture_assert_ntstatus_ok(tctx, status, "GetMembersInAlias");
2511 static bool test_AddMemberToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2512 struct policy_handle *alias_handle,
2513 const struct dom_sid *domain_sid)
2515 struct samr_AddAliasMember r;
2516 struct samr_DeleteAliasMember d;
2518 struct dom_sid *sid;
2520 sid = dom_sid_add_rid(tctx, domain_sid, 512);
2522 torture_comment(tctx, "testing AddAliasMember\n");
2523 r.in.alias_handle = alias_handle;
2526 status = dcerpc_samr_AddAliasMember(p, tctx, &r);
2527 torture_assert_ntstatus_ok(tctx, status, "AddAliasMember");
2529 d.in.alias_handle = alias_handle;
2532 status = dcerpc_samr_DeleteAliasMember(p, tctx, &d);
2533 torture_assert_ntstatus_ok(tctx, status, "DelAliasMember");
2538 static bool test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2539 struct policy_handle *alias_handle)
2541 struct samr_AddMultipleMembersToAlias a;
2542 struct samr_RemoveMultipleMembersFromAlias r;
2544 struct lsa_SidArray sids;
2546 torture_comment(tctx, "testing AddMultipleMembersToAlias\n");
2547 a.in.alias_handle = alias_handle;
2551 sids.sids = talloc_array(tctx, struct lsa_SidPtr, 3);
2553 sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2554 sids.sids[1].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-2");
2555 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-3");
2557 status = dcerpc_samr_AddMultipleMembersToAlias(p, tctx, &a);
2558 torture_assert_ntstatus_ok(tctx, status, "AddMultipleMembersToAlias");
2561 torture_comment(tctx, "testing RemoveMultipleMembersFromAlias\n");
2562 r.in.alias_handle = alias_handle;
2565 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2566 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2568 /* strange! removing twice doesn't give any error */
2569 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2570 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2572 /* but removing an alias that isn't there does */
2573 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-4");
2575 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2576 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, "RemoveMultipleMembersFromAlias");
2581 static bool test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2582 struct policy_handle *user_handle)
2584 struct samr_TestPrivateFunctionsUser r;
2587 torture_comment(tctx, "Testing TestPrivateFunctionsUser\n");
2589 r.in.user_handle = user_handle;
2591 status = dcerpc_samr_TestPrivateFunctionsUser(p, tctx, &r);
2592 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsUser");
2597 static bool test_QueryUserInfo_pwdlastset(struct dcerpc_pipe *p,
2598 struct torture_context *tctx,
2599 struct policy_handle *handle,
2604 uint16_t levels[] = { /* 3, */ 5, 21 };
2606 NTTIME pwdlastset3 = 0;
2607 NTTIME pwdlastset5 = 0;
2608 NTTIME pwdlastset21 = 0;
2610 torture_comment(tctx, "Testing QueryUserInfo%s level 5 and 21 call ",
2611 use_info2 ? "2":"");
2613 for (i=0; i<ARRAY_SIZE(levels); i++) {
2615 struct samr_QueryUserInfo r;
2616 struct samr_QueryUserInfo2 r2;
2617 union samr_UserInfo *info;
2620 r2.in.user_handle = handle;
2621 r2.in.level = levels[i];
2622 r2.out.info = &info;
2623 status = dcerpc_samr_QueryUserInfo2(p, tctx, &r2);
2626 r.in.user_handle = handle;
2627 r.in.level = levels[i];
2629 status = dcerpc_samr_QueryUserInfo(p, tctx, &r);
2632 if (!NT_STATUS_IS_OK(status) &&
2633 !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
2634 printf("QueryUserInfo%s level %u failed - %s\n",
2635 use_info2 ? "2":"", levels[i], nt_errstr(status));
2639 switch (levels[i]) {
2641 pwdlastset3 = info->info3.last_password_change;
2644 pwdlastset5 = info->info5.last_password_change;
2647 pwdlastset21 = info->info21.last_password_change;
2653 /* torture_assert_int_equal(tctx, pwdlastset3, pwdlastset5,
2654 "pwdlastset mixup"); */
2655 torture_assert_int_equal(tctx, pwdlastset5, pwdlastset21,
2656 "pwdlastset mixup");
2658 *pwdlastset = pwdlastset21;
2660 torture_comment(tctx, "(pwdlastset: %lld)\n", *pwdlastset);
2665 static bool test_SamLogon_Creds(struct dcerpc_pipe *p, struct torture_context *tctx,
2666 struct cli_credentials *machine_credentials,
2667 struct cli_credentials *test_credentials,
2668 struct netlogon_creds_CredentialState *creds,
2669 NTSTATUS expected_result)
2672 struct netr_LogonSamLogon r;
2673 struct netr_Authenticator auth, auth2;
2674 union netr_LogonLevel logon;
2675 union netr_Validation validation;
2676 uint8_t authoritative;
2677 struct netr_NetworkInfo ninfo;
2678 DATA_BLOB names_blob, chal, lm_resp, nt_resp;
2679 int flags = CLI_CRED_NTLM_AUTH;
2681 if (lp_client_lanman_auth(tctx->lp_ctx)) {
2682 flags |= CLI_CRED_LANMAN_AUTH;
2685 if (lp_client_ntlmv2_auth(tctx->lp_ctx)) {
2686 flags |= CLI_CRED_NTLMv2_AUTH;
2689 cli_credentials_get_ntlm_username_domain(test_credentials, tctx,
2690 &ninfo.identity_info.account_name.string,
2691 &ninfo.identity_info.domain_name.string);
2693 generate_random_buffer(ninfo.challenge,
2694 sizeof(ninfo.challenge));
2695 chal = data_blob_const(ninfo.challenge,
2696 sizeof(ninfo.challenge));
2698 names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(machine_credentials),
2699 cli_credentials_get_domain(machine_credentials));
2701 status = cli_credentials_get_ntlm_response(test_credentials, tctx,
2707 torture_assert_ntstatus_ok(tctx, status, "cli_credentials_get_ntlm_response failed");
2709 ninfo.lm.data = lm_resp.data;
2710 ninfo.lm.length = lm_resp.length;
2712 ninfo.nt.data = nt_resp.data;
2713 ninfo.nt.length = nt_resp.length;
2715 ninfo.identity_info.parameter_control =
2716 MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT |
2717 MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;
2718 ninfo.identity_info.logon_id_low = 0;
2719 ninfo.identity_info.logon_id_high = 0;
2720 ninfo.identity_info.workstation.string = cli_credentials_get_workstation(machine_credentials);
2722 logon.network = &ninfo;
2724 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2725 r.in.computer_name = cli_credentials_get_workstation(machine_credentials);
2726 r.in.credential = &auth;
2727 r.in.return_authenticator = &auth2;
2728 r.in.logon_level = 2;
2729 r.in.logon = &logon;
2730 r.out.validation = &validation;
2731 r.out.authoritative = &authoritative;
2733 d_printf("Testing LogonSamLogon with name %s\n", ninfo.identity_info.account_name.string);
2736 netlogon_creds_client_authenticator(creds, &auth);
2738 r.in.validation_level = 2;
2740 status = dcerpc_netr_LogonSamLogon(p, tctx, &r);
2741 if (!NT_STATUS_IS_OK(status)) {
2742 torture_assert_ntstatus_equal(tctx, status, expected_result, "LogonSamLogon failed");
2745 torture_assert_ntstatus_ok(tctx, status, "LogonSamLogon failed");
2748 torture_assert(tctx, netlogon_creds_client_check(creds, &r.out.return_authenticator->cred),
2749 "Credential chaining failed");
2754 static bool test_SamLogon(struct torture_context *tctx,
2755 struct dcerpc_pipe *p,
2756 struct cli_credentials *machine_credentials,
2757 struct cli_credentials *test_credentials,
2758 NTSTATUS expected_result)
2760 struct netlogon_creds_CredentialState *creds;
2762 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
2766 return test_SamLogon_Creds(p, tctx, machine_credentials, test_credentials,
2767 creds, expected_result);
2770 static bool test_SamLogon_with_creds(struct torture_context *tctx,
2771 struct dcerpc_pipe *p,
2772 struct cli_credentials *machine_creds,
2773 const char *acct_name,
2775 NTSTATUS expected_samlogon_result)
2778 struct cli_credentials *test_credentials;
2780 test_credentials = cli_credentials_init(tctx);
2782 cli_credentials_set_workstation(test_credentials,
2783 TEST_ACCOUNT_NAME_PWD, CRED_SPECIFIED);
2784 cli_credentials_set_domain(test_credentials,
2785 lp_workgroup(tctx->lp_ctx), CRED_SPECIFIED);
2786 cli_credentials_set_username(test_credentials,
2787 acct_name, CRED_SPECIFIED);
2788 cli_credentials_set_password(test_credentials,
2789 password, CRED_SPECIFIED);
2790 cli_credentials_set_secure_channel_type(test_credentials, SEC_CHAN_BDC);
2792 printf("testing samlogon as %s@%s password: %s\n",
2793 acct_name, TEST_ACCOUNT_NAME_PWD, password);
2795 if (!test_SamLogon(tctx, p, machine_creds, test_credentials,
2796 expected_samlogon_result)) {
2797 torture_warning(tctx, "new password did not work\n");
2804 static bool test_SetPassword_level(struct dcerpc_pipe *p,
2805 struct dcerpc_pipe *np,
2806 struct torture_context *tctx,
2807 struct policy_handle *handle,
2809 uint32_t fields_present,
2810 uint8_t password_expired,
2811 bool *matched_expected_error,
2813 const char *acct_name,
2815 struct cli_credentials *machine_creds,
2816 bool use_queryinfo2,
2818 NTSTATUS expected_samlogon_result)
2820 const char *fields = NULL;
2827 fields = talloc_asprintf(tctx, "(fields_present: 0x%08x)",
2834 torture_comment(tctx, "Testing SetUserInfo%s level %d call "
2835 "(password_expired: %d) %s\n",
2836 use_setinfo2 ? "2":"", level, password_expired,
2837 fields ? fields : "");
2839 if (!test_SetUserPass_level_ex(p, tctx, handle, level,
2844 matched_expected_error)) {
2848 if (!test_QueryUserInfo_pwdlastset(p, tctx, handle,
2854 if (*matched_expected_error == true) {
2858 if (!test_SamLogon_with_creds(tctx, np,
2862 expected_samlogon_result)) {
2869 static bool test_SetPassword_pwdlastset(struct dcerpc_pipe *p,
2870 struct torture_context *tctx,
2871 uint32_t acct_flags,
2872 const char *acct_name,
2873 struct policy_handle *handle,
2875 struct cli_credentials *machine_credentials)
2877 int s = 0, q = 0, f = 0, l = 0, z = 0;
2880 bool set_levels[] = { false, true };
2881 bool query_levels[] = { false, true };
2882 uint32_t levels[] = { 18, 21, 23, 24, 25, 26 };
2883 uint32_t nonzeros[] = { 1, 24 };
2884 uint32_t fields_present[] = {
2886 SAMR_FIELD_EXPIRED_FLAG,
2887 SAMR_FIELD_LAST_PWD_CHANGE,
2888 SAMR_FIELD_EXPIRED_FLAG | SAMR_FIELD_LAST_PWD_CHANGE,
2890 SAMR_FIELD_NT_PASSWORD_PRESENT,
2891 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
2892 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
2893 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
2894 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
2895 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
2896 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE | SAMR_FIELD_EXPIRED_FLAG
2899 struct dcerpc_pipe *np = NULL;
2901 if (torture_setting_bool(tctx, "samba3", false)) {
2903 printf("Samba3 has second granularity, setting delay to: %d\n",
2907 status = torture_rpc_connection(tctx, &np, &ndr_table_netlogon);
2908 if (!NT_STATUS_IS_OK(status)) {
2912 /* set to 1 to enable testing for all possible opcode
2913 (SetUserInfo, SetUserInfo2, QueryUserInfo, QueryUserInfo2)
2916 #define TEST_SET_LEVELS 1
2917 #define TEST_QUERY_LEVELS 1
2919 for (l=0; l<ARRAY_SIZE(levels); l++) {
2920 for (z=0; z<ARRAY_SIZE(nonzeros); z++) {
2921 for (f=0; f<ARRAY_SIZE(fields_present); f++) {
2922 #ifdef TEST_SET_LEVELS
2923 for (s=0; s<ARRAY_SIZE(set_levels); s++) {
2925 #ifdef TEST_QUERY_LEVELS
2926 for (q=0; q<ARRAY_SIZE(query_levels); q++) {
2928 NTTIME pwdlastset_old = 0;
2929 NTTIME pwdlastset_new = 0;
2930 bool matched_expected_error = false;
2931 NTSTATUS expected_samlogon_result = NT_STATUS_ACCOUNT_DISABLED;
2933 torture_comment(tctx, "------------------------------\n"
2934 "Testing pwdLastSet attribute for flags: 0x%08x "
2935 "(s: %d (l: %d), q: %d)\n",
2936 acct_flags, s, levels[l], q);
2938 switch (levels[l]) {
2942 if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
2943 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT))) {
2944 expected_samlogon_result = NT_STATUS_WRONG_PASSWORD;
2952 /* set a password and force password change (pwdlastset 0) by
2953 * setting the password expired flag to a non-0 value */
2955 if (!test_SetPassword_level(p, np, tctx, handle,
2959 &matched_expected_error,
2963 machine_credentials,
2966 expected_samlogon_result)) {
2970 if (matched_expected_error == true) {
2971 /* skipping on expected failure */
2975 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
2976 * set without the SAMR_FIELD_EXPIRED_FLAG */
2978 switch (levels[l]) {
2982 if ((pwdlastset_new != 0) &&
2983 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
2984 torture_comment(tctx, "not considering a non-0 "
2985 "pwdLastSet as a an error as the "
2986 "SAMR_FIELD_EXPIRED_FLAG has not "
2991 if (pwdlastset_new != 0) {
2992 torture_warning(tctx, "pwdLastSet test failed: "
2993 "expected pwdLastSet 0 but got %lld\n",
3000 switch (levels[l]) {
3004 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3005 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3006 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3007 (pwdlastset_old >= pwdlastset_new)) {
3008 torture_warning(tctx, "pwdlastset not increasing\n");
3013 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3014 (pwdlastset_old >= pwdlastset_new)) {
3015 torture_warning(tctx, "pwdlastset not increasing\n");
3025 /* set a password, pwdlastset needs to get updated (increased
3026 * value), password_expired value used here is 0 */
3028 if (!test_SetPassword_level(p, np, tctx, handle,
3032 &matched_expected_error,
3036 machine_credentials,
3039 expected_samlogon_result)) {
3043 /* when a password has been changed, pwdlastset must not be 0 afterwards
3044 * and must be larger then the old value */
3046 switch (levels[l]) {
3051 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3052 * password has been changed, old and new pwdlastset
3053 * need to be the same value */
3055 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3056 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3057 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3059 torture_assert_int_equal(tctx, pwdlastset_old,
3060 pwdlastset_new, "pwdlastset must be equal");
3064 if (pwdlastset_old >= pwdlastset_new) {
3065 torture_warning(tctx, "pwdLastSet test failed: "
3066 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
3067 pwdlastset_old, pwdlastset_new);
3070 if (pwdlastset_new == 0) {
3071 torture_warning(tctx, "pwdLastSet test failed: "
3072 "expected non-0 pwdlastset, got: %lld\n",
3078 switch (levels[l]) {
3082 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3083 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3084 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3085 (pwdlastset_old >= pwdlastset_new)) {
3086 torture_warning(tctx, "pwdlastset not increasing\n");
3091 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3092 (pwdlastset_old >= pwdlastset_new)) {
3093 torture_warning(tctx, "pwdlastset not increasing\n");
3099 pwdlastset_old = pwdlastset_new;
3105 /* set a password, pwdlastset needs to get updated (increased
3106 * value), password_expired value used here is 0 */
3108 if (!test_SetPassword_level(p, np, tctx, handle,
3112 &matched_expected_error,
3116 machine_credentials,
3119 expected_samlogon_result)) {
3123 /* when a password has been changed, pwdlastset must not be 0 afterwards
3124 * and must be larger then the old value */
3126 switch (levels[l]) {
3131 /* if no password has been changed, old and new pwdlastset
3132 * need to be the same value */
3134 if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3135 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3137 torture_assert_int_equal(tctx, pwdlastset_old,
3138 pwdlastset_new, "pwdlastset must be equal");
3142 if (pwdlastset_old >= pwdlastset_new) {
3143 torture_warning(tctx, "pwdLastSet test failed: "
3144 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
3145 pwdlastset_old, pwdlastset_new);
3148 if (pwdlastset_new == 0) {
3149 torture_warning(tctx, "pwdLastSet test failed: "
3150 "expected non-0 pwdlastset, got: %lld\n",
3158 /* set a password and force password change (pwdlastset 0) by
3159 * setting the password expired flag to a non-0 value */