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, TALLOC_CTX *mem_ctx,
52 struct policy_handle *handle);
54 static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
55 struct policy_handle *handle);
57 static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
58 struct policy_handle *handle);
60 static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
61 const char *acct_name,
62 struct policy_handle *domain_handle, char **password);
64 static void init_lsa_String(struct lsa_String *string, const char *s)
69 static void init_lsa_BinaryString(struct lsa_BinaryString *string, const char *s, uint32_t length)
71 string->length = length;
72 string->size = length;
73 string->array = (uint16_t *)discard_const(s);
76 bool test_samr_handle_Close(struct dcerpc_pipe *p, struct torture_context *tctx,
77 struct policy_handle *handle)
83 r.out.handle = handle;
85 status = dcerpc_samr_Close(p, tctx, &r);
86 torture_assert_ntstatus_ok(tctx, status, "Close");
91 static bool test_Shutdown(struct dcerpc_pipe *p, struct torture_context *tctx,
92 struct policy_handle *handle)
95 struct samr_Shutdown r;
97 if (!torture_setting_bool(tctx, "dangerous", false)) {
98 torture_skip(tctx, "samr_Shutdown disabled - enable dangerous tests to use\n");
102 r.in.connect_handle = handle;
104 torture_comment(tctx, "testing samr_Shutdown\n");
106 status = dcerpc_samr_Shutdown(p, tctx, &r);
107 torture_assert_ntstatus_ok(tctx, status, "samr_Shutdown");
112 static bool test_SetDsrmPassword(struct dcerpc_pipe *p, struct torture_context *tctx,
113 struct policy_handle *handle)
116 struct samr_SetDsrmPassword r;
117 struct lsa_String string;
118 struct samr_Password hash;
120 if (!torture_setting_bool(tctx, "dangerous", false)) {
121 torture_skip(tctx, "samr_SetDsrmPassword disabled - enable dangerous tests to use");
124 E_md4hash("TeSTDSRM123", hash.hash);
126 init_lsa_String(&string, "Administrator");
132 torture_comment(tctx, "testing samr_SetDsrmPassword\n");
134 status = dcerpc_samr_SetDsrmPassword(p, tctx, &r);
135 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_SUPPORTED, "samr_SetDsrmPassword");
141 static bool test_QuerySecurity(struct dcerpc_pipe *p,
142 struct torture_context *tctx,
143 struct policy_handle *handle)
146 struct samr_QuerySecurity r;
147 struct samr_SetSecurity s;
148 struct sec_desc_buf *sdbuf = NULL;
150 r.in.handle = handle;
152 r.out.sdbuf = &sdbuf;
154 status = dcerpc_samr_QuerySecurity(p, tctx, &r);
155 torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
157 torture_assert(tctx, sdbuf != NULL, "sdbuf is NULL");
159 s.in.handle = handle;
163 if (torture_setting_bool(tctx, "samba4", false)) {
164 torture_skip(tctx, "skipping SetSecurity test against Samba4\n");
167 status = dcerpc_samr_SetSecurity(p, tctx, &s);
168 torture_assert_ntstatus_ok(tctx, status, "SetSecurity");
170 status = dcerpc_samr_QuerySecurity(p, tctx, &r);
171 torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
177 static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
178 struct policy_handle *handle, uint32_t base_acct_flags,
179 const char *base_account_name)
182 struct samr_SetUserInfo s;
183 struct samr_SetUserInfo2 s2;
184 struct samr_QueryUserInfo q;
185 struct samr_QueryUserInfo q0;
186 union samr_UserInfo u;
187 union samr_UserInfo *info;
189 const char *test_account_name;
191 uint32_t user_extra_flags = 0;
192 if (base_acct_flags == ACB_NORMAL) {
193 /* When created, accounts are expired by default */
194 user_extra_flags = ACB_PW_EXPIRED;
197 s.in.user_handle = handle;
200 s2.in.user_handle = handle;
203 q.in.user_handle = handle;
207 #define TESTCALL(call, r) \
208 status = dcerpc_samr_ ##call(p, tctx, &r); \
209 if (!NT_STATUS_IS_OK(status)) { \
210 torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
211 r.in.level, nt_errstr(status), __location__); \
216 #define STRING_EQUAL(s1, s2, field) \
217 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
218 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
219 #field, s2, __location__); \
224 #define MEM_EQUAL(s1, s2, length, field) \
225 if ((s1 && !s2) || (s2 && !s1) || memcmp(s1, s2, length)) { \
226 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
227 #field, (const char *)s2, __location__); \
232 #define INT_EQUAL(i1, i2, field) \
234 torture_comment(tctx, "Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \
235 #field, (unsigned long long)i2, (unsigned long long)i1, __location__); \
240 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
241 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
243 TESTCALL(QueryUserInfo, q) \
245 s2.in.level = lvl1; \
248 ZERO_STRUCT(u.info21); \
249 u.info21.fields_present = fpval; \
251 init_lsa_String(&u.info ## lvl1.field1, value); \
252 TESTCALL(SetUserInfo, s) \
253 TESTCALL(SetUserInfo2, s2) \
254 init_lsa_String(&u.info ## lvl1.field1, ""); \
255 TESTCALL(QueryUserInfo, q); \
257 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
259 TESTCALL(QueryUserInfo, q) \
261 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
264 #define TEST_USERINFO_BINARYSTRING(lvl1, field1, lvl2, field2, value, fpval) do { \
265 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
267 TESTCALL(QueryUserInfo, q) \
269 s2.in.level = lvl1; \
272 ZERO_STRUCT(u.info21); \
273 u.info21.fields_present = fpval; \
275 init_lsa_BinaryString(&u.info ## lvl1.field1, value, strlen(value)); \
276 TESTCALL(SetUserInfo, s) \
277 TESTCALL(SetUserInfo2, s2) \
278 init_lsa_BinaryString(&u.info ## lvl1.field1, "", 1); \
279 TESTCALL(QueryUserInfo, q); \
281 MEM_EQUAL(u.info ## lvl1.field1.array, value, strlen(value), field1); \
283 TESTCALL(QueryUserInfo, q) \
285 MEM_EQUAL(u.info ## lvl2.field2.array, value, strlen(value), field2); \
288 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
289 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
291 TESTCALL(QueryUserInfo, q) \
293 s2.in.level = lvl1; \
296 uint8_t *bits = u.info21.logon_hours.bits; \
297 ZERO_STRUCT(u.info21); \
298 if (fpval == SAMR_FIELD_LOGON_HOURS) { \
299 u.info21.logon_hours.units_per_week = 168; \
300 u.info21.logon_hours.bits = bits; \
302 u.info21.fields_present = fpval; \
304 u.info ## lvl1.field1 = value; \
305 TESTCALL(SetUserInfo, s) \
306 TESTCALL(SetUserInfo2, s2) \
307 u.info ## lvl1.field1 = 0; \
308 TESTCALL(QueryUserInfo, q); \
310 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
312 TESTCALL(QueryUserInfo, q) \
314 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
317 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
318 TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
322 do { TESTCALL(QueryUserInfo, q0) } while (0);
324 /* Samba 3 cannot store comment fields atm. - gd */
325 if (!torture_setting_bool(tctx, "samba3", false)) {
326 TEST_USERINFO_STRING(2, comment, 1, comment, "xx2-1 comment", 0);
327 TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
328 TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment",
332 test_account_name = talloc_asprintf(tctx, "%sxx7-1", base_account_name);
333 TEST_USERINFO_STRING(7, account_name, 1, account_name, base_account_name, 0);
334 test_account_name = talloc_asprintf(tctx, "%sxx7-3", base_account_name);
335 TEST_USERINFO_STRING(7, account_name, 3, account_name, base_account_name, 0);
336 test_account_name = talloc_asprintf(tctx, "%sxx7-5", base_account_name);
337 TEST_USERINFO_STRING(7, account_name, 5, account_name, base_account_name, 0);
338 test_account_name = talloc_asprintf(tctx, "%sxx7-6", base_account_name);
339 TEST_USERINFO_STRING(7, account_name, 6, account_name, base_account_name, 0);
340 test_account_name = talloc_asprintf(tctx, "%sxx7-7", base_account_name);
341 TEST_USERINFO_STRING(7, account_name, 7, account_name, base_account_name, 0);
342 test_account_name = talloc_asprintf(tctx, "%sxx7-21", base_account_name);
343 TEST_USERINFO_STRING(7, account_name, 21, account_name, base_account_name, 0);
344 test_account_name = base_account_name;
345 TEST_USERINFO_STRING(21, account_name, 21, account_name, base_account_name,
346 SAMR_FIELD_ACCOUNT_NAME);
348 TEST_USERINFO_STRING(6, full_name, 1, full_name, "xx6-1 full_name", 0);
349 TEST_USERINFO_STRING(6, full_name, 3, full_name, "xx6-3 full_name", 0);
350 TEST_USERINFO_STRING(6, full_name, 5, full_name, "xx6-5 full_name", 0);
351 TEST_USERINFO_STRING(6, full_name, 6, full_name, "xx6-6 full_name", 0);
352 TEST_USERINFO_STRING(6, full_name, 8, full_name, "xx6-8 full_name", 0);
353 TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
354 TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
355 TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name",
356 SAMR_FIELD_FULL_NAME);
358 TEST_USERINFO_STRING(6, full_name, 1, full_name, "", 0);
359 TEST_USERINFO_STRING(6, full_name, 3, full_name, "", 0);
360 TEST_USERINFO_STRING(6, full_name, 5, full_name, "", 0);
361 TEST_USERINFO_STRING(6, full_name, 6, full_name, "", 0);
362 TEST_USERINFO_STRING(6, full_name, 8, full_name, "", 0);
363 TEST_USERINFO_STRING(6, full_name, 21, full_name, "", 0);
364 TEST_USERINFO_STRING(8, full_name, 21, full_name, "", 0);
365 TEST_USERINFO_STRING(21, full_name, 21, full_name, "",
366 SAMR_FIELD_FULL_NAME);
368 TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
369 TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
370 TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
371 TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script",
372 SAMR_FIELD_LOGON_SCRIPT);
374 TEST_USERINFO_STRING(12, profile_path, 3, profile_path, "xx12-3 profile_path", 0);
375 TEST_USERINFO_STRING(12, profile_path, 5, profile_path, "xx12-5 profile_path", 0);
376 TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
377 TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path",
378 SAMR_FIELD_PROFILE_PATH);
380 TEST_USERINFO_STRING(10, home_directory, 3, home_directory, "xx10-3 home_directory", 0);
381 TEST_USERINFO_STRING(10, home_directory, 5, home_directory, "xx10-5 home_directory", 0);
382 TEST_USERINFO_STRING(10, home_directory, 21, home_directory, "xx10-21 home_directory", 0);
383 TEST_USERINFO_STRING(21, home_directory, 21, home_directory, "xx21-21 home_directory",
384 SAMR_FIELD_HOME_DIRECTORY);
385 TEST_USERINFO_STRING(21, home_directory, 10, home_directory, "xx21-10 home_directory",
386 SAMR_FIELD_HOME_DIRECTORY);
388 TEST_USERINFO_STRING(10, home_drive, 3, home_drive, "xx10-3 home_drive", 0);
389 TEST_USERINFO_STRING(10, home_drive, 5, home_drive, "xx10-5 home_drive", 0);
390 TEST_USERINFO_STRING(10, home_drive, 21, home_drive, "xx10-21 home_drive", 0);
391 TEST_USERINFO_STRING(21, home_drive, 21, home_drive, "xx21-21 home_drive",
392 SAMR_FIELD_HOME_DRIVE);
393 TEST_USERINFO_STRING(21, home_drive, 10, home_drive, "xx21-10 home_drive",
394 SAMR_FIELD_HOME_DRIVE);
396 TEST_USERINFO_STRING(13, description, 1, description, "xx13-1 description", 0);
397 TEST_USERINFO_STRING(13, description, 5, description, "xx13-5 description", 0);
398 TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
399 TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description",
400 SAMR_FIELD_DESCRIPTION);
402 TEST_USERINFO_STRING(14, workstations, 3, workstations, "14workstation3", 0);
403 TEST_USERINFO_STRING(14, workstations, 5, workstations, "14workstation4", 0);
404 TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
405 TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21",
406 SAMR_FIELD_WORKSTATIONS);
407 TEST_USERINFO_STRING(21, workstations, 3, workstations, "21workstation3",
408 SAMR_FIELD_WORKSTATIONS);
409 TEST_USERINFO_STRING(21, workstations, 5, workstations, "21workstation5",
410 SAMR_FIELD_WORKSTATIONS);
411 TEST_USERINFO_STRING(21, workstations, 14, workstations, "21workstation14",
412 SAMR_FIELD_WORKSTATIONS);
414 TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
415 TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "xx21-21 parameters",
416 SAMR_FIELD_PARAMETERS);
417 TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "xx21-20 parameters",
418 SAMR_FIELD_PARAMETERS);
419 /* also empty user parameters are allowed */
420 TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "", 0);
421 TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "",
422 SAMR_FIELD_PARAMETERS);
423 TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "",
424 SAMR_FIELD_PARAMETERS);
426 /* Samba 3 cannot store country_code and copy_page atm. - gd */
427 if (!torture_setting_bool(tctx, "samba3", false)) {
428 TEST_USERINFO_INT(2, country_code, 2, country_code, __LINE__, 0);
429 TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
430 TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__,
431 SAMR_FIELD_COUNTRY_CODE);
432 TEST_USERINFO_INT(21, country_code, 2, country_code, __LINE__,
433 SAMR_FIELD_COUNTRY_CODE);
435 TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
436 TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__,
437 SAMR_FIELD_CODE_PAGE);
438 TEST_USERINFO_INT(21, code_page, 2, code_page, __LINE__,
439 SAMR_FIELD_CODE_PAGE);
442 if (!torture_setting_bool(tctx, "samba3", false)) {
443 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, __LINE__, 0);
444 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, __LINE__, 0);
445 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, __LINE__,
446 SAMR_FIELD_ACCT_EXPIRY);
447 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, __LINE__,
448 SAMR_FIELD_ACCT_EXPIRY);
449 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, __LINE__,
450 SAMR_FIELD_ACCT_EXPIRY);
452 /* Samba 3 can only store seconds / time_t in passdb - gd */
454 unix_to_nt_time(&nt, time(NULL) + __LINE__);
455 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, nt, 0);
456 unix_to_nt_time(&nt, time(NULL) + __LINE__);
457 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, nt, 0);
458 unix_to_nt_time(&nt, time(NULL) + __LINE__);
459 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
460 unix_to_nt_time(&nt, time(NULL) + __LINE__);
461 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
462 unix_to_nt_time(&nt, time(NULL) + __LINE__);
463 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
466 TEST_USERINFO_INT(4, logon_hours.bits[3], 3, logon_hours.bits[3], 1, 0);
467 TEST_USERINFO_INT(4, logon_hours.bits[3], 5, logon_hours.bits[3], 2, 0);
468 TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
469 TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4,
470 SAMR_FIELD_LOGON_HOURS);
472 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
473 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
474 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
476 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
477 (base_acct_flags | ACB_DISABLED),
478 (base_acct_flags | ACB_DISABLED | user_extra_flags),
481 /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
482 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
483 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
484 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
486 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
487 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
488 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
492 /* The 'autolock' flag doesn't stick - check this */
493 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
494 (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK),
495 (base_acct_flags | ACB_DISABLED | user_extra_flags),
498 /* Removing the 'disabled' flag doesn't stick - check this */
499 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
501 (base_acct_flags | ACB_DISABLED | user_extra_flags),
504 /* The 'store plaintext' flag does stick */
505 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
506 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED),
507 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags),
509 /* The 'use DES' flag does stick */
510 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
511 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY),
512 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags),
514 /* The 'don't require kerberos pre-authentication flag does stick */
515 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
516 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH),
517 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags),
519 /* The 'no kerberos PAC required' flag sticks */
520 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
521 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD),
522 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags),
525 TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags,
526 (base_acct_flags | ACB_DISABLED),
527 (base_acct_flags | ACB_DISABLED | user_extra_flags),
528 SAMR_FIELD_ACCT_FLAGS);
531 /* these fail with win2003 - it appears you can't set the primary gid?
532 the set succeeds, but the gid isn't changed. Very weird! */
533 TEST_USERINFO_INT(9, primary_gid, 1, primary_gid, 513);
534 TEST_USERINFO_INT(9, primary_gid, 3, primary_gid, 513);
535 TEST_USERINFO_INT(9, primary_gid, 5, primary_gid, 513);
536 TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
543 generate a random password for password change tests
545 static char *samr_rand_pass_silent(TALLOC_CTX *mem_ctx, int min_len)
547 size_t len = MAX(8, min_len) + (random() % 6);
548 char *s = generate_random_str(mem_ctx, len);
552 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
554 char *s = samr_rand_pass_silent(mem_ctx, min_len);
555 printf("Generated password '%s'\n", s);
561 generate a random password for password change tests
563 static DATA_BLOB samr_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
566 DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
567 generate_random_buffer(password.data, password.length);
569 for (i=0; i < len; i++) {
570 if (((uint16_t *)password.data)[i] == 0) {
571 ((uint16_t *)password.data)[i] = 1;
579 generate a random password for password change tests (fixed length)
581 static char *samr_rand_pass_fixed_len(TALLOC_CTX *mem_ctx, int len)
583 char *s = generate_random_str(mem_ctx, len);
584 printf("Generated password '%s'\n", s);
588 static bool test_SetUserPass(struct dcerpc_pipe *p, struct torture_context *tctx,
589 struct policy_handle *handle, char **password)
592 struct samr_SetUserInfo s;
593 union samr_UserInfo u;
595 DATA_BLOB session_key;
597 struct samr_GetUserPwInfo pwp;
598 struct samr_PwInfo info;
599 int policy_min_pw_len = 0;
600 pwp.in.user_handle = handle;
601 pwp.out.info = &info;
603 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
604 if (NT_STATUS_IS_OK(status)) {
605 policy_min_pw_len = pwp.out.info->min_password_length;
607 newpass = samr_rand_pass(tctx, policy_min_pw_len);
609 s.in.user_handle = handle;
613 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
614 u.info24.password_expired = 0;
616 status = dcerpc_fetch_session_key(p, &session_key);
617 if (!NT_STATUS_IS_OK(status)) {
618 printf("SetUserInfo level %u - no session key - %s\n",
619 s.in.level, nt_errstr(status));
623 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
625 torture_comment(tctx, "Testing SetUserInfo level 24 (set password)\n");
627 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
628 if (!NT_STATUS_IS_OK(status)) {
629 printf("SetUserInfo level %u failed - %s\n",
630 s.in.level, nt_errstr(status));
640 static bool test_SetUserPass_23(struct dcerpc_pipe *p, struct torture_context *tctx,
641 struct policy_handle *handle, uint32_t fields_present,
645 struct samr_SetUserInfo s;
646 union samr_UserInfo u;
648 DATA_BLOB session_key;
650 struct samr_GetUserPwInfo pwp;
651 struct samr_PwInfo info;
652 int policy_min_pw_len = 0;
653 pwp.in.user_handle = handle;
654 pwp.out.info = &info;
656 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
657 if (NT_STATUS_IS_OK(status)) {
658 policy_min_pw_len = pwp.out.info->min_password_length;
660 newpass = samr_rand_pass(tctx, policy_min_pw_len);
662 s.in.user_handle = handle;
668 u.info23.info.fields_present = fields_present;
670 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
672 status = dcerpc_fetch_session_key(p, &session_key);
673 if (!NT_STATUS_IS_OK(status)) {
674 printf("SetUserInfo level %u - no session key - %s\n",
675 s.in.level, nt_errstr(status));
679 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
681 torture_comment(tctx, "Testing SetUserInfo level 23 (set password)\n");
683 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
684 if (!NT_STATUS_IS_OK(status)) {
685 printf("SetUserInfo level %u failed - %s\n",
686 s.in.level, nt_errstr(status));
692 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
694 status = dcerpc_fetch_session_key(p, &session_key);
695 if (!NT_STATUS_IS_OK(status)) {
696 printf("SetUserInfo level %u - no session key - %s\n",
697 s.in.level, nt_errstr(status));
701 /* This should break the key nicely */
702 session_key.length--;
703 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
705 torture_comment(tctx, "Testing SetUserInfo level 23 (set password) with wrong password\n");
707 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
708 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
709 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
710 s.in.level, nt_errstr(status));
718 static bool test_SetUserPassEx(struct dcerpc_pipe *p, struct torture_context *tctx,
719 struct policy_handle *handle, bool makeshort,
723 struct samr_SetUserInfo s;
724 union samr_UserInfo u;
726 DATA_BLOB session_key;
727 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
728 uint8_t confounder[16];
730 struct MD5Context ctx;
731 struct samr_GetUserPwInfo pwp;
732 struct samr_PwInfo info;
733 int policy_min_pw_len = 0;
734 pwp.in.user_handle = handle;
735 pwp.out.info = &info;
737 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
738 if (NT_STATUS_IS_OK(status)) {
739 policy_min_pw_len = pwp.out.info->min_password_length;
741 if (makeshort && policy_min_pw_len) {
742 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len - 1);
744 newpass = samr_rand_pass(tctx, policy_min_pw_len);
747 s.in.user_handle = handle;
751 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
752 u.info26.password_expired = 0;
754 status = dcerpc_fetch_session_key(p, &session_key);
755 if (!NT_STATUS_IS_OK(status)) {
756 printf("SetUserInfo level %u - no session key - %s\n",
757 s.in.level, nt_errstr(status));
761 generate_random_buffer((uint8_t *)confounder, 16);
764 MD5Update(&ctx, confounder, 16);
765 MD5Update(&ctx, session_key.data, session_key.length);
766 MD5Final(confounded_session_key.data, &ctx);
768 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
769 memcpy(&u.info26.password.data[516], confounder, 16);
771 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex)\n");
773 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
774 if (!NT_STATUS_IS_OK(status)) {
775 printf("SetUserInfo level %u failed - %s\n",
776 s.in.level, nt_errstr(status));
782 /* This should break the key nicely */
783 confounded_session_key.data[0]++;
785 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
786 memcpy(&u.info26.password.data[516], confounder, 16);
788 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
790 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
791 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
792 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
793 s.in.level, nt_errstr(status));
802 static bool test_SetUserPass_25(struct dcerpc_pipe *p, struct torture_context *tctx,
803 struct policy_handle *handle, uint32_t fields_present,
807 struct samr_SetUserInfo s;
808 union samr_UserInfo u;
810 DATA_BLOB session_key;
811 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
812 struct MD5Context ctx;
813 uint8_t confounder[16];
815 struct samr_GetUserPwInfo pwp;
816 struct samr_PwInfo info;
817 int policy_min_pw_len = 0;
818 pwp.in.user_handle = handle;
819 pwp.out.info = &info;
821 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
822 if (NT_STATUS_IS_OK(status)) {
823 policy_min_pw_len = pwp.out.info->min_password_length;
825 newpass = samr_rand_pass(tctx, policy_min_pw_len);
827 s.in.user_handle = handle;
833 u.info25.info.fields_present = fields_present;
835 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
837 status = dcerpc_fetch_session_key(p, &session_key);
838 if (!NT_STATUS_IS_OK(status)) {
839 printf("SetUserInfo level %u - no session key - %s\n",
840 s.in.level, nt_errstr(status));
844 generate_random_buffer((uint8_t *)confounder, 16);
847 MD5Update(&ctx, confounder, 16);
848 MD5Update(&ctx, session_key.data, session_key.length);
849 MD5Final(confounded_session_key.data, &ctx);
851 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
852 memcpy(&u.info25.password.data[516], confounder, 16);
854 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex)\n");
856 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
857 if (!NT_STATUS_IS_OK(status)) {
858 printf("SetUserInfo level %u failed - %s\n",
859 s.in.level, nt_errstr(status));
865 /* This should break the key nicely */
866 confounded_session_key.data[0]++;
868 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
869 memcpy(&u.info25.password.data[516], confounder, 16);
871 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
873 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
874 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
875 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
876 s.in.level, nt_errstr(status));
883 static bool test_SetUserPass_18(struct dcerpc_pipe *p, struct torture_context *tctx,
884 struct policy_handle *handle, char **password)
887 struct samr_SetUserInfo s;
888 union samr_UserInfo u;
890 DATA_BLOB session_key;
892 struct samr_GetUserPwInfo pwp;
893 struct samr_PwInfo info;
894 int policy_min_pw_len = 0;
895 uint8_t lm_hash[16], nt_hash[16];
897 pwp.in.user_handle = handle;
898 pwp.out.info = &info;
900 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
901 if (NT_STATUS_IS_OK(status)) {
902 policy_min_pw_len = pwp.out.info->min_password_length;
904 newpass = samr_rand_pass(tctx, policy_min_pw_len);
906 s.in.user_handle = handle;
912 u.info18.nt_pwd_active = true;
913 u.info18.lm_pwd_active = true;
915 E_md4hash(newpass, nt_hash);
916 E_deshash(newpass, lm_hash);
918 status = dcerpc_fetch_session_key(p, &session_key);
919 if (!NT_STATUS_IS_OK(status)) {
920 printf("SetUserInfo level %u - no session key - %s\n",
921 s.in.level, nt_errstr(status));
927 in = data_blob_const(nt_hash, 16);
928 out = data_blob_talloc_zero(tctx, 16);
929 sess_crypt_blob(&out, &in, &session_key, true);
930 memcpy(u.info18.nt_pwd.hash, out.data, out.length);
934 in = data_blob_const(lm_hash, 16);
935 out = data_blob_talloc_zero(tctx, 16);
936 sess_crypt_blob(&out, &in, &session_key, true);
937 memcpy(u.info18.lm_pwd.hash, out.data, out.length);
940 torture_comment(tctx, "Testing SetUserInfo level 18 (set password hash)\n");
942 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
943 if (!NT_STATUS_IS_OK(status)) {
944 printf("SetUserInfo level %u failed - %s\n",
945 s.in.level, nt_errstr(status));
954 static bool test_SetUserPass_21(struct dcerpc_pipe *p, struct torture_context *tctx,
955 struct policy_handle *handle, uint32_t fields_present,
959 struct samr_SetUserInfo s;
960 union samr_UserInfo u;
962 DATA_BLOB session_key;
964 struct samr_GetUserPwInfo pwp;
965 struct samr_PwInfo info;
966 int policy_min_pw_len = 0;
967 uint8_t lm_hash[16], nt_hash[16];
969 pwp.in.user_handle = handle;
970 pwp.out.info = &info;
972 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
973 if (NT_STATUS_IS_OK(status)) {
974 policy_min_pw_len = pwp.out.info->min_password_length;
976 newpass = samr_rand_pass(tctx, policy_min_pw_len);
978 s.in.user_handle = handle;
982 E_md4hash(newpass, nt_hash);
983 E_deshash(newpass, lm_hash);
987 u.info21.fields_present = fields_present;
989 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
990 u.info21.lm_owf_password.length = 16;
991 u.info21.lm_owf_password.size = 16;
992 u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
993 u.info21.lm_password_set = true;
996 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
997 u.info21.nt_owf_password.length = 16;
998 u.info21.nt_owf_password.size = 16;
999 u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
1000 u.info21.nt_password_set = true;
1003 status = dcerpc_fetch_session_key(p, &session_key);
1004 if (!NT_STATUS_IS_OK(status)) {
1005 printf("SetUserInfo level %u - no session key - %s\n",
1006 s.in.level, nt_errstr(status));
1010 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1012 in = data_blob_const(u.info21.lm_owf_password.array,
1013 u.info21.lm_owf_password.length);
1014 out = data_blob_talloc_zero(tctx, 16);
1015 sess_crypt_blob(&out, &in, &session_key, true);
1016 u.info21.lm_owf_password.array = (uint16_t *)out.data;
1019 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1021 in = data_blob_const(u.info21.nt_owf_password.array,
1022 u.info21.nt_owf_password.length);
1023 out = data_blob_talloc_zero(tctx, 16);
1024 sess_crypt_blob(&out, &in, &session_key, true);
1025 u.info21.nt_owf_password.array = (uint16_t *)out.data;
1028 torture_comment(tctx, "Testing SetUserInfo level 21 (set password hash)\n");
1030 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1031 if (!NT_STATUS_IS_OK(status)) {
1032 printf("SetUserInfo level %u failed - %s\n",
1033 s.in.level, nt_errstr(status));
1036 *password = newpass;
1039 /* try invalid length */
1040 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1042 u.info21.nt_owf_password.length++;
1044 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1046 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1047 printf("SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1048 s.in.level, nt_errstr(status));
1053 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1055 u.info21.lm_owf_password.length++;
1057 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1059 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1060 printf("SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1061 s.in.level, nt_errstr(status));
1069 static bool test_SetUserPass_level_ex(struct dcerpc_pipe *p,
1070 struct torture_context *tctx,
1071 struct policy_handle *handle,
1073 uint32_t fields_present,
1074 char **password, uint8_t password_expired,
1076 bool *matched_expected_error)
1079 NTSTATUS expected_error = NT_STATUS_OK;
1080 struct samr_SetUserInfo s;
1081 struct samr_SetUserInfo2 s2;
1082 union samr_UserInfo u;
1084 DATA_BLOB session_key;
1085 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
1086 struct MD5Context ctx;
1087 uint8_t confounder[16];
1089 struct samr_GetUserPwInfo pwp;
1090 struct samr_PwInfo info;
1091 int policy_min_pw_len = 0;
1092 const char *comment = NULL;
1093 uint8_t lm_hash[16], nt_hash[16];
1095 pwp.in.user_handle = handle;
1096 pwp.out.info = &info;
1098 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1099 if (NT_STATUS_IS_OK(status)) {
1100 policy_min_pw_len = pwp.out.info->min_password_length;
1102 newpass = samr_rand_pass_silent(tctx, policy_min_pw_len);
1105 s2.in.user_handle = handle;
1107 s2.in.level = level;
1109 s.in.user_handle = handle;
1114 if (fields_present & SAMR_FIELD_COMMENT) {
1115 comment = talloc_asprintf(tctx, "comment: %ld\n", time(NULL));
1122 E_md4hash(newpass, nt_hash);
1123 E_deshash(newpass, lm_hash);
1125 u.info18.nt_pwd_active = true;
1126 u.info18.lm_pwd_active = true;
1127 u.info18.password_expired = password_expired;
1129 memcpy(u.info18.lm_pwd.hash, lm_hash, 16);
1130 memcpy(u.info18.nt_pwd.hash, nt_hash, 16);
1134 E_md4hash(newpass, nt_hash);
1135 E_deshash(newpass, lm_hash);
1137 u.info21.fields_present = fields_present;
1138 u.info21.password_expired = password_expired;
1139 u.info21.comment.string = comment;
1141 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1142 u.info21.lm_owf_password.length = 16;
1143 u.info21.lm_owf_password.size = 16;
1144 u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
1145 u.info21.lm_password_set = true;
1148 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1149 u.info21.nt_owf_password.length = 16;
1150 u.info21.nt_owf_password.size = 16;
1151 u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
1152 u.info21.nt_password_set = true;
1157 u.info23.info.fields_present = fields_present;
1158 u.info23.info.password_expired = password_expired;
1159 u.info23.info.comment.string = comment;
1161 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
1165 u.info24.password_expired = password_expired;
1167 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
1171 u.info25.info.fields_present = fields_present;
1172 u.info25.info.password_expired = password_expired;
1173 u.info25.info.comment.string = comment;
1175 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
1179 u.info26.password_expired = password_expired;
1181 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
1186 status = dcerpc_fetch_session_key(p, &session_key);
1187 if (!NT_STATUS_IS_OK(status)) {
1188 printf("SetUserInfo level %u - no session key - %s\n",
1189 s.in.level, nt_errstr(status));
1193 generate_random_buffer((uint8_t *)confounder, 16);
1196 MD5Update(&ctx, confounder, 16);
1197 MD5Update(&ctx, session_key.data, session_key.length);
1198 MD5Final(confounded_session_key.data, &ctx);
1204 in = data_blob_const(u.info18.nt_pwd.hash, 16);
1205 out = data_blob_talloc_zero(tctx, 16);
1206 sess_crypt_blob(&out, &in, &session_key, true);
1207 memcpy(u.info18.nt_pwd.hash, out.data, out.length);
1211 in = data_blob_const(u.info18.lm_pwd.hash, 16);
1212 out = data_blob_talloc_zero(tctx, 16);
1213 sess_crypt_blob(&out, &in, &session_key, true);
1214 memcpy(u.info18.lm_pwd.hash, out.data, out.length);
1219 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1221 in = data_blob_const(u.info21.lm_owf_password.array,
1222 u.info21.lm_owf_password.length);
1223 out = data_blob_talloc_zero(tctx, 16);
1224 sess_crypt_blob(&out, &in, &session_key, true);
1225 u.info21.lm_owf_password.array = (uint16_t *)out.data;
1227 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1229 in = data_blob_const(u.info21.nt_owf_password.array,
1230 u.info21.nt_owf_password.length);
1231 out = data_blob_talloc_zero(tctx, 16);
1232 sess_crypt_blob(&out, &in, &session_key, true);
1233 u.info21.nt_owf_password.array = (uint16_t *)out.data;
1237 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
1240 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
1243 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
1244 memcpy(&u.info25.password.data[516], confounder, 16);
1247 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
1248 memcpy(&u.info26.password.data[516], confounder, 16);
1253 status = dcerpc_samr_SetUserInfo2(p, tctx, &s2);
1255 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1258 if (!NT_STATUS_IS_OK(status)) {
1259 if (fields_present == 0) {
1260 expected_error = NT_STATUS_INVALID_PARAMETER;
1262 if (fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
1263 expected_error = NT_STATUS_ACCESS_DENIED;
1267 if (!NT_STATUS_IS_OK(expected_error)) {
1269 torture_assert_ntstatus_equal(tctx,
1271 expected_error, "SetUserInfo2 failed");
1273 torture_assert_ntstatus_equal(tctx,
1275 expected_error, "SetUserInfo failed");
1277 *matched_expected_error = true;
1281 if (!NT_STATUS_IS_OK(status)) {
1282 printf("SetUserInfo%s level %u failed - %s\n",
1283 use_setinfo2 ? "2":"", level, nt_errstr(status));
1286 *password = newpass;
1292 static bool test_SetAliasInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1293 struct policy_handle *handle)
1296 struct samr_SetAliasInfo r;
1297 struct samr_QueryAliasInfo q;
1298 union samr_AliasInfo *info;
1299 uint16_t levels[] = {2, 3};
1303 /* Ignoring switch level 1, as that includes the number of members for the alias
1304 * and setting this to a wrong value might have negative consequences
1307 for (i=0;i<ARRAY_SIZE(levels);i++) {
1308 torture_comment(tctx, "Testing SetAliasInfo level %u\n", levels[i]);
1310 r.in.alias_handle = handle;
1311 r.in.level = levels[i];
1312 r.in.info = talloc(tctx, union samr_AliasInfo);
1313 switch (r.in.level) {
1314 case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
1315 case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
1316 "Test Description, should test I18N as well"); break;
1317 case ALIASINFOALL: printf("ALIASINFOALL ignored\n"); break;
1320 status = dcerpc_samr_SetAliasInfo(p, tctx, &r);
1321 if (!NT_STATUS_IS_OK(status)) {
1322 printf("SetAliasInfo level %u failed - %s\n",
1323 levels[i], nt_errstr(status));
1327 q.in.alias_handle = handle;
1328 q.in.level = levels[i];
1331 status = dcerpc_samr_QueryAliasInfo(p, tctx, &q);
1332 if (!NT_STATUS_IS_OK(status)) {
1333 printf("QueryAliasInfo level %u failed - %s\n",
1334 levels[i], nt_errstr(status));
1342 static bool test_GetGroupsForUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1343 struct policy_handle *user_handle)
1345 struct samr_GetGroupsForUser r;
1346 struct samr_RidWithAttributeArray *rids = NULL;
1349 torture_comment(tctx, "testing GetGroupsForUser\n");
1351 r.in.user_handle = user_handle;
1354 status = dcerpc_samr_GetGroupsForUser(p, tctx, &r);
1355 torture_assert_ntstatus_ok(tctx, status, "GetGroupsForUser");
1361 static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1362 struct lsa_String *domain_name)
1365 struct samr_GetDomPwInfo r;
1366 struct samr_PwInfo info;
1368 r.in.domain_name = domain_name;
1371 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1373 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1374 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1376 r.in.domain_name->string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1377 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1379 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1380 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1382 r.in.domain_name->string = "\\\\__NONAME__";
1383 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1385 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1386 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1388 r.in.domain_name->string = "\\\\Builtin";
1389 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1391 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1392 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1397 static bool test_GetUserPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1398 struct policy_handle *handle)
1401 struct samr_GetUserPwInfo r;
1402 struct samr_PwInfo info;
1404 torture_comment(tctx, "Testing GetUserPwInfo\n");
1406 r.in.user_handle = handle;
1409 status = dcerpc_samr_GetUserPwInfo(p, tctx, &r);
1410 torture_assert_ntstatus_ok(tctx, status, "GetUserPwInfo");
1415 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, struct torture_context *tctx,
1416 struct policy_handle *domain_handle, const char *name,
1420 struct samr_LookupNames n;
1421 struct lsa_String sname[2];
1422 struct samr_Ids rids, types;
1424 init_lsa_String(&sname[0], name);
1426 n.in.domain_handle = domain_handle;
1430 n.out.types = &types;
1431 status = dcerpc_samr_LookupNames(p, tctx, &n);
1432 if (NT_STATUS_IS_OK(status)) {
1433 *rid = n.out.rids->ids[0];
1438 init_lsa_String(&sname[1], "xxNONAMExx");
1440 status = dcerpc_samr_LookupNames(p, tctx, &n);
1441 if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
1442 printf("LookupNames[2] failed - %s\n", nt_errstr(status));
1443 if (NT_STATUS_IS_OK(status)) {
1444 return NT_STATUS_UNSUCCESSFUL;
1450 status = dcerpc_samr_LookupNames(p, tctx, &n);
1451 if (!NT_STATUS_IS_OK(status)) {
1452 printf("LookupNames[0] failed - %s\n", nt_errstr(status));
1456 init_lsa_String(&sname[0], "xxNONAMExx");
1458 status = dcerpc_samr_LookupNames(p, tctx, &n);
1459 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1460 printf("LookupNames[1 bad name] failed - %s\n", nt_errstr(status));
1461 if (NT_STATUS_IS_OK(status)) {
1462 return NT_STATUS_UNSUCCESSFUL;
1467 init_lsa_String(&sname[0], "xxNONAMExx");
1468 init_lsa_String(&sname[1], "xxNONAME2xx");
1470 status = dcerpc_samr_LookupNames(p, tctx, &n);
1471 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1472 printf("LookupNames[2 bad names] failed - %s\n", nt_errstr(status));
1473 if (NT_STATUS_IS_OK(status)) {
1474 return NT_STATUS_UNSUCCESSFUL;
1479 return NT_STATUS_OK;
1482 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1483 struct policy_handle *domain_handle,
1484 const char *name, struct policy_handle *user_handle)
1487 struct samr_OpenUser r;
1490 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
1491 if (!NT_STATUS_IS_OK(status)) {
1495 r.in.domain_handle = domain_handle;
1496 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1498 r.out.user_handle = user_handle;
1499 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
1500 if (!NT_STATUS_IS_OK(status)) {
1501 printf("OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(status));
1508 static bool test_ChangePasswordNT3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1509 struct policy_handle *handle)
1512 struct samr_ChangePasswordUser r;
1514 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1515 struct policy_handle user_handle;
1516 char *oldpass = "test";
1517 char *newpass = "test2";
1518 uint8_t old_nt_hash[16], new_nt_hash[16];
1519 uint8_t old_lm_hash[16], new_lm_hash[16];
1521 status = test_OpenUser_byname(p, mem_ctx, handle, "testuser", &user_handle);
1522 if (!NT_STATUS_IS_OK(status)) {
1526 printf("Testing ChangePasswordUser for user 'testuser'\n");
1528 printf("old password: %s\n", oldpass);
1529 printf("new password: %s\n", newpass);
1531 E_md4hash(oldpass, old_nt_hash);
1532 E_md4hash(newpass, new_nt_hash);
1533 E_deshash(oldpass, old_lm_hash);
1534 E_deshash(newpass, new_lm_hash);
1536 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1537 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1538 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1539 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1540 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1541 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1543 r.in.handle = &user_handle;
1544 r.in.lm_present = 1;
1545 r.in.old_lm_crypted = &hash1;
1546 r.in.new_lm_crypted = &hash2;
1547 r.in.nt_present = 1;
1548 r.in.old_nt_crypted = &hash3;
1549 r.in.new_nt_crypted = &hash4;
1550 r.in.cross1_present = 1;
1551 r.in.nt_cross = &hash5;
1552 r.in.cross2_present = 1;
1553 r.in.lm_cross = &hash6;
1555 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1556 if (!NT_STATUS_IS_OK(status)) {
1557 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1561 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1569 static bool test_ChangePasswordUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1570 const char *acct_name,
1571 struct policy_handle *handle, char **password)
1574 struct samr_ChangePasswordUser r;
1576 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1577 struct policy_handle user_handle;
1579 uint8_t old_nt_hash[16], new_nt_hash[16];
1580 uint8_t old_lm_hash[16], new_lm_hash[16];
1581 bool changed = true;
1584 struct samr_GetUserPwInfo pwp;
1585 struct samr_PwInfo info;
1586 int policy_min_pw_len = 0;
1588 status = test_OpenUser_byname(p, tctx, handle, acct_name, &user_handle);
1589 if (!NT_STATUS_IS_OK(status)) {
1592 pwp.in.user_handle = &user_handle;
1593 pwp.out.info = &info;
1595 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1596 if (NT_STATUS_IS_OK(status)) {
1597 policy_min_pw_len = pwp.out.info->min_password_length;
1599 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1601 torture_comment(tctx, "Testing ChangePasswordUser\n");
1603 torture_assert(tctx, *password != NULL,
1604 "Failing ChangePasswordUser as old password was NULL. Previous test failed?");
1606 oldpass = *password;
1608 E_md4hash(oldpass, old_nt_hash);
1609 E_md4hash(newpass, new_nt_hash);
1610 E_deshash(oldpass, old_lm_hash);
1611 E_deshash(newpass, new_lm_hash);
1613 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1614 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1615 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1616 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1617 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1618 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1620 r.in.user_handle = &user_handle;
1621 r.in.lm_present = 1;
1622 /* Break the LM hash */
1624 r.in.old_lm_crypted = &hash1;
1625 r.in.new_lm_crypted = &hash2;
1626 r.in.nt_present = 1;
1627 r.in.old_nt_crypted = &hash3;
1628 r.in.new_nt_crypted = &hash4;
1629 r.in.cross1_present = 1;
1630 r.in.nt_cross = &hash5;
1631 r.in.cross2_present = 1;
1632 r.in.lm_cross = &hash6;
1634 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1635 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1636 "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash");
1638 /* Unbreak the LM hash */
1641 r.in.user_handle = &user_handle;
1642 r.in.lm_present = 1;
1643 r.in.old_lm_crypted = &hash1;
1644 r.in.new_lm_crypted = &hash2;
1645 /* Break the NT hash */
1647 r.in.nt_present = 1;
1648 r.in.old_nt_crypted = &hash3;
1649 r.in.new_nt_crypted = &hash4;
1650 r.in.cross1_present = 1;
1651 r.in.nt_cross = &hash5;
1652 r.in.cross2_present = 1;
1653 r.in.lm_cross = &hash6;
1655 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1656 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1657 "expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash");
1659 /* Unbreak the NT hash */
1662 r.in.user_handle = &user_handle;
1663 r.in.lm_present = 1;
1664 r.in.old_lm_crypted = &hash1;
1665 r.in.new_lm_crypted = &hash2;
1666 r.in.nt_present = 1;
1667 r.in.old_nt_crypted = &hash3;
1668 r.in.new_nt_crypted = &hash4;
1669 r.in.cross1_present = 1;
1670 r.in.nt_cross = &hash5;
1671 r.in.cross2_present = 1;
1672 /* Break the LM cross */
1674 r.in.lm_cross = &hash6;
1676 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1677 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1678 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status));
1682 /* Unbreak the LM cross */
1685 r.in.user_handle = &user_handle;
1686 r.in.lm_present = 1;
1687 r.in.old_lm_crypted = &hash1;
1688 r.in.new_lm_crypted = &hash2;
1689 r.in.nt_present = 1;
1690 r.in.old_nt_crypted = &hash3;
1691 r.in.new_nt_crypted = &hash4;
1692 r.in.cross1_present = 1;
1693 /* Break the NT cross */
1695 r.in.nt_cross = &hash5;
1696 r.in.cross2_present = 1;
1697 r.in.lm_cross = &hash6;
1699 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1700 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1701 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status));
1705 /* Unbreak the NT cross */
1709 /* Reset the hashes to not broken values */
1710 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1711 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1712 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1713 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1714 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1715 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1717 r.in.user_handle = &user_handle;
1718 r.in.lm_present = 1;
1719 r.in.old_lm_crypted = &hash1;
1720 r.in.new_lm_crypted = &hash2;
1721 r.in.nt_present = 1;
1722 r.in.old_nt_crypted = &hash3;
1723 r.in.new_nt_crypted = &hash4;
1724 r.in.cross1_present = 1;
1725 r.in.nt_cross = &hash5;
1726 r.in.cross2_present = 0;
1727 r.in.lm_cross = NULL;
1729 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1730 if (NT_STATUS_IS_OK(status)) {
1732 *password = newpass;
1733 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1734 printf("ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(status));
1739 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1741 E_md4hash(oldpass, old_nt_hash);
1742 E_md4hash(newpass, new_nt_hash);
1743 E_deshash(oldpass, old_lm_hash);
1744 E_deshash(newpass, new_lm_hash);
1747 /* Reset the hashes to not broken values */
1748 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1749 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1750 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1751 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1752 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1753 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1755 r.in.user_handle = &user_handle;
1756 r.in.lm_present = 1;
1757 r.in.old_lm_crypted = &hash1;
1758 r.in.new_lm_crypted = &hash2;
1759 r.in.nt_present = 1;
1760 r.in.old_nt_crypted = &hash3;
1761 r.in.new_nt_crypted = &hash4;
1762 r.in.cross1_present = 0;
1763 r.in.nt_cross = NULL;
1764 r.in.cross2_present = 1;
1765 r.in.lm_cross = &hash6;
1767 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1768 if (NT_STATUS_IS_OK(status)) {
1770 *password = newpass;
1771 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1772 printf("ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status));
1777 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1779 E_md4hash(oldpass, old_nt_hash);
1780 E_md4hash(newpass, new_nt_hash);
1781 E_deshash(oldpass, old_lm_hash);
1782 E_deshash(newpass, new_lm_hash);
1785 /* Reset the hashes to not broken values */
1786 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1787 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1788 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1789 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1790 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1791 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1793 r.in.user_handle = &user_handle;
1794 r.in.lm_present = 1;
1795 r.in.old_lm_crypted = &hash1;
1796 r.in.new_lm_crypted = &hash2;
1797 r.in.nt_present = 1;
1798 r.in.old_nt_crypted = &hash3;
1799 r.in.new_nt_crypted = &hash4;
1800 r.in.cross1_present = 1;
1801 r.in.nt_cross = &hash5;
1802 r.in.cross2_present = 1;
1803 r.in.lm_cross = &hash6;
1805 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1806 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1807 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1808 } else if (!NT_STATUS_IS_OK(status)) {
1809 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1813 *password = newpass;
1816 r.in.user_handle = &user_handle;
1817 r.in.lm_present = 1;
1818 r.in.old_lm_crypted = &hash1;
1819 r.in.new_lm_crypted = &hash2;
1820 r.in.nt_present = 1;
1821 r.in.old_nt_crypted = &hash3;
1822 r.in.new_nt_crypted = &hash4;
1823 r.in.cross1_present = 1;
1824 r.in.nt_cross = &hash5;
1825 r.in.cross2_present = 1;
1826 r.in.lm_cross = &hash6;
1829 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1830 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1831 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1832 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1833 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status));
1839 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
1847 static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
1848 const char *acct_name,
1849 struct policy_handle *handle, char **password)
1852 struct samr_OemChangePasswordUser2 r;
1854 struct samr_Password lm_verifier;
1855 struct samr_CryptPassword lm_pass;
1856 struct lsa_AsciiString server, account, account_bad;
1859 uint8_t old_lm_hash[16], new_lm_hash[16];
1861 struct samr_GetDomPwInfo dom_pw_info;
1862 struct samr_PwInfo info;
1863 int policy_min_pw_len = 0;
1865 struct lsa_String domain_name;
1867 domain_name.string = "";
1868 dom_pw_info.in.domain_name = &domain_name;
1869 dom_pw_info.out.info = &info;
1871 torture_comment(tctx, "Testing OemChangePasswordUser2\n");
1873 torture_assert(tctx, *password != NULL,
1874 "Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?");
1876 oldpass = *password;
1878 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
1879 if (NT_STATUS_IS_OK(status)) {
1880 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
1883 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1885 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1886 account.string = acct_name;
1888 E_deshash(oldpass, old_lm_hash);
1889 E_deshash(newpass, new_lm_hash);
1891 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1892 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1893 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1895 r.in.server = &server;
1896 r.in.account = &account;
1897 r.in.password = &lm_pass;
1898 r.in.hash = &lm_verifier;
1900 /* Break the verification */
1901 lm_verifier.hash[0]++;
1903 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1905 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1906 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1907 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1912 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1913 /* Break the old password */
1915 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1916 /* unbreak it for the next operation */
1918 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1920 r.in.server = &server;
1921 r.in.account = &account;
1922 r.in.password = &lm_pass;
1923 r.in.hash = &lm_verifier;
1925 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1927 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1928 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1929 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1934 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1935 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1937 r.in.server = &server;
1938 r.in.account = &account;
1939 r.in.password = &lm_pass;
1942 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1944 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1945 && !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1946 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
1951 /* This shouldn't be a valid name */
1952 account_bad.string = TEST_ACCOUNT_NAME "XX";
1953 r.in.account = &account_bad;
1955 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1957 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1958 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
1963 /* This shouldn't be a valid name */
1964 account_bad.string = TEST_ACCOUNT_NAME "XX";
1965 r.in.account = &account_bad;
1966 r.in.password = &lm_pass;
1967 r.in.hash = &lm_verifier;
1969 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1971 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1972 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1977 /* This shouldn't be a valid name */
1978 account_bad.string = TEST_ACCOUNT_NAME "XX";
1979 r.in.account = &account_bad;
1980 r.in.password = NULL;
1981 r.in.hash = &lm_verifier;
1983 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1985 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1986 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
1991 E_deshash(oldpass, old_lm_hash);
1992 E_deshash(newpass, new_lm_hash);
1994 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1995 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1996 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1998 r.in.server = &server;
1999 r.in.account = &account;
2000 r.in.password = &lm_pass;
2001 r.in.hash = &lm_verifier;
2003 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
2004 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2005 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
2006 } else if (!NT_STATUS_IS_OK(status)) {
2007 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
2010 *password = newpass;
2017 static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
2018 const char *acct_name,
2020 char *newpass, bool allow_password_restriction)
2023 struct samr_ChangePasswordUser2 r;
2025 struct lsa_String server, account;
2026 struct samr_CryptPassword nt_pass, lm_pass;
2027 struct samr_Password nt_verifier, lm_verifier;
2029 uint8_t old_nt_hash[16], new_nt_hash[16];
2030 uint8_t old_lm_hash[16], new_lm_hash[16];
2032 struct samr_GetDomPwInfo dom_pw_info;
2033 struct samr_PwInfo info;
2035 struct lsa_String domain_name;
2037 domain_name.string = "";
2038 dom_pw_info.in.domain_name = &domain_name;
2039 dom_pw_info.out.info = &info;
2041 torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name);
2043 torture_assert(tctx, *password != NULL,
2044 "Failing ChangePasswordUser2 as old password was NULL. Previous test failed?");
2045 oldpass = *password;
2048 int policy_min_pw_len = 0;
2049 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
2050 if (NT_STATUS_IS_OK(status)) {
2051 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
2054 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2057 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2058 init_lsa_String(&account, acct_name);
2060 E_md4hash(oldpass, old_nt_hash);
2061 E_md4hash(newpass, new_nt_hash);
2063 E_deshash(oldpass, old_lm_hash);
2064 E_deshash(newpass, new_lm_hash);
2066 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
2067 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2068 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2070 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2071 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2072 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2074 r.in.server = &server;
2075 r.in.account = &account;
2076 r.in.nt_password = &nt_pass;
2077 r.in.nt_verifier = &nt_verifier;
2079 r.in.lm_password = &lm_pass;
2080 r.in.lm_verifier = &lm_verifier;
2082 status = dcerpc_samr_ChangePasswordUser2(p, tctx, &r);
2083 if (allow_password_restriction && NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2084 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
2085 } else if (!NT_STATUS_IS_OK(status)) {
2086 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
2089 *password = newpass;
2096 bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tctx,
2097 const char *account_string,
2098 int policy_min_pw_len,
2100 const char *newpass,
2101 NTTIME last_password_change,
2102 bool handle_reject_reason)
2105 struct samr_ChangePasswordUser3 r;
2107 struct lsa_String server, account, account_bad;
2108 struct samr_CryptPassword nt_pass, lm_pass;
2109 struct samr_Password nt_verifier, lm_verifier;
2111 uint8_t old_nt_hash[16], new_nt_hash[16];
2112 uint8_t old_lm_hash[16], new_lm_hash[16];
2114 struct samr_DomInfo1 *dominfo = NULL;
2115 struct samr_ChangeReject *reject = NULL;
2117 torture_comment(tctx, "Testing ChangePasswordUser3\n");
2119 if (newpass == NULL) {
2121 if (policy_min_pw_len == 0) {
2122 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2124 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len);
2126 } while (check_password_quality(newpass) == false);
2128 torture_comment(tctx, "Using password '%s'\n", newpass);
2131 torture_assert(tctx, *password != NULL,
2132 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2134 oldpass = *password;
2135 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2136 init_lsa_String(&account, account_string);
2138 E_md4hash(oldpass, old_nt_hash);
2139 E_md4hash(newpass, new_nt_hash);
2141 E_deshash(oldpass, old_lm_hash);
2142 E_deshash(newpass, new_lm_hash);
2144 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2145 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2146 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2148 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2149 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2150 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2152 /* Break the verification */
2153 nt_verifier.hash[0]++;
2155 r.in.server = &server;
2156 r.in.account = &account;
2157 r.in.nt_password = &nt_pass;
2158 r.in.nt_verifier = &nt_verifier;
2160 r.in.lm_password = &lm_pass;
2161 r.in.lm_verifier = &lm_verifier;
2162 r.in.password3 = NULL;
2163 r.out.dominfo = &dominfo;
2164 r.out.reject = &reject;
2166 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2167 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
2168 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
2169 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
2174 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2175 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2176 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2178 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2179 /* Break the NT hash */
2181 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2182 /* Unbreak it again */
2184 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2186 r.in.server = &server;
2187 r.in.account = &account;
2188 r.in.nt_password = &nt_pass;
2189 r.in.nt_verifier = &nt_verifier;
2191 r.in.lm_password = &lm_pass;
2192 r.in.lm_verifier = &lm_verifier;
2193 r.in.password3 = NULL;
2194 r.out.dominfo = &dominfo;
2195 r.out.reject = &reject;
2197 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2198 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
2199 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
2200 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
2205 /* This shouldn't be a valid name */
2206 init_lsa_String(&account_bad, talloc_asprintf(tctx, "%sXX", account_string));
2208 r.in.account = &account_bad;
2209 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2210 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
2211 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
2216 E_md4hash(oldpass, old_nt_hash);
2217 E_md4hash(newpass, new_nt_hash);
2219 E_deshash(oldpass, old_lm_hash);
2220 E_deshash(newpass, new_lm_hash);
2222 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2223 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2224 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2226 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2227 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2228 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2230 r.in.server = &server;
2231 r.in.account = &account;
2232 r.in.nt_password = &nt_pass;
2233 r.in.nt_verifier = &nt_verifier;
2235 r.in.lm_password = &lm_pass;
2236 r.in.lm_verifier = &lm_verifier;
2237 r.in.password3 = NULL;
2238 r.out.dominfo = &dominfo;
2239 r.out.reject = &reject;
2241 unix_to_nt_time(&t, time(NULL));
2243 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2245 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
2248 && handle_reject_reason
2249 && (!null_nttime(last_password_change) || !dominfo->min_password_age)) {
2250 if (dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
2252 if (reject && (reject->reason != SAMR_REJECT_OTHER)) {
2253 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2254 SAMR_REJECT_OTHER, reject->reason);
2259 /* We tested the order of precendence which is as follows:
2268 if ((dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
2269 (last_password_change + dominfo->min_password_age > t)) {
2271 if (reject->reason != SAMR_REJECT_OTHER) {
2272 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2273 SAMR_REJECT_OTHER, reject->reason);
2277 } else if ((dominfo->min_password_length > 0) &&
2278 (strlen(newpass) < dominfo->min_password_length)) {
2280 if (reject->reason != SAMR_REJECT_TOO_SHORT) {
2281 printf("expected SAMR_REJECT_TOO_SHORT (%d), got %d\n",
2282 SAMR_REJECT_TOO_SHORT, reject->reason);
2286 } else if ((dominfo->password_history_length > 0) &&
2287 strequal(oldpass, newpass)) {
2289 if (reject->reason != SAMR_REJECT_IN_HISTORY) {
2290 printf("expected SAMR_REJECT_IN_HISTORY (%d), got %d\n",
2291 SAMR_REJECT_IN_HISTORY, reject->reason);
2294 } else if (dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
2296 if (reject->reason != SAMR_REJECT_COMPLEXITY) {
2297 printf("expected SAMR_REJECT_COMPLEXITY (%d), got %d\n",
2298 SAMR_REJECT_COMPLEXITY, reject->reason);
2304 if (reject->reason == SAMR_REJECT_TOO_SHORT) {
2305 /* retry with adjusted size */
2306 return test_ChangePasswordUser3(p, tctx, account_string,
2307 dominfo->min_password_length,
2308 password, NULL, 0, false);
2312 } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2313 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2314 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2315 SAMR_REJECT_OTHER, reject->reason);
2318 /* Perhaps the server has a 'min password age' set? */
2321 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3");
2322 *password = talloc_strdup(tctx, newpass);
2328 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_context *tctx,
2329 const char *account_string,
2330 struct policy_handle *handle,
2334 struct samr_ChangePasswordUser3 r;
2335 struct samr_SetUserInfo s;
2336 union samr_UserInfo u;
2337 DATA_BLOB session_key;
2338 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
2339 uint8_t confounder[16];
2340 struct MD5Context ctx;
2343 struct lsa_String server, account;
2344 struct samr_CryptPassword nt_pass;
2345 struct samr_Password nt_verifier;
2346 DATA_BLOB new_random_pass;
2349 uint8_t old_nt_hash[16], new_nt_hash[16];
2351 struct samr_DomInfo1 *dominfo = NULL;
2352 struct samr_ChangeReject *reject = NULL;
2354 new_random_pass = samr_very_rand_pass(tctx, 128);
2356 torture_assert(tctx, *password != NULL,
2357 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2359 oldpass = *password;
2360 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2361 init_lsa_String(&account, account_string);
2363 s.in.user_handle = handle;
2369 u.info25.info.fields_present = SAMR_FIELD_NT_PASSWORD_PRESENT;
2371 set_pw_in_buffer(u.info25.password.data, &new_random_pass);
2373 status = dcerpc_fetch_session_key(p, &session_key);
2374 if (!NT_STATUS_IS_OK(status)) {
2375 printf("SetUserInfo level %u - no session key - %s\n",
2376 s.in.level, nt_errstr(status));
2380 generate_random_buffer((uint8_t *)confounder, 16);
2383 MD5Update(&ctx, confounder, 16);
2384 MD5Update(&ctx, session_key.data, session_key.length);
2385 MD5Final(confounded_session_key.data, &ctx);
2387 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
2388 memcpy(&u.info25.password.data[516], confounder, 16);
2390 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
2392 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
2393 if (!NT_STATUS_IS_OK(status)) {
2394 printf("SetUserInfo level %u failed - %s\n",
2395 s.in.level, nt_errstr(status));
2399 torture_comment(tctx, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
2401 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2403 new_random_pass = samr_very_rand_pass(tctx, 128);
2405 mdfour(new_nt_hash, new_random_pass.data, new_random_pass.length);
2407 set_pw_in_buffer(nt_pass.data, &new_random_pass);
2408 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2409 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2411 r.in.server = &server;
2412 r.in.account = &account;
2413 r.in.nt_password = &nt_pass;
2414 r.in.nt_verifier = &nt_verifier;
2416 r.in.lm_password = NULL;
2417 r.in.lm_verifier = NULL;
2418 r.in.password3 = NULL;
2419 r.out.dominfo = &dominfo;
2420 r.out.reject = &reject;
2422 unix_to_nt_time(&t, time(NULL));
2424 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2426 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2427 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2428 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2429 SAMR_REJECT_OTHER, reject->reason);
2432 /* Perhaps the server has a 'min password age' set? */
2434 } else if (!NT_STATUS_IS_OK(status)) {
2435 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
2439 newpass = samr_rand_pass(tctx, 128);
2441 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2443 E_md4hash(newpass, new_nt_hash);
2445 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2446 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2447 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2449 r.in.server = &server;
2450 r.in.account = &account;
2451 r.in.nt_password = &nt_pass;
2452 r.in.nt_verifier = &nt_verifier;
2454 r.in.lm_password = NULL;
2455 r.in.lm_verifier = NULL;
2456 r.in.password3 = NULL;
2457 r.out.dominfo = &dominfo;
2458 r.out.reject = &reject;
2460 unix_to_nt_time(&t, time(NULL));
2462 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2464 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2465 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2466 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2467 SAMR_REJECT_OTHER, reject->reason);
2470 /* Perhaps the server has a 'min password age' set? */
2473 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3 (on second random password)");
2474 *password = talloc_strdup(tctx, newpass);
2481 static bool test_GetMembersInAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2482 struct policy_handle *alias_handle)
2484 struct samr_GetMembersInAlias r;
2485 struct lsa_SidArray sids;
2488 torture_comment(tctx, "Testing GetMembersInAlias\n");
2490 r.in.alias_handle = alias_handle;
2493 status = dcerpc_samr_GetMembersInAlias(p, tctx, &r);
2494 torture_assert_ntstatus_ok(tctx, status, "GetMembersInAlias");
2499 static bool test_AddMemberToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2500 struct policy_handle *alias_handle,
2501 const struct dom_sid *domain_sid)
2503 struct samr_AddAliasMember r;
2504 struct samr_DeleteAliasMember d;
2506 struct dom_sid *sid;
2508 sid = dom_sid_add_rid(tctx, domain_sid, 512);
2510 torture_comment(tctx, "testing AddAliasMember\n");
2511 r.in.alias_handle = alias_handle;
2514 status = dcerpc_samr_AddAliasMember(p, tctx, &r);
2515 torture_assert_ntstatus_ok(tctx, status, "AddAliasMember");
2517 d.in.alias_handle = alias_handle;
2520 status = dcerpc_samr_DeleteAliasMember(p, tctx, &d);
2521 torture_assert_ntstatus_ok(tctx, status, "DelAliasMember");
2526 static bool test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2527 struct policy_handle *alias_handle)
2529 struct samr_AddMultipleMembersToAlias a;
2530 struct samr_RemoveMultipleMembersFromAlias r;
2532 struct lsa_SidArray sids;
2534 torture_comment(tctx, "testing AddMultipleMembersToAlias\n");
2535 a.in.alias_handle = alias_handle;
2539 sids.sids = talloc_array(tctx, struct lsa_SidPtr, 3);
2541 sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2542 sids.sids[1].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-2");
2543 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-3");
2545 status = dcerpc_samr_AddMultipleMembersToAlias(p, tctx, &a);
2546 torture_assert_ntstatus_ok(tctx, status, "AddMultipleMembersToAlias");
2549 torture_comment(tctx, "testing RemoveMultipleMembersFromAlias\n");
2550 r.in.alias_handle = alias_handle;
2553 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2554 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2556 /* strange! removing twice doesn't give any error */
2557 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2558 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2560 /* but removing an alias that isn't there does */
2561 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-4");
2563 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2564 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, "RemoveMultipleMembersFromAlias");
2569 static bool test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2570 struct policy_handle *user_handle)
2572 struct samr_TestPrivateFunctionsUser r;
2575 torture_comment(tctx, "Testing TestPrivateFunctionsUser\n");
2577 r.in.user_handle = user_handle;
2579 status = dcerpc_samr_TestPrivateFunctionsUser(p, tctx, &r);
2580 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsUser");
2585 static bool test_QueryUserInfo_pwdlastset(struct dcerpc_pipe *p,
2586 struct torture_context *tctx,
2587 struct policy_handle *handle,
2592 uint16_t levels[] = { /* 3, */ 5, 21 };
2594 NTTIME pwdlastset3 = 0;
2595 NTTIME pwdlastset5 = 0;
2596 NTTIME pwdlastset21 = 0;
2598 torture_comment(tctx, "Testing QueryUserInfo%s level 5 and 21 call ",
2599 use_info2 ? "2":"");
2601 for (i=0; i<ARRAY_SIZE(levels); i++) {
2603 struct samr_QueryUserInfo r;
2604 struct samr_QueryUserInfo2 r2;
2605 union samr_UserInfo *info;
2608 r2.in.user_handle = handle;
2609 r2.in.level = levels[i];
2610 r2.out.info = &info;
2611 status = dcerpc_samr_QueryUserInfo2(p, tctx, &r2);
2614 r.in.user_handle = handle;
2615 r.in.level = levels[i];
2617 status = dcerpc_samr_QueryUserInfo(p, tctx, &r);
2620 if (!NT_STATUS_IS_OK(status) &&
2621 !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
2622 printf("QueryUserInfo%s level %u failed - %s\n",
2623 use_info2 ? "2":"", levels[i], nt_errstr(status));
2627 switch (levels[i]) {
2629 pwdlastset3 = info->info3.last_password_change;
2632 pwdlastset5 = info->info5.last_password_change;
2635 pwdlastset21 = info->info21.last_password_change;
2641 /* torture_assert_int_equal(tctx, pwdlastset3, pwdlastset5,
2642 "pwdlastset mixup"); */
2643 torture_assert_int_equal(tctx, pwdlastset5, pwdlastset21,
2644 "pwdlastset mixup");
2646 *pwdlastset = pwdlastset21;
2648 torture_comment(tctx, "(pwdlastset: %lld)\n", *pwdlastset);
2653 static bool test_SamLogon_Creds(struct dcerpc_pipe *p, struct torture_context *tctx,
2654 struct cli_credentials *machine_credentials,
2655 struct cli_credentials *test_credentials,
2656 struct netlogon_creds_CredentialState *creds,
2657 NTSTATUS expected_result)
2660 struct netr_LogonSamLogon r;
2661 struct netr_Authenticator auth, auth2;
2662 union netr_LogonLevel logon;
2663 union netr_Validation validation;
2664 uint8_t authoritative;
2665 struct netr_NetworkInfo ninfo;
2666 DATA_BLOB names_blob, chal, lm_resp, nt_resp;
2667 int flags = CLI_CRED_NTLM_AUTH;
2669 if (lp_client_lanman_auth(tctx->lp_ctx)) {
2670 flags |= CLI_CRED_LANMAN_AUTH;
2673 if (lp_client_ntlmv2_auth(tctx->lp_ctx)) {
2674 flags |= CLI_CRED_NTLMv2_AUTH;
2677 cli_credentials_get_ntlm_username_domain(test_credentials, tctx,
2678 &ninfo.identity_info.account_name.string,
2679 &ninfo.identity_info.domain_name.string);
2681 generate_random_buffer(ninfo.challenge,
2682 sizeof(ninfo.challenge));
2683 chal = data_blob_const(ninfo.challenge,
2684 sizeof(ninfo.challenge));
2686 names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(machine_credentials),
2687 cli_credentials_get_domain(machine_credentials));
2689 status = cli_credentials_get_ntlm_response(test_credentials, tctx,
2695 torture_assert_ntstatus_ok(tctx, status, "cli_credentials_get_ntlm_response failed");
2697 ninfo.lm.data = lm_resp.data;
2698 ninfo.lm.length = lm_resp.length;
2700 ninfo.nt.data = nt_resp.data;
2701 ninfo.nt.length = nt_resp.length;
2703 ninfo.identity_info.parameter_control =
2704 MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT |
2705 MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;
2706 ninfo.identity_info.logon_id_low = 0;
2707 ninfo.identity_info.logon_id_high = 0;
2708 ninfo.identity_info.workstation.string = cli_credentials_get_workstation(machine_credentials);
2710 logon.network = &ninfo;
2712 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2713 r.in.computer_name = cli_credentials_get_workstation(machine_credentials);
2714 r.in.credential = &auth;
2715 r.in.return_authenticator = &auth2;
2716 r.in.logon_level = 2;
2717 r.in.logon = &logon;
2718 r.out.validation = &validation;
2719 r.out.authoritative = &authoritative;
2721 d_printf("Testing LogonSamLogon with name %s\n", ninfo.identity_info.account_name.string);
2724 netlogon_creds_client_authenticator(creds, &auth);
2726 r.in.validation_level = 2;
2728 status = dcerpc_netr_LogonSamLogon(p, tctx, &r);
2729 if (!NT_STATUS_IS_OK(status)) {
2730 torture_assert_ntstatus_equal(tctx, status, expected_result, "LogonSamLogon failed");
2733 torture_assert_ntstatus_ok(tctx, status, "LogonSamLogon failed");
2736 torture_assert(tctx, netlogon_creds_client_check(creds, &r.out.return_authenticator->cred),
2737 "Credential chaining failed");
2742 static bool test_SamLogon(struct torture_context *tctx,
2743 struct dcerpc_pipe *p,
2744 struct cli_credentials *machine_credentials,
2745 struct cli_credentials *test_credentials,
2746 NTSTATUS expected_result)
2748 struct netlogon_creds_CredentialState *creds;
2750 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
2754 return test_SamLogon_Creds(p, tctx, machine_credentials, test_credentials,
2755 creds, expected_result);
2758 static bool test_SamLogon_with_creds(struct torture_context *tctx,
2759 struct dcerpc_pipe *p,
2760 struct cli_credentials *machine_creds,
2761 const char *acct_name,
2763 NTSTATUS expected_samlogon_result)
2766 struct cli_credentials *test_credentials;
2768 test_credentials = cli_credentials_init(tctx);
2770 cli_credentials_set_workstation(test_credentials,
2771 TEST_ACCOUNT_NAME_PWD, CRED_SPECIFIED);
2772 cli_credentials_set_domain(test_credentials,
2773 lp_workgroup(tctx->lp_ctx), CRED_SPECIFIED);
2774 cli_credentials_set_username(test_credentials,
2775 acct_name, CRED_SPECIFIED);
2776 cli_credentials_set_password(test_credentials,
2777 password, CRED_SPECIFIED);
2778 cli_credentials_set_secure_channel_type(test_credentials, SEC_CHAN_BDC);
2780 printf("testing samlogon as %s@%s password: %s\n",
2781 acct_name, TEST_ACCOUNT_NAME_PWD, password);
2783 if (!test_SamLogon(tctx, p, machine_creds, test_credentials,
2784 expected_samlogon_result)) {
2785 torture_warning(tctx, "new password did not work\n");
2792 static bool test_SetPassword_level(struct dcerpc_pipe *p,
2793 struct dcerpc_pipe *np,
2794 struct torture_context *tctx,
2795 struct policy_handle *handle,
2797 uint32_t fields_present,
2798 uint8_t password_expired,
2799 bool *matched_expected_error,
2801 const char *acct_name,
2803 struct cli_credentials *machine_creds,
2804 bool use_queryinfo2,
2806 NTSTATUS expected_samlogon_result)
2808 const char *fields = NULL;
2815 fields = talloc_asprintf(tctx, "(fields_present: 0x%08x)",
2822 torture_comment(tctx, "Testing SetUserInfo%s level %d call "
2823 "(password_expired: %d) %s\n",
2824 use_setinfo2 ? "2":"", level, password_expired,
2825 fields ? fields : "");
2827 if (!test_SetUserPass_level_ex(p, tctx, handle, level,
2832 matched_expected_error)) {
2836 if (!test_QueryUserInfo_pwdlastset(p, tctx, handle,
2842 if (*matched_expected_error == true) {
2846 if (!test_SamLogon_with_creds(tctx, np,
2850 expected_samlogon_result)) {
2857 static bool test_SetPassword_pwdlastset(struct dcerpc_pipe *p,
2858 struct torture_context *tctx,
2859 uint32_t acct_flags,
2860 const char *acct_name,
2861 struct policy_handle *handle,
2863 struct cli_credentials *machine_credentials)
2865 int s = 0, q = 0, f = 0, l = 0, z = 0;
2868 bool set_levels[] = { false, true };
2869 bool query_levels[] = { false, true };
2870 uint32_t levels[] = { 18, 21, 23, 24, 25, 26 };
2871 uint32_t nonzeros[] = { 1, 24 };
2872 uint32_t fields_present[] = {
2874 SAMR_FIELD_EXPIRED_FLAG,
2875 SAMR_FIELD_LAST_PWD_CHANGE,
2876 SAMR_FIELD_EXPIRED_FLAG | SAMR_FIELD_LAST_PWD_CHANGE,
2878 SAMR_FIELD_NT_PASSWORD_PRESENT,
2879 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
2880 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
2881 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
2882 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
2883 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
2884 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE | SAMR_FIELD_EXPIRED_FLAG
2887 struct dcerpc_pipe *np = NULL;
2889 if (torture_setting_bool(tctx, "samba3", false)) {
2891 printf("Samba3 has second granularity, setting delay to: %d\n",
2895 status = torture_rpc_connection(tctx, &np, &ndr_table_netlogon);
2896 if (!NT_STATUS_IS_OK(status)) {
2900 /* set to 1 to enable testing for all possible opcode
2901 (SetUserInfo, SetUserInfo2, QueryUserInfo, QueryUserInfo2)
2904 #define TEST_SET_LEVELS 1
2905 #define TEST_QUERY_LEVELS 1
2907 for (l=0; l<ARRAY_SIZE(levels); l++) {
2908 for (z=0; z<ARRAY_SIZE(nonzeros); z++) {
2909 for (f=0; f<ARRAY_SIZE(fields_present); f++) {
2910 #ifdef TEST_SET_LEVELS
2911 for (s=0; s<ARRAY_SIZE(set_levels); s++) {
2913 #ifdef TEST_QUERY_LEVELS
2914 for (q=0; q<ARRAY_SIZE(query_levels); q++) {
2916 NTTIME pwdlastset_old = 0;
2917 NTTIME pwdlastset_new = 0;
2918 bool matched_expected_error = false;
2919 NTSTATUS expected_samlogon_result = NT_STATUS_ACCOUNT_DISABLED;
2921 torture_comment(tctx, "------------------------------\n"
2922 "Testing pwdLastSet attribute for flags: 0x%08x "
2923 "(s: %d (l: %d), q: %d)\n",
2924 acct_flags, s, levels[l], q);
2926 switch (levels[l]) {
2930 if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
2931 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT))) {
2932 expected_samlogon_result = NT_STATUS_WRONG_PASSWORD;
2940 /* set a password and force password change (pwdlastset 0) by
2941 * setting the password expired flag to a non-0 value */
2943 if (!test_SetPassword_level(p, np, tctx, handle,
2947 &matched_expected_error,
2951 machine_credentials,
2954 expected_samlogon_result)) {
2958 if (matched_expected_error == true) {
2959 /* skipping on expected failure */
2963 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
2964 * set without the SAMR_FIELD_EXPIRED_FLAG */
2966 switch (levels[l]) {
2970 if ((pwdlastset_new != 0) &&
2971 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
2972 torture_comment(tctx, "not considering a non-0 "
2973 "pwdLastSet as a an error as the "
2974 "SAMR_FIELD_EXPIRED_FLAG has not "
2979 if (pwdlastset_new != 0) {
2980 torture_warning(tctx, "pwdLastSet test failed: "
2981 "expected pwdLastSet 0 but got %lld\n",
2988 switch (levels[l]) {
2992 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
2993 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
2994 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
2995 (pwdlastset_old >= pwdlastset_new)) {
2996 torture_warning(tctx, "pwdlastset not increasing\n");
3001 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3002 (pwdlastset_old >= pwdlastset_new)) {
3003 torture_warning(tctx, "pwdlastset not increasing\n");
3013 /* set a password, pwdlastset needs to get updated (increased
3014 * value), password_expired value used here is 0 */
3016 if (!test_SetPassword_level(p, np, tctx, handle,
3020 &matched_expected_error,
3024 machine_credentials,
3027 expected_samlogon_result)) {
3031 /* when a password has been changed, pwdlastset must not be 0 afterwards
3032 * and must be larger then the old value */
3034 switch (levels[l]) {
3039 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3040 * password has been changed, old and new pwdlastset
3041 * need to be the same value */
3043 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3044 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3045 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3047 torture_assert_int_equal(tctx, pwdlastset_old,
3048 pwdlastset_new, "pwdlastset must be equal");
3052 if (pwdlastset_old >= pwdlastset_new) {
3053 torture_warning(tctx, "pwdLastSet test failed: "
3054 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
3055 pwdlastset_old, pwdlastset_new);
3058 if (pwdlastset_new == 0) {
3059 torture_warning(tctx, "pwdLastSet test failed: "
3060 "expected non-0 pwdlastset, got: %lld\n",
3066 switch (levels[l]) {
3070 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3071 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3072 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3073 (pwdlastset_old >= pwdlastset_new)) {
3074 torture_warning(tctx, "pwdlastset not increasing\n");
3079 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3080 (pwdlastset_old >= pwdlastset_new)) {
3081 torture_warning(tctx, "pwdlastset not increasing\n");
3087 pwdlastset_old = pwdlastset_new;
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 /* if no password has been changed, old and new pwdlastset
3120 * need to be the same value */
3122 if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3123 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3125 torture_assert_int_equal(tctx, pwdlastset_old,
3126 pwdlastset_new, "pwdlastset must be equal");
3130 if (pwdlastset_old >= pwdlastset_new) {
3131 torture_warning(tctx, "pwdLastSet test failed: "
3132 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
3133 pwdlastset_old, pwdlastset_new);
3136 if (pwdlastset_new == 0) {
3137 torture_warning(tctx, "pwdLastSet test failed: "
3138 "expected non-0 pwdlastset, got: %lld\n",
3146 /* set a password and force password change (pwdlastset 0) by
3147 * setting the password expired flag to a non-0 value */
3149 if (!test_SetPassword_level(p, np, tctx, handle,
3153 &matched_expected_error,