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;
193 if (!torture_setting_bool(tctx, "samba3", false)) {
194 if (base_acct_flags == ACB_NORMAL) {
195 /* When created, accounts are expired by default */
196 user_extra_flags = ACB_PW_EXPIRED;
200 s.in.user_handle = handle;
203 s2.in.user_handle = handle;
206 q.in.user_handle = handle;
210 #define TESTCALL(call, r) \
211 status = dcerpc_samr_ ##call(p, tctx, &r); \
212 if (!NT_STATUS_IS_OK(status)) { \
213 torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
214 r.in.level, nt_errstr(status), __location__); \
219 #define STRING_EQUAL(s1, s2, field) \
220 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
221 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
222 #field, s2, __location__); \
227 #define MEM_EQUAL(s1, s2, length, field) \
228 if ((s1 && !s2) || (s2 && !s1) || memcmp(s1, s2, length)) { \
229 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
230 #field, (const char *)s2, __location__); \
235 #define INT_EQUAL(i1, i2, field) \
237 torture_comment(tctx, "Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \
238 #field, (unsigned long long)i2, (unsigned long long)i1, __location__); \
243 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
244 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
246 TESTCALL(QueryUserInfo, q) \
248 s2.in.level = lvl1; \
251 ZERO_STRUCT(u.info21); \
252 u.info21.fields_present = fpval; \
254 init_lsa_String(&u.info ## lvl1.field1, value); \
255 TESTCALL(SetUserInfo, s) \
256 TESTCALL(SetUserInfo2, s2) \
257 init_lsa_String(&u.info ## lvl1.field1, ""); \
258 TESTCALL(QueryUserInfo, q); \
260 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
262 TESTCALL(QueryUserInfo, q) \
264 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
267 #define TEST_USERINFO_BINARYSTRING(lvl1, field1, lvl2, field2, value, fpval) do { \
268 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
270 TESTCALL(QueryUserInfo, q) \
272 s2.in.level = lvl1; \
275 ZERO_STRUCT(u.info21); \
276 u.info21.fields_present = fpval; \
278 init_lsa_BinaryString(&u.info ## lvl1.field1, value, strlen(value)); \
279 TESTCALL(SetUserInfo, s) \
280 TESTCALL(SetUserInfo2, s2) \
281 init_lsa_BinaryString(&u.info ## lvl1.field1, "", 1); \
282 TESTCALL(QueryUserInfo, q); \
284 MEM_EQUAL(u.info ## lvl1.field1.array, value, strlen(value), field1); \
286 TESTCALL(QueryUserInfo, q) \
288 MEM_EQUAL(u.info ## lvl2.field2.array, value, strlen(value), field2); \
291 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
292 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
294 TESTCALL(QueryUserInfo, q) \
296 s2.in.level = lvl1; \
299 uint8_t *bits = u.info21.logon_hours.bits; \
300 ZERO_STRUCT(u.info21); \
301 if (fpval == SAMR_FIELD_LOGON_HOURS) { \
302 u.info21.logon_hours.units_per_week = 168; \
303 u.info21.logon_hours.bits = bits; \
305 u.info21.fields_present = fpval; \
307 u.info ## lvl1.field1 = value; \
308 TESTCALL(SetUserInfo, s) \
309 TESTCALL(SetUserInfo2, s2) \
310 u.info ## lvl1.field1 = 0; \
311 TESTCALL(QueryUserInfo, q); \
313 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
315 TESTCALL(QueryUserInfo, q) \
317 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
320 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
321 TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
325 do { TESTCALL(QueryUserInfo, q0) } while (0);
327 /* Samba 3 cannot store comment fields atm. - gd */
328 if (!torture_setting_bool(tctx, "samba3", false)) {
329 TEST_USERINFO_STRING(2, comment, 1, comment, "xx2-1 comment", 0);
330 TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
331 TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment",
335 test_account_name = talloc_asprintf(tctx, "%sxx7-1", base_account_name);
336 TEST_USERINFO_STRING(7, account_name, 1, account_name, base_account_name, 0);
337 test_account_name = talloc_asprintf(tctx, "%sxx7-3", base_account_name);
338 TEST_USERINFO_STRING(7, account_name, 3, account_name, base_account_name, 0);
339 test_account_name = talloc_asprintf(tctx, "%sxx7-5", base_account_name);
340 TEST_USERINFO_STRING(7, account_name, 5, account_name, base_account_name, 0);
341 test_account_name = talloc_asprintf(tctx, "%sxx7-6", base_account_name);
342 TEST_USERINFO_STRING(7, account_name, 6, account_name, base_account_name, 0);
343 test_account_name = talloc_asprintf(tctx, "%sxx7-7", base_account_name);
344 TEST_USERINFO_STRING(7, account_name, 7, account_name, base_account_name, 0);
345 test_account_name = talloc_asprintf(tctx, "%sxx7-21", base_account_name);
346 TEST_USERINFO_STRING(7, account_name, 21, account_name, base_account_name, 0);
347 test_account_name = base_account_name;
348 TEST_USERINFO_STRING(21, account_name, 21, account_name, base_account_name,
349 SAMR_FIELD_ACCOUNT_NAME);
351 TEST_USERINFO_STRING(6, full_name, 1, full_name, "xx6-1 full_name", 0);
352 TEST_USERINFO_STRING(6, full_name, 3, full_name, "xx6-3 full_name", 0);
353 TEST_USERINFO_STRING(6, full_name, 5, full_name, "xx6-5 full_name", 0);
354 TEST_USERINFO_STRING(6, full_name, 6, full_name, "xx6-6 full_name", 0);
355 TEST_USERINFO_STRING(6, full_name, 8, full_name, "xx6-8 full_name", 0);
356 TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
357 TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
358 TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name",
359 SAMR_FIELD_FULL_NAME);
361 TEST_USERINFO_STRING(6, full_name, 1, full_name, "", 0);
362 TEST_USERINFO_STRING(6, full_name, 3, full_name, "", 0);
363 TEST_USERINFO_STRING(6, full_name, 5, full_name, "", 0);
364 TEST_USERINFO_STRING(6, full_name, 6, full_name, "", 0);
365 TEST_USERINFO_STRING(6, full_name, 8, full_name, "", 0);
366 TEST_USERINFO_STRING(6, full_name, 21, full_name, "", 0);
367 TEST_USERINFO_STRING(8, full_name, 21, full_name, "", 0);
368 TEST_USERINFO_STRING(21, full_name, 21, full_name, "",
369 SAMR_FIELD_FULL_NAME);
371 TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
372 TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
373 TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
374 TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script",
375 SAMR_FIELD_LOGON_SCRIPT);
377 TEST_USERINFO_STRING(12, profile_path, 3, profile_path, "xx12-3 profile_path", 0);
378 TEST_USERINFO_STRING(12, profile_path, 5, profile_path, "xx12-5 profile_path", 0);
379 TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
380 TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path",
381 SAMR_FIELD_PROFILE_PATH);
383 TEST_USERINFO_STRING(10, home_directory, 3, home_directory, "xx10-3 home_directory", 0);
384 TEST_USERINFO_STRING(10, home_directory, 5, home_directory, "xx10-5 home_directory", 0);
385 TEST_USERINFO_STRING(10, home_directory, 21, home_directory, "xx10-21 home_directory", 0);
386 TEST_USERINFO_STRING(21, home_directory, 21, home_directory, "xx21-21 home_directory",
387 SAMR_FIELD_HOME_DIRECTORY);
388 TEST_USERINFO_STRING(21, home_directory, 10, home_directory, "xx21-10 home_directory",
389 SAMR_FIELD_HOME_DIRECTORY);
391 TEST_USERINFO_STRING(10, home_drive, 3, home_drive, "xx10-3 home_drive", 0);
392 TEST_USERINFO_STRING(10, home_drive, 5, home_drive, "xx10-5 home_drive", 0);
393 TEST_USERINFO_STRING(10, home_drive, 21, home_drive, "xx10-21 home_drive", 0);
394 TEST_USERINFO_STRING(21, home_drive, 21, home_drive, "xx21-21 home_drive",
395 SAMR_FIELD_HOME_DRIVE);
396 TEST_USERINFO_STRING(21, home_drive, 10, home_drive, "xx21-10 home_drive",
397 SAMR_FIELD_HOME_DRIVE);
399 TEST_USERINFO_STRING(13, description, 1, description, "xx13-1 description", 0);
400 TEST_USERINFO_STRING(13, description, 5, description, "xx13-5 description", 0);
401 TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
402 TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description",
403 SAMR_FIELD_DESCRIPTION);
405 TEST_USERINFO_STRING(14, workstations, 3, workstations, "14workstation3", 0);
406 TEST_USERINFO_STRING(14, workstations, 5, workstations, "14workstation4", 0);
407 TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
408 TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21",
409 SAMR_FIELD_WORKSTATIONS);
410 TEST_USERINFO_STRING(21, workstations, 3, workstations, "21workstation3",
411 SAMR_FIELD_WORKSTATIONS);
412 TEST_USERINFO_STRING(21, workstations, 5, workstations, "21workstation5",
413 SAMR_FIELD_WORKSTATIONS);
414 TEST_USERINFO_STRING(21, workstations, 14, workstations, "21workstation14",
415 SAMR_FIELD_WORKSTATIONS);
417 TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
418 TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "xx21-21 parameters",
419 SAMR_FIELD_PARAMETERS);
420 TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "xx21-20 parameters",
421 SAMR_FIELD_PARAMETERS);
422 /* also empty user parameters are allowed */
423 TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "", 0);
424 TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "",
425 SAMR_FIELD_PARAMETERS);
426 TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "",
427 SAMR_FIELD_PARAMETERS);
429 /* Samba 3 cannot store country_code and copy_page atm. - gd */
430 if (!torture_setting_bool(tctx, "samba3", false)) {
431 TEST_USERINFO_INT(2, country_code, 2, country_code, __LINE__, 0);
432 TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
433 TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__,
434 SAMR_FIELD_COUNTRY_CODE);
435 TEST_USERINFO_INT(21, country_code, 2, country_code, __LINE__,
436 SAMR_FIELD_COUNTRY_CODE);
438 TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
439 TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__,
440 SAMR_FIELD_CODE_PAGE);
441 TEST_USERINFO_INT(21, code_page, 2, code_page, __LINE__,
442 SAMR_FIELD_CODE_PAGE);
445 if (!torture_setting_bool(tctx, "samba3", false)) {
446 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, __LINE__, 0);
447 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, __LINE__, 0);
448 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, __LINE__,
449 SAMR_FIELD_ACCT_EXPIRY);
450 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, __LINE__,
451 SAMR_FIELD_ACCT_EXPIRY);
452 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, __LINE__,
453 SAMR_FIELD_ACCT_EXPIRY);
455 /* Samba 3 can only store seconds / time_t in passdb - gd */
457 unix_to_nt_time(&nt, time(NULL) + __LINE__);
458 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, nt, 0);
459 unix_to_nt_time(&nt, time(NULL) + __LINE__);
460 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, nt, 0);
461 unix_to_nt_time(&nt, time(NULL) + __LINE__);
462 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
463 unix_to_nt_time(&nt, time(NULL) + __LINE__);
464 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
465 unix_to_nt_time(&nt, time(NULL) + __LINE__);
466 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
469 TEST_USERINFO_INT(4, logon_hours.bits[3], 3, logon_hours.bits[3], 1, 0);
470 TEST_USERINFO_INT(4, logon_hours.bits[3], 5, logon_hours.bits[3], 2, 0);
471 TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
472 TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4,
473 SAMR_FIELD_LOGON_HOURS);
475 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
476 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
477 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
479 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
480 (base_acct_flags | ACB_DISABLED),
481 (base_acct_flags | ACB_DISABLED | user_extra_flags),
484 /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
485 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
486 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
487 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
489 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
490 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
491 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
495 /* The 'autolock' flag doesn't stick - check this */
496 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
497 (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK),
498 (base_acct_flags | ACB_DISABLED | user_extra_flags),
501 /* Removing the 'disabled' flag doesn't stick - check this */
502 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
504 (base_acct_flags | ACB_DISABLED | user_extra_flags),
508 /* Samba3 cannot store these atm */
509 if (!torture_setting_bool(tctx, "samba3", false)) {
510 /* The 'store plaintext' flag does stick */
511 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
512 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED),
513 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags),
515 /* The 'use DES' flag does stick */
516 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
517 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY),
518 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags),
520 /* The 'don't require kerberos pre-authentication flag does stick */
521 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
522 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH),
523 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags),
525 /* The 'no kerberos PAC required' flag sticks */
526 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
527 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD),
528 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags),
531 TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags,
532 (base_acct_flags | ACB_DISABLED),
533 (base_acct_flags | ACB_DISABLED | user_extra_flags),
534 SAMR_FIELD_ACCT_FLAGS);
537 /* these fail with win2003 - it appears you can't set the primary gid?
538 the set succeeds, but the gid isn't changed. Very weird! */
539 TEST_USERINFO_INT(9, primary_gid, 1, primary_gid, 513);
540 TEST_USERINFO_INT(9, primary_gid, 3, primary_gid, 513);
541 TEST_USERINFO_INT(9, primary_gid, 5, primary_gid, 513);
542 TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
549 generate a random password for password change tests
551 static char *samr_rand_pass_silent(TALLOC_CTX *mem_ctx, int min_len)
553 size_t len = MAX(8, min_len) + (random() % 6);
554 char *s = generate_random_str(mem_ctx, len);
558 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
560 char *s = samr_rand_pass_silent(mem_ctx, min_len);
561 printf("Generated password '%s'\n", s);
567 generate a random password for password change tests
569 static DATA_BLOB samr_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
572 DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
573 generate_random_buffer(password.data, password.length);
575 for (i=0; i < len; i++) {
576 if (((uint16_t *)password.data)[i] == 0) {
577 ((uint16_t *)password.data)[i] = 1;
585 generate a random password for password change tests (fixed length)
587 static char *samr_rand_pass_fixed_len(TALLOC_CTX *mem_ctx, int len)
589 char *s = generate_random_str(mem_ctx, len);
590 printf("Generated password '%s'\n", s);
594 static bool test_SetUserPass(struct dcerpc_pipe *p, struct torture_context *tctx,
595 struct policy_handle *handle, char **password)
598 struct samr_SetUserInfo s;
599 union samr_UserInfo u;
601 DATA_BLOB session_key;
603 struct samr_GetUserPwInfo pwp;
604 struct samr_PwInfo info;
605 int policy_min_pw_len = 0;
606 pwp.in.user_handle = handle;
607 pwp.out.info = &info;
609 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
610 if (NT_STATUS_IS_OK(status)) {
611 policy_min_pw_len = pwp.out.info->min_password_length;
613 newpass = samr_rand_pass(tctx, policy_min_pw_len);
615 s.in.user_handle = handle;
619 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
620 u.info24.password_expired = 0;
622 status = dcerpc_fetch_session_key(p, &session_key);
623 if (!NT_STATUS_IS_OK(status)) {
624 printf("SetUserInfo level %u - no session key - %s\n",
625 s.in.level, nt_errstr(status));
629 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
631 torture_comment(tctx, "Testing SetUserInfo level 24 (set password)\n");
633 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
634 if (!NT_STATUS_IS_OK(status)) {
635 printf("SetUserInfo level %u failed - %s\n",
636 s.in.level, nt_errstr(status));
646 static bool test_SetUserPass_23(struct dcerpc_pipe *p, struct torture_context *tctx,
647 struct policy_handle *handle, uint32_t fields_present,
651 struct samr_SetUserInfo s;
652 union samr_UserInfo u;
654 DATA_BLOB session_key;
656 struct samr_GetUserPwInfo pwp;
657 struct samr_PwInfo info;
658 int policy_min_pw_len = 0;
659 pwp.in.user_handle = handle;
660 pwp.out.info = &info;
662 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
663 if (NT_STATUS_IS_OK(status)) {
664 policy_min_pw_len = pwp.out.info->min_password_length;
666 newpass = samr_rand_pass(tctx, policy_min_pw_len);
668 s.in.user_handle = handle;
674 u.info23.info.fields_present = fields_present;
676 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
678 status = dcerpc_fetch_session_key(p, &session_key);
679 if (!NT_STATUS_IS_OK(status)) {
680 printf("SetUserInfo level %u - no session key - %s\n",
681 s.in.level, nt_errstr(status));
685 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
687 torture_comment(tctx, "Testing SetUserInfo level 23 (set password)\n");
689 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
690 if (!NT_STATUS_IS_OK(status)) {
691 printf("SetUserInfo level %u failed - %s\n",
692 s.in.level, nt_errstr(status));
698 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
700 status = dcerpc_fetch_session_key(p, &session_key);
701 if (!NT_STATUS_IS_OK(status)) {
702 printf("SetUserInfo level %u - no session key - %s\n",
703 s.in.level, nt_errstr(status));
707 /* This should break the key nicely */
708 session_key.length--;
709 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
711 torture_comment(tctx, "Testing SetUserInfo level 23 (set password) with wrong password\n");
713 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
714 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
715 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
716 s.in.level, nt_errstr(status));
724 static bool test_SetUserPassEx(struct dcerpc_pipe *p, struct torture_context *tctx,
725 struct policy_handle *handle, bool makeshort,
729 struct samr_SetUserInfo s;
730 union samr_UserInfo u;
732 DATA_BLOB session_key;
733 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
734 uint8_t confounder[16];
736 struct MD5Context ctx;
737 struct samr_GetUserPwInfo pwp;
738 struct samr_PwInfo info;
739 int policy_min_pw_len = 0;
740 pwp.in.user_handle = handle;
741 pwp.out.info = &info;
743 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
744 if (NT_STATUS_IS_OK(status)) {
745 policy_min_pw_len = pwp.out.info->min_password_length;
747 if (makeshort && policy_min_pw_len) {
748 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len - 1);
750 newpass = samr_rand_pass(tctx, policy_min_pw_len);
753 s.in.user_handle = handle;
757 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
758 u.info26.password_expired = 0;
760 status = dcerpc_fetch_session_key(p, &session_key);
761 if (!NT_STATUS_IS_OK(status)) {
762 printf("SetUserInfo level %u - no session key - %s\n",
763 s.in.level, nt_errstr(status));
767 generate_random_buffer((uint8_t *)confounder, 16);
770 MD5Update(&ctx, confounder, 16);
771 MD5Update(&ctx, session_key.data, session_key.length);
772 MD5Final(confounded_session_key.data, &ctx);
774 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
775 memcpy(&u.info26.password.data[516], confounder, 16);
777 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex)\n");
779 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
780 if (!NT_STATUS_IS_OK(status)) {
781 printf("SetUserInfo level %u failed - %s\n",
782 s.in.level, nt_errstr(status));
788 /* This should break the key nicely */
789 confounded_session_key.data[0]++;
791 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
792 memcpy(&u.info26.password.data[516], confounder, 16);
794 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
796 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
797 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
798 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
799 s.in.level, nt_errstr(status));
808 static bool test_SetUserPass_25(struct dcerpc_pipe *p, struct torture_context *tctx,
809 struct policy_handle *handle, uint32_t fields_present,
813 struct samr_SetUserInfo s;
814 union samr_UserInfo u;
816 DATA_BLOB session_key;
817 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
818 struct MD5Context ctx;
819 uint8_t confounder[16];
821 struct samr_GetUserPwInfo pwp;
822 struct samr_PwInfo info;
823 int policy_min_pw_len = 0;
824 pwp.in.user_handle = handle;
825 pwp.out.info = &info;
827 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
828 if (NT_STATUS_IS_OK(status)) {
829 policy_min_pw_len = pwp.out.info->min_password_length;
831 newpass = samr_rand_pass(tctx, policy_min_pw_len);
833 s.in.user_handle = handle;
839 u.info25.info.fields_present = fields_present;
841 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
843 status = dcerpc_fetch_session_key(p, &session_key);
844 if (!NT_STATUS_IS_OK(status)) {
845 printf("SetUserInfo level %u - no session key - %s\n",
846 s.in.level, nt_errstr(status));
850 generate_random_buffer((uint8_t *)confounder, 16);
853 MD5Update(&ctx, confounder, 16);
854 MD5Update(&ctx, session_key.data, session_key.length);
855 MD5Final(confounded_session_key.data, &ctx);
857 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
858 memcpy(&u.info25.password.data[516], confounder, 16);
860 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex)\n");
862 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
863 if (!NT_STATUS_IS_OK(status)) {
864 printf("SetUserInfo level %u failed - %s\n",
865 s.in.level, nt_errstr(status));
871 /* This should break the key nicely */
872 confounded_session_key.data[0]++;
874 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
875 memcpy(&u.info25.password.data[516], confounder, 16);
877 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
879 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
880 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
881 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
882 s.in.level, nt_errstr(status));
889 static bool test_SetUserPass_18(struct dcerpc_pipe *p, struct torture_context *tctx,
890 struct policy_handle *handle, char **password)
893 struct samr_SetUserInfo s;
894 union samr_UserInfo u;
896 DATA_BLOB session_key;
898 struct samr_GetUserPwInfo pwp;
899 struct samr_PwInfo info;
900 int policy_min_pw_len = 0;
901 uint8_t lm_hash[16], nt_hash[16];
903 pwp.in.user_handle = handle;
904 pwp.out.info = &info;
906 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
907 if (NT_STATUS_IS_OK(status)) {
908 policy_min_pw_len = pwp.out.info->min_password_length;
910 newpass = samr_rand_pass(tctx, policy_min_pw_len);
912 s.in.user_handle = handle;
918 u.info18.nt_pwd_active = true;
919 u.info18.lm_pwd_active = true;
921 E_md4hash(newpass, nt_hash);
922 E_deshash(newpass, lm_hash);
924 status = dcerpc_fetch_session_key(p, &session_key);
925 if (!NT_STATUS_IS_OK(status)) {
926 printf("SetUserInfo level %u - no session key - %s\n",
927 s.in.level, nt_errstr(status));
933 in = data_blob_const(nt_hash, 16);
934 out = data_blob_talloc_zero(tctx, 16);
935 sess_crypt_blob(&out, &in, &session_key, true);
936 memcpy(u.info18.nt_pwd.hash, out.data, out.length);
940 in = data_blob_const(lm_hash, 16);
941 out = data_blob_talloc_zero(tctx, 16);
942 sess_crypt_blob(&out, &in, &session_key, true);
943 memcpy(u.info18.lm_pwd.hash, out.data, out.length);
946 torture_comment(tctx, "Testing SetUserInfo level 18 (set password hash)\n");
948 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
949 if (!NT_STATUS_IS_OK(status)) {
950 printf("SetUserInfo level %u failed - %s\n",
951 s.in.level, nt_errstr(status));
960 static bool test_SetUserPass_21(struct dcerpc_pipe *p, struct torture_context *tctx,
961 struct policy_handle *handle, uint32_t fields_present,
965 struct samr_SetUserInfo s;
966 union samr_UserInfo u;
968 DATA_BLOB session_key;
970 struct samr_GetUserPwInfo pwp;
971 struct samr_PwInfo info;
972 int policy_min_pw_len = 0;
973 uint8_t lm_hash[16], nt_hash[16];
975 pwp.in.user_handle = handle;
976 pwp.out.info = &info;
978 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
979 if (NT_STATUS_IS_OK(status)) {
980 policy_min_pw_len = pwp.out.info->min_password_length;
982 newpass = samr_rand_pass(tctx, policy_min_pw_len);
984 s.in.user_handle = handle;
988 E_md4hash(newpass, nt_hash);
989 E_deshash(newpass, lm_hash);
993 u.info21.fields_present = fields_present;
995 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
996 u.info21.lm_owf_password.length = 16;
997 u.info21.lm_owf_password.size = 16;
998 u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
999 u.info21.lm_password_set = true;
1002 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1003 u.info21.nt_owf_password.length = 16;
1004 u.info21.nt_owf_password.size = 16;
1005 u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
1006 u.info21.nt_password_set = true;
1009 status = dcerpc_fetch_session_key(p, &session_key);
1010 if (!NT_STATUS_IS_OK(status)) {
1011 printf("SetUserInfo level %u - no session key - %s\n",
1012 s.in.level, nt_errstr(status));
1016 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1018 in = data_blob_const(u.info21.lm_owf_password.array,
1019 u.info21.lm_owf_password.length);
1020 out = data_blob_talloc_zero(tctx, 16);
1021 sess_crypt_blob(&out, &in, &session_key, true);
1022 u.info21.lm_owf_password.array = (uint16_t *)out.data;
1025 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1027 in = data_blob_const(u.info21.nt_owf_password.array,
1028 u.info21.nt_owf_password.length);
1029 out = data_blob_talloc_zero(tctx, 16);
1030 sess_crypt_blob(&out, &in, &session_key, true);
1031 u.info21.nt_owf_password.array = (uint16_t *)out.data;
1034 torture_comment(tctx, "Testing SetUserInfo level 21 (set password hash)\n");
1036 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1037 if (!NT_STATUS_IS_OK(status)) {
1038 printf("SetUserInfo level %u failed - %s\n",
1039 s.in.level, nt_errstr(status));
1042 *password = newpass;
1045 /* try invalid length */
1046 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1048 u.info21.nt_owf_password.length++;
1050 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1052 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1053 printf("SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1054 s.in.level, nt_errstr(status));
1059 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1061 u.info21.lm_owf_password.length++;
1063 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1065 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1066 printf("SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1067 s.in.level, nt_errstr(status));
1075 static bool test_SetUserPass_level_ex(struct dcerpc_pipe *p,
1076 struct torture_context *tctx,
1077 struct policy_handle *handle,
1079 uint32_t fields_present,
1080 char **password, uint8_t password_expired,
1082 bool *matched_expected_error)
1085 NTSTATUS expected_error = NT_STATUS_OK;
1086 struct samr_SetUserInfo s;
1087 struct samr_SetUserInfo2 s2;
1088 union samr_UserInfo u;
1090 DATA_BLOB session_key;
1091 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
1092 struct MD5Context ctx;
1093 uint8_t confounder[16];
1095 struct samr_GetUserPwInfo pwp;
1096 struct samr_PwInfo info;
1097 int policy_min_pw_len = 0;
1098 const char *comment = NULL;
1099 uint8_t lm_hash[16], nt_hash[16];
1101 pwp.in.user_handle = handle;
1102 pwp.out.info = &info;
1104 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1105 if (NT_STATUS_IS_OK(status)) {
1106 policy_min_pw_len = pwp.out.info->min_password_length;
1108 newpass = samr_rand_pass_silent(tctx, policy_min_pw_len);
1111 s2.in.user_handle = handle;
1113 s2.in.level = level;
1115 s.in.user_handle = handle;
1120 if (fields_present & SAMR_FIELD_COMMENT) {
1121 comment = talloc_asprintf(tctx, "comment: %ld\n", time(NULL));
1128 E_md4hash(newpass, nt_hash);
1129 E_deshash(newpass, lm_hash);
1131 u.info18.nt_pwd_active = true;
1132 u.info18.lm_pwd_active = true;
1133 u.info18.password_expired = password_expired;
1135 memcpy(u.info18.lm_pwd.hash, lm_hash, 16);
1136 memcpy(u.info18.nt_pwd.hash, nt_hash, 16);
1140 E_md4hash(newpass, nt_hash);
1141 E_deshash(newpass, lm_hash);
1143 u.info21.fields_present = fields_present;
1144 u.info21.password_expired = password_expired;
1145 u.info21.comment.string = comment;
1147 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1148 u.info21.lm_owf_password.length = 16;
1149 u.info21.lm_owf_password.size = 16;
1150 u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
1151 u.info21.lm_password_set = true;
1154 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1155 u.info21.nt_owf_password.length = 16;
1156 u.info21.nt_owf_password.size = 16;
1157 u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
1158 u.info21.nt_password_set = true;
1163 u.info23.info.fields_present = fields_present;
1164 u.info23.info.password_expired = password_expired;
1165 u.info23.info.comment.string = comment;
1167 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
1171 u.info24.password_expired = password_expired;
1173 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
1177 u.info25.info.fields_present = fields_present;
1178 u.info25.info.password_expired = password_expired;
1179 u.info25.info.comment.string = comment;
1181 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
1185 u.info26.password_expired = password_expired;
1187 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
1192 status = dcerpc_fetch_session_key(p, &session_key);
1193 if (!NT_STATUS_IS_OK(status)) {
1194 printf("SetUserInfo level %u - no session key - %s\n",
1195 s.in.level, nt_errstr(status));
1199 generate_random_buffer((uint8_t *)confounder, 16);
1202 MD5Update(&ctx, confounder, 16);
1203 MD5Update(&ctx, session_key.data, session_key.length);
1204 MD5Final(confounded_session_key.data, &ctx);
1210 in = data_blob_const(u.info18.nt_pwd.hash, 16);
1211 out = data_blob_talloc_zero(tctx, 16);
1212 sess_crypt_blob(&out, &in, &session_key, true);
1213 memcpy(u.info18.nt_pwd.hash, out.data, out.length);
1217 in = data_blob_const(u.info18.lm_pwd.hash, 16);
1218 out = data_blob_talloc_zero(tctx, 16);
1219 sess_crypt_blob(&out, &in, &session_key, true);
1220 memcpy(u.info18.lm_pwd.hash, out.data, out.length);
1225 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1227 in = data_blob_const(u.info21.lm_owf_password.array,
1228 u.info21.lm_owf_password.length);
1229 out = data_blob_talloc_zero(tctx, 16);
1230 sess_crypt_blob(&out, &in, &session_key, true);
1231 u.info21.lm_owf_password.array = (uint16_t *)out.data;
1233 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1235 in = data_blob_const(u.info21.nt_owf_password.array,
1236 u.info21.nt_owf_password.length);
1237 out = data_blob_talloc_zero(tctx, 16);
1238 sess_crypt_blob(&out, &in, &session_key, true);
1239 u.info21.nt_owf_password.array = (uint16_t *)out.data;
1243 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
1246 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
1249 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
1250 memcpy(&u.info25.password.data[516], confounder, 16);
1253 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
1254 memcpy(&u.info26.password.data[516], confounder, 16);
1259 status = dcerpc_samr_SetUserInfo2(p, tctx, &s2);
1261 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1264 if (!NT_STATUS_IS_OK(status)) {
1265 if (fields_present == 0) {
1266 expected_error = NT_STATUS_INVALID_PARAMETER;
1268 if (fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
1269 expected_error = NT_STATUS_ACCESS_DENIED;
1273 if (!NT_STATUS_IS_OK(expected_error)) {
1275 torture_assert_ntstatus_equal(tctx,
1277 expected_error, "SetUserInfo2 failed");
1279 torture_assert_ntstatus_equal(tctx,
1281 expected_error, "SetUserInfo failed");
1283 *matched_expected_error = true;
1287 if (!NT_STATUS_IS_OK(status)) {
1288 printf("SetUserInfo%s level %u failed - %s\n",
1289 use_setinfo2 ? "2":"", level, nt_errstr(status));
1292 *password = newpass;
1298 static bool test_SetAliasInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1299 struct policy_handle *handle)
1302 struct samr_SetAliasInfo r;
1303 struct samr_QueryAliasInfo q;
1304 union samr_AliasInfo *info;
1305 uint16_t levels[] = {2, 3};
1309 /* Ignoring switch level 1, as that includes the number of members for the alias
1310 * and setting this to a wrong value might have negative consequences
1313 for (i=0;i<ARRAY_SIZE(levels);i++) {
1314 torture_comment(tctx, "Testing SetAliasInfo level %u\n", levels[i]);
1316 r.in.alias_handle = handle;
1317 r.in.level = levels[i];
1318 r.in.info = talloc(tctx, union samr_AliasInfo);
1319 switch (r.in.level) {
1320 case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
1321 case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
1322 "Test Description, should test I18N as well"); break;
1323 case ALIASINFOALL: printf("ALIASINFOALL ignored\n"); break;
1326 status = dcerpc_samr_SetAliasInfo(p, tctx, &r);
1327 if (!NT_STATUS_IS_OK(status)) {
1328 printf("SetAliasInfo level %u failed - %s\n",
1329 levels[i], nt_errstr(status));
1333 q.in.alias_handle = handle;
1334 q.in.level = levels[i];
1337 status = dcerpc_samr_QueryAliasInfo(p, tctx, &q);
1338 if (!NT_STATUS_IS_OK(status)) {
1339 printf("QueryAliasInfo level %u failed - %s\n",
1340 levels[i], nt_errstr(status));
1348 static bool test_GetGroupsForUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1349 struct policy_handle *user_handle)
1351 struct samr_GetGroupsForUser r;
1352 struct samr_RidWithAttributeArray *rids = NULL;
1355 torture_comment(tctx, "testing GetGroupsForUser\n");
1357 r.in.user_handle = user_handle;
1360 status = dcerpc_samr_GetGroupsForUser(p, tctx, &r);
1361 torture_assert_ntstatus_ok(tctx, status, "GetGroupsForUser");
1367 static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1368 struct lsa_String *domain_name)
1371 struct samr_GetDomPwInfo r;
1372 struct samr_PwInfo info;
1374 r.in.domain_name = domain_name;
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 = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
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 = "\\\\__NONAME__";
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");
1394 r.in.domain_name->string = "\\\\Builtin";
1395 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1397 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1398 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1403 static bool test_GetUserPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1404 struct policy_handle *handle)
1407 struct samr_GetUserPwInfo r;
1408 struct samr_PwInfo info;
1410 torture_comment(tctx, "Testing GetUserPwInfo\n");
1412 r.in.user_handle = handle;
1415 status = dcerpc_samr_GetUserPwInfo(p, tctx, &r);
1416 torture_assert_ntstatus_ok(tctx, status, "GetUserPwInfo");
1421 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, struct torture_context *tctx,
1422 struct policy_handle *domain_handle, const char *name,
1426 struct samr_LookupNames n;
1427 struct lsa_String sname[2];
1428 struct samr_Ids rids, types;
1430 init_lsa_String(&sname[0], name);
1432 n.in.domain_handle = domain_handle;
1436 n.out.types = &types;
1437 status = dcerpc_samr_LookupNames(p, tctx, &n);
1438 if (NT_STATUS_IS_OK(status)) {
1439 *rid = n.out.rids->ids[0];
1444 init_lsa_String(&sname[1], "xxNONAMExx");
1446 status = dcerpc_samr_LookupNames(p, tctx, &n);
1447 if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
1448 printf("LookupNames[2] failed - %s\n", nt_errstr(status));
1449 if (NT_STATUS_IS_OK(status)) {
1450 return NT_STATUS_UNSUCCESSFUL;
1456 status = dcerpc_samr_LookupNames(p, tctx, &n);
1457 if (!NT_STATUS_IS_OK(status)) {
1458 printf("LookupNames[0] failed - %s\n", nt_errstr(status));
1462 init_lsa_String(&sname[0], "xxNONAMExx");
1464 status = dcerpc_samr_LookupNames(p, tctx, &n);
1465 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1466 printf("LookupNames[1 bad name] failed - %s\n", nt_errstr(status));
1467 if (NT_STATUS_IS_OK(status)) {
1468 return NT_STATUS_UNSUCCESSFUL;
1473 init_lsa_String(&sname[0], "xxNONAMExx");
1474 init_lsa_String(&sname[1], "xxNONAME2xx");
1476 status = dcerpc_samr_LookupNames(p, tctx, &n);
1477 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1478 printf("LookupNames[2 bad names] failed - %s\n", nt_errstr(status));
1479 if (NT_STATUS_IS_OK(status)) {
1480 return NT_STATUS_UNSUCCESSFUL;
1485 return NT_STATUS_OK;
1488 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1489 struct policy_handle *domain_handle,
1490 const char *name, struct policy_handle *user_handle)
1493 struct samr_OpenUser r;
1496 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
1497 if (!NT_STATUS_IS_OK(status)) {
1501 r.in.domain_handle = domain_handle;
1502 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1504 r.out.user_handle = user_handle;
1505 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
1506 if (!NT_STATUS_IS_OK(status)) {
1507 printf("OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(status));
1514 static bool test_ChangePasswordNT3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1515 struct policy_handle *handle)
1518 struct samr_ChangePasswordUser r;
1520 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1521 struct policy_handle user_handle;
1522 char *oldpass = "test";
1523 char *newpass = "test2";
1524 uint8_t old_nt_hash[16], new_nt_hash[16];
1525 uint8_t old_lm_hash[16], new_lm_hash[16];
1527 status = test_OpenUser_byname(p, mem_ctx, handle, "testuser", &user_handle);
1528 if (!NT_STATUS_IS_OK(status)) {
1532 printf("Testing ChangePasswordUser for user 'testuser'\n");
1534 printf("old password: %s\n", oldpass);
1535 printf("new password: %s\n", newpass);
1537 E_md4hash(oldpass, old_nt_hash);
1538 E_md4hash(newpass, new_nt_hash);
1539 E_deshash(oldpass, old_lm_hash);
1540 E_deshash(newpass, new_lm_hash);
1542 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1543 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1544 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1545 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1546 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1547 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1549 r.in.handle = &user_handle;
1550 r.in.lm_present = 1;
1551 r.in.old_lm_crypted = &hash1;
1552 r.in.new_lm_crypted = &hash2;
1553 r.in.nt_present = 1;
1554 r.in.old_nt_crypted = &hash3;
1555 r.in.new_nt_crypted = &hash4;
1556 r.in.cross1_present = 1;
1557 r.in.nt_cross = &hash5;
1558 r.in.cross2_present = 1;
1559 r.in.lm_cross = &hash6;
1561 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1562 if (!NT_STATUS_IS_OK(status)) {
1563 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1567 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1575 static bool test_ChangePasswordUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1576 const char *acct_name,
1577 struct policy_handle *handle, char **password)
1580 struct samr_ChangePasswordUser r;
1582 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1583 struct policy_handle user_handle;
1585 uint8_t old_nt_hash[16], new_nt_hash[16];
1586 uint8_t old_lm_hash[16], new_lm_hash[16];
1587 bool changed = true;
1590 struct samr_GetUserPwInfo pwp;
1591 struct samr_PwInfo info;
1592 int policy_min_pw_len = 0;
1594 status = test_OpenUser_byname(p, tctx, handle, acct_name, &user_handle);
1595 if (!NT_STATUS_IS_OK(status)) {
1598 pwp.in.user_handle = &user_handle;
1599 pwp.out.info = &info;
1601 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1602 if (NT_STATUS_IS_OK(status)) {
1603 policy_min_pw_len = pwp.out.info->min_password_length;
1605 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1607 torture_comment(tctx, "Testing ChangePasswordUser\n");
1609 torture_assert(tctx, *password != NULL,
1610 "Failing ChangePasswordUser as old password was NULL. Previous test failed?");
1612 oldpass = *password;
1614 E_md4hash(oldpass, old_nt_hash);
1615 E_md4hash(newpass, new_nt_hash);
1616 E_deshash(oldpass, old_lm_hash);
1617 E_deshash(newpass, new_lm_hash);
1619 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1620 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1621 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1622 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1623 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1624 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1626 r.in.user_handle = &user_handle;
1627 r.in.lm_present = 1;
1628 /* Break the LM hash */
1630 r.in.old_lm_crypted = &hash1;
1631 r.in.new_lm_crypted = &hash2;
1632 r.in.nt_present = 1;
1633 r.in.old_nt_crypted = &hash3;
1634 r.in.new_nt_crypted = &hash4;
1635 r.in.cross1_present = 1;
1636 r.in.nt_cross = &hash5;
1637 r.in.cross2_present = 1;
1638 r.in.lm_cross = &hash6;
1640 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1641 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1642 "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash");
1644 /* Unbreak the LM hash */
1647 r.in.user_handle = &user_handle;
1648 r.in.lm_present = 1;
1649 r.in.old_lm_crypted = &hash1;
1650 r.in.new_lm_crypted = &hash2;
1651 /* Break the NT hash */
1653 r.in.nt_present = 1;
1654 r.in.old_nt_crypted = &hash3;
1655 r.in.new_nt_crypted = &hash4;
1656 r.in.cross1_present = 1;
1657 r.in.nt_cross = &hash5;
1658 r.in.cross2_present = 1;
1659 r.in.lm_cross = &hash6;
1661 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1662 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1663 "expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash");
1665 /* Unbreak the NT hash */
1668 r.in.user_handle = &user_handle;
1669 r.in.lm_present = 1;
1670 r.in.old_lm_crypted = &hash1;
1671 r.in.new_lm_crypted = &hash2;
1672 r.in.nt_present = 1;
1673 r.in.old_nt_crypted = &hash3;
1674 r.in.new_nt_crypted = &hash4;
1675 r.in.cross1_present = 1;
1676 r.in.nt_cross = &hash5;
1677 r.in.cross2_present = 1;
1678 /* Break the LM cross */
1680 r.in.lm_cross = &hash6;
1682 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1683 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1684 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status));
1688 /* Unbreak the LM cross */
1691 r.in.user_handle = &user_handle;
1692 r.in.lm_present = 1;
1693 r.in.old_lm_crypted = &hash1;
1694 r.in.new_lm_crypted = &hash2;
1695 r.in.nt_present = 1;
1696 r.in.old_nt_crypted = &hash3;
1697 r.in.new_nt_crypted = &hash4;
1698 r.in.cross1_present = 1;
1699 /* Break the NT cross */
1701 r.in.nt_cross = &hash5;
1702 r.in.cross2_present = 1;
1703 r.in.lm_cross = &hash6;
1705 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1706 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1707 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status));
1711 /* Unbreak the NT cross */
1715 /* Reset the hashes to not broken values */
1716 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1717 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1718 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1719 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1720 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1721 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1723 r.in.user_handle = &user_handle;
1724 r.in.lm_present = 1;
1725 r.in.old_lm_crypted = &hash1;
1726 r.in.new_lm_crypted = &hash2;
1727 r.in.nt_present = 1;
1728 r.in.old_nt_crypted = &hash3;
1729 r.in.new_nt_crypted = &hash4;
1730 r.in.cross1_present = 1;
1731 r.in.nt_cross = &hash5;
1732 r.in.cross2_present = 0;
1733 r.in.lm_cross = NULL;
1735 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1736 if (NT_STATUS_IS_OK(status)) {
1738 *password = newpass;
1739 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1740 printf("ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(status));
1745 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1747 E_md4hash(oldpass, old_nt_hash);
1748 E_md4hash(newpass, new_nt_hash);
1749 E_deshash(oldpass, old_lm_hash);
1750 E_deshash(newpass, new_lm_hash);
1753 /* Reset the hashes to not broken values */
1754 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1755 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1756 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1757 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1758 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1759 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1761 r.in.user_handle = &user_handle;
1762 r.in.lm_present = 1;
1763 r.in.old_lm_crypted = &hash1;
1764 r.in.new_lm_crypted = &hash2;
1765 r.in.nt_present = 1;
1766 r.in.old_nt_crypted = &hash3;
1767 r.in.new_nt_crypted = &hash4;
1768 r.in.cross1_present = 0;
1769 r.in.nt_cross = NULL;
1770 r.in.cross2_present = 1;
1771 r.in.lm_cross = &hash6;
1773 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1774 if (NT_STATUS_IS_OK(status)) {
1776 *password = newpass;
1777 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1778 printf("ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status));
1783 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1785 E_md4hash(oldpass, old_nt_hash);
1786 E_md4hash(newpass, new_nt_hash);
1787 E_deshash(oldpass, old_lm_hash);
1788 E_deshash(newpass, new_lm_hash);
1791 /* Reset the hashes to not broken values */
1792 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1793 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1794 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1795 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1796 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1797 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1799 r.in.user_handle = &user_handle;
1800 r.in.lm_present = 1;
1801 r.in.old_lm_crypted = &hash1;
1802 r.in.new_lm_crypted = &hash2;
1803 r.in.nt_present = 1;
1804 r.in.old_nt_crypted = &hash3;
1805 r.in.new_nt_crypted = &hash4;
1806 r.in.cross1_present = 1;
1807 r.in.nt_cross = &hash5;
1808 r.in.cross2_present = 1;
1809 r.in.lm_cross = &hash6;
1811 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1812 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1813 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1814 } else if (!NT_STATUS_IS_OK(status)) {
1815 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1819 *password = newpass;
1822 r.in.user_handle = &user_handle;
1823 r.in.lm_present = 1;
1824 r.in.old_lm_crypted = &hash1;
1825 r.in.new_lm_crypted = &hash2;
1826 r.in.nt_present = 1;
1827 r.in.old_nt_crypted = &hash3;
1828 r.in.new_nt_crypted = &hash4;
1829 r.in.cross1_present = 1;
1830 r.in.nt_cross = &hash5;
1831 r.in.cross2_present = 1;
1832 r.in.lm_cross = &hash6;
1835 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1836 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1837 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1838 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1839 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status));
1845 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
1853 static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
1854 const char *acct_name,
1855 struct policy_handle *handle, char **password)
1858 struct samr_OemChangePasswordUser2 r;
1860 struct samr_Password lm_verifier;
1861 struct samr_CryptPassword lm_pass;
1862 struct lsa_AsciiString server, account, account_bad;
1865 uint8_t old_lm_hash[16], new_lm_hash[16];
1867 struct samr_GetDomPwInfo dom_pw_info;
1868 struct samr_PwInfo info;
1869 int policy_min_pw_len = 0;
1871 struct lsa_String domain_name;
1873 domain_name.string = "";
1874 dom_pw_info.in.domain_name = &domain_name;
1875 dom_pw_info.out.info = &info;
1877 torture_comment(tctx, "Testing OemChangePasswordUser2\n");
1879 torture_assert(tctx, *password != NULL,
1880 "Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?");
1882 oldpass = *password;
1884 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
1885 if (NT_STATUS_IS_OK(status)) {
1886 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
1889 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1891 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1892 account.string = acct_name;
1894 E_deshash(oldpass, old_lm_hash);
1895 E_deshash(newpass, new_lm_hash);
1897 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1898 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1899 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1901 r.in.server = &server;
1902 r.in.account = &account;
1903 r.in.password = &lm_pass;
1904 r.in.hash = &lm_verifier;
1906 /* Break the verification */
1907 lm_verifier.hash[0]++;
1909 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1911 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1912 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1913 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1918 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1919 /* Break the old password */
1921 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1922 /* unbreak it for the next operation */
1924 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1926 r.in.server = &server;
1927 r.in.account = &account;
1928 r.in.password = &lm_pass;
1929 r.in.hash = &lm_verifier;
1931 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1933 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1934 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1935 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1940 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1941 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1943 r.in.server = &server;
1944 r.in.account = &account;
1945 r.in.password = &lm_pass;
1948 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1950 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1951 && !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1952 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
1957 /* This shouldn't be a valid name */
1958 account_bad.string = TEST_ACCOUNT_NAME "XX";
1959 r.in.account = &account_bad;
1961 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1963 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1964 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
1969 /* This shouldn't be a valid name */
1970 account_bad.string = TEST_ACCOUNT_NAME "XX";
1971 r.in.account = &account_bad;
1972 r.in.password = &lm_pass;
1973 r.in.hash = &lm_verifier;
1975 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1977 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1978 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1983 /* This shouldn't be a valid name */
1984 account_bad.string = TEST_ACCOUNT_NAME "XX";
1985 r.in.account = &account_bad;
1986 r.in.password = NULL;
1987 r.in.hash = &lm_verifier;
1989 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1991 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1992 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
1997 E_deshash(oldpass, old_lm_hash);
1998 E_deshash(newpass, new_lm_hash);
2000 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
2001 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2002 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
2004 r.in.server = &server;
2005 r.in.account = &account;
2006 r.in.password = &lm_pass;
2007 r.in.hash = &lm_verifier;
2009 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
2010 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2011 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
2012 } else if (!NT_STATUS_IS_OK(status)) {
2013 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
2016 *password = newpass;
2023 static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
2024 const char *acct_name,
2026 char *newpass, bool allow_password_restriction)
2029 struct samr_ChangePasswordUser2 r;
2031 struct lsa_String server, account;
2032 struct samr_CryptPassword nt_pass, lm_pass;
2033 struct samr_Password nt_verifier, lm_verifier;
2035 uint8_t old_nt_hash[16], new_nt_hash[16];
2036 uint8_t old_lm_hash[16], new_lm_hash[16];
2038 struct samr_GetDomPwInfo dom_pw_info;
2039 struct samr_PwInfo info;
2041 struct lsa_String domain_name;
2043 domain_name.string = "";
2044 dom_pw_info.in.domain_name = &domain_name;
2045 dom_pw_info.out.info = &info;
2047 torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name);
2049 torture_assert(tctx, *password != NULL,
2050 "Failing ChangePasswordUser2 as old password was NULL. Previous test failed?");
2051 oldpass = *password;
2054 int policy_min_pw_len = 0;
2055 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
2056 if (NT_STATUS_IS_OK(status)) {
2057 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
2060 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2063 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2064 init_lsa_String(&account, acct_name);
2066 E_md4hash(oldpass, old_nt_hash);
2067 E_md4hash(newpass, new_nt_hash);
2069 E_deshash(oldpass, old_lm_hash);
2070 E_deshash(newpass, new_lm_hash);
2072 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
2073 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2074 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2076 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2077 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2078 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2080 r.in.server = &server;
2081 r.in.account = &account;
2082 r.in.nt_password = &nt_pass;
2083 r.in.nt_verifier = &nt_verifier;
2085 r.in.lm_password = &lm_pass;
2086 r.in.lm_verifier = &lm_verifier;
2088 status = dcerpc_samr_ChangePasswordUser2(p, tctx, &r);
2089 if (allow_password_restriction && NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2090 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
2091 } else if (!NT_STATUS_IS_OK(status)) {
2092 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
2095 *password = newpass;
2102 bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tctx,
2103 const char *account_string,
2104 int policy_min_pw_len,
2106 const char *newpass,
2107 NTTIME last_password_change,
2108 bool handle_reject_reason)
2111 struct samr_ChangePasswordUser3 r;
2113 struct lsa_String server, account, account_bad;
2114 struct samr_CryptPassword nt_pass, lm_pass;
2115 struct samr_Password nt_verifier, lm_verifier;
2117 uint8_t old_nt_hash[16], new_nt_hash[16];
2118 uint8_t old_lm_hash[16], new_lm_hash[16];
2120 struct samr_DomInfo1 *dominfo = NULL;
2121 struct samr_ChangeReject *reject = NULL;
2123 torture_comment(tctx, "Testing ChangePasswordUser3\n");
2125 if (newpass == NULL) {
2127 if (policy_min_pw_len == 0) {
2128 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2130 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len);
2132 } while (check_password_quality(newpass) == false);
2134 torture_comment(tctx, "Using password '%s'\n", newpass);
2137 torture_assert(tctx, *password != NULL,
2138 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2140 oldpass = *password;
2141 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2142 init_lsa_String(&account, account_string);
2144 E_md4hash(oldpass, old_nt_hash);
2145 E_md4hash(newpass, new_nt_hash);
2147 E_deshash(oldpass, old_lm_hash);
2148 E_deshash(newpass, new_lm_hash);
2150 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2151 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2152 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2154 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2155 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2156 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2158 /* Break the verification */
2159 nt_verifier.hash[0]++;
2161 r.in.server = &server;
2162 r.in.account = &account;
2163 r.in.nt_password = &nt_pass;
2164 r.in.nt_verifier = &nt_verifier;
2166 r.in.lm_password = &lm_pass;
2167 r.in.lm_verifier = &lm_verifier;
2168 r.in.password3 = NULL;
2169 r.out.dominfo = &dominfo;
2170 r.out.reject = &reject;
2172 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2173 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
2174 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
2175 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
2180 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2181 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2182 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2184 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2185 /* Break the NT hash */
2187 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2188 /* Unbreak it again */
2190 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2192 r.in.server = &server;
2193 r.in.account = &account;
2194 r.in.nt_password = &nt_pass;
2195 r.in.nt_verifier = &nt_verifier;
2197 r.in.lm_password = &lm_pass;
2198 r.in.lm_verifier = &lm_verifier;
2199 r.in.password3 = NULL;
2200 r.out.dominfo = &dominfo;
2201 r.out.reject = &reject;
2203 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2204 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
2205 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
2206 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
2211 /* This shouldn't be a valid name */
2212 init_lsa_String(&account_bad, talloc_asprintf(tctx, "%sXX", account_string));
2214 r.in.account = &account_bad;
2215 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2216 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
2217 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
2222 E_md4hash(oldpass, old_nt_hash);
2223 E_md4hash(newpass, new_nt_hash);
2225 E_deshash(oldpass, old_lm_hash);
2226 E_deshash(newpass, new_lm_hash);
2228 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2229 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2230 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2232 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2233 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2234 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2236 r.in.server = &server;
2237 r.in.account = &account;
2238 r.in.nt_password = &nt_pass;
2239 r.in.nt_verifier = &nt_verifier;
2241 r.in.lm_password = &lm_pass;
2242 r.in.lm_verifier = &lm_verifier;
2243 r.in.password3 = NULL;
2244 r.out.dominfo = &dominfo;
2245 r.out.reject = &reject;
2247 unix_to_nt_time(&t, time(NULL));
2249 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2251 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
2254 && handle_reject_reason
2255 && (!null_nttime(last_password_change) || !dominfo->min_password_age)) {
2256 if (dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
2258 if (reject && (reject->reason != SAMR_REJECT_OTHER)) {
2259 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2260 SAMR_REJECT_OTHER, reject->reason);
2265 /* We tested the order of precendence which is as follows:
2274 if ((dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
2275 (last_password_change + dominfo->min_password_age > t)) {
2277 if (reject->reason != SAMR_REJECT_OTHER) {
2278 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2279 SAMR_REJECT_OTHER, reject->reason);
2283 } else if ((dominfo->min_password_length > 0) &&
2284 (strlen(newpass) < dominfo->min_password_length)) {
2286 if (reject->reason != SAMR_REJECT_TOO_SHORT) {
2287 printf("expected SAMR_REJECT_TOO_SHORT (%d), got %d\n",
2288 SAMR_REJECT_TOO_SHORT, reject->reason);
2292 } else if ((dominfo->password_history_length > 0) &&
2293 strequal(oldpass, newpass)) {
2295 if (reject->reason != SAMR_REJECT_IN_HISTORY) {
2296 printf("expected SAMR_REJECT_IN_HISTORY (%d), got %d\n",
2297 SAMR_REJECT_IN_HISTORY, reject->reason);
2300 } else if (dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
2302 if (reject->reason != SAMR_REJECT_COMPLEXITY) {
2303 printf("expected SAMR_REJECT_COMPLEXITY (%d), got %d\n",
2304 SAMR_REJECT_COMPLEXITY, reject->reason);
2310 if (reject->reason == SAMR_REJECT_TOO_SHORT) {
2311 /* retry with adjusted size */
2312 return test_ChangePasswordUser3(p, tctx, account_string,
2313 dominfo->min_password_length,
2314 password, NULL, 0, false);
2318 } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2319 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2320 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2321 SAMR_REJECT_OTHER, reject->reason);
2324 /* Perhaps the server has a 'min password age' set? */
2327 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3");
2328 *password = talloc_strdup(tctx, newpass);
2334 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_context *tctx,
2335 const char *account_string,
2336 struct policy_handle *handle,
2340 struct samr_ChangePasswordUser3 r;
2341 struct samr_SetUserInfo s;
2342 union samr_UserInfo u;
2343 DATA_BLOB session_key;
2344 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
2345 uint8_t confounder[16];
2346 struct MD5Context ctx;
2349 struct lsa_String server, account;
2350 struct samr_CryptPassword nt_pass;
2351 struct samr_Password nt_verifier;
2352 DATA_BLOB new_random_pass;
2355 uint8_t old_nt_hash[16], new_nt_hash[16];
2357 struct samr_DomInfo1 *dominfo = NULL;
2358 struct samr_ChangeReject *reject = NULL;
2360 new_random_pass = samr_very_rand_pass(tctx, 128);
2362 torture_assert(tctx, *password != NULL,
2363 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2365 oldpass = *password;
2366 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2367 init_lsa_String(&account, account_string);
2369 s.in.user_handle = handle;
2375 u.info25.info.fields_present = SAMR_FIELD_NT_PASSWORD_PRESENT;
2377 set_pw_in_buffer(u.info25.password.data, &new_random_pass);
2379 status = dcerpc_fetch_session_key(p, &session_key);
2380 if (!NT_STATUS_IS_OK(status)) {
2381 printf("SetUserInfo level %u - no session key - %s\n",
2382 s.in.level, nt_errstr(status));
2386 generate_random_buffer((uint8_t *)confounder, 16);
2389 MD5Update(&ctx, confounder, 16);
2390 MD5Update(&ctx, session_key.data, session_key.length);
2391 MD5Final(confounded_session_key.data, &ctx);
2393 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
2394 memcpy(&u.info25.password.data[516], confounder, 16);
2396 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
2398 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
2399 if (!NT_STATUS_IS_OK(status)) {
2400 printf("SetUserInfo level %u failed - %s\n",
2401 s.in.level, nt_errstr(status));
2405 torture_comment(tctx, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
2407 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2409 new_random_pass = samr_very_rand_pass(tctx, 128);
2411 mdfour(new_nt_hash, new_random_pass.data, new_random_pass.length);
2413 set_pw_in_buffer(nt_pass.data, &new_random_pass);
2414 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2415 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2417 r.in.server = &server;
2418 r.in.account = &account;
2419 r.in.nt_password = &nt_pass;
2420 r.in.nt_verifier = &nt_verifier;
2422 r.in.lm_password = NULL;
2423 r.in.lm_verifier = NULL;
2424 r.in.password3 = NULL;
2425 r.out.dominfo = &dominfo;
2426 r.out.reject = &reject;
2428 unix_to_nt_time(&t, time(NULL));
2430 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2432 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2433 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2434 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2435 SAMR_REJECT_OTHER, reject->reason);
2438 /* Perhaps the server has a 'min password age' set? */
2440 } else if (!NT_STATUS_IS_OK(status)) {
2441 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
2445 newpass = samr_rand_pass(tctx, 128);
2447 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2449 E_md4hash(newpass, new_nt_hash);
2451 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2452 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2453 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2455 r.in.server = &server;
2456 r.in.account = &account;
2457 r.in.nt_password = &nt_pass;
2458 r.in.nt_verifier = &nt_verifier;
2460 r.in.lm_password = NULL;
2461 r.in.lm_verifier = NULL;
2462 r.in.password3 = NULL;
2463 r.out.dominfo = &dominfo;
2464 r.out.reject = &reject;
2466 unix_to_nt_time(&t, time(NULL));
2468 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2470 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2471 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2472 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2473 SAMR_REJECT_OTHER, reject->reason);
2476 /* Perhaps the server has a 'min password age' set? */
2479 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3 (on second random password)");
2480 *password = talloc_strdup(tctx, newpass);
2487 static bool test_GetMembersInAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2488 struct policy_handle *alias_handle)
2490 struct samr_GetMembersInAlias r;
2491 struct lsa_SidArray sids;
2494 torture_comment(tctx, "Testing GetMembersInAlias\n");
2496 r.in.alias_handle = alias_handle;
2499 status = dcerpc_samr_GetMembersInAlias(p, tctx, &r);
2500 torture_assert_ntstatus_ok(tctx, status, "GetMembersInAlias");
2505 static bool test_AddMemberToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2506 struct policy_handle *alias_handle,
2507 const struct dom_sid *domain_sid)
2509 struct samr_AddAliasMember r;
2510 struct samr_DeleteAliasMember d;
2512 struct dom_sid *sid;
2514 sid = dom_sid_add_rid(tctx, domain_sid, 512);
2516 torture_comment(tctx, "testing AddAliasMember\n");
2517 r.in.alias_handle = alias_handle;
2520 status = dcerpc_samr_AddAliasMember(p, tctx, &r);
2521 torture_assert_ntstatus_ok(tctx, status, "AddAliasMember");
2523 d.in.alias_handle = alias_handle;
2526 status = dcerpc_samr_DeleteAliasMember(p, tctx, &d);
2527 torture_assert_ntstatus_ok(tctx, status, "DelAliasMember");
2532 static bool test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2533 struct policy_handle *alias_handle)
2535 struct samr_AddMultipleMembersToAlias a;
2536 struct samr_RemoveMultipleMembersFromAlias r;
2538 struct lsa_SidArray sids;
2540 torture_comment(tctx, "testing AddMultipleMembersToAlias\n");
2541 a.in.alias_handle = alias_handle;
2545 sids.sids = talloc_array(tctx, struct lsa_SidPtr, 3);
2547 sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2548 sids.sids[1].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-2");
2549 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-3");
2551 status = dcerpc_samr_AddMultipleMembersToAlias(p, tctx, &a);
2552 torture_assert_ntstatus_ok(tctx, status, "AddMultipleMembersToAlias");
2555 torture_comment(tctx, "testing RemoveMultipleMembersFromAlias\n");
2556 r.in.alias_handle = alias_handle;
2559 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2560 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2562 /* strange! removing twice doesn't give any error */
2563 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2564 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2566 /* but removing an alias that isn't there does */
2567 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-4");
2569 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2570 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, "RemoveMultipleMembersFromAlias");
2575 static bool test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2576 struct policy_handle *user_handle)
2578 struct samr_TestPrivateFunctionsUser r;
2581 torture_comment(tctx, "Testing TestPrivateFunctionsUser\n");
2583 r.in.user_handle = user_handle;
2585 status = dcerpc_samr_TestPrivateFunctionsUser(p, tctx, &r);
2586 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsUser");
2591 static bool test_QueryUserInfo_pwdlastset(struct dcerpc_pipe *p,
2592 struct torture_context *tctx,
2593 struct policy_handle *handle,
2598 uint16_t levels[] = { /* 3, */ 5, 21 };
2600 NTTIME pwdlastset3 = 0;
2601 NTTIME pwdlastset5 = 0;
2602 NTTIME pwdlastset21 = 0;
2604 torture_comment(tctx, "Testing QueryUserInfo%s level 5 and 21 call ",
2605 use_info2 ? "2":"");
2607 for (i=0; i<ARRAY_SIZE(levels); i++) {
2609 struct samr_QueryUserInfo r;
2610 struct samr_QueryUserInfo2 r2;
2611 union samr_UserInfo *info;
2614 r2.in.user_handle = handle;
2615 r2.in.level = levels[i];
2616 r2.out.info = &info;
2617 status = dcerpc_samr_QueryUserInfo2(p, tctx, &r2);
2620 r.in.user_handle = handle;
2621 r.in.level = levels[i];
2623 status = dcerpc_samr_QueryUserInfo(p, tctx, &r);
2626 if (!NT_STATUS_IS_OK(status) &&
2627 !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
2628 printf("QueryUserInfo%s level %u failed - %s\n",
2629 use_info2 ? "2":"", levels[i], nt_errstr(status));
2633 switch (levels[i]) {
2635 pwdlastset3 = info->info3.last_password_change;
2638 pwdlastset5 = info->info5.last_password_change;
2641 pwdlastset21 = info->info21.last_password_change;
2647 /* torture_assert_int_equal(tctx, pwdlastset3, pwdlastset5,
2648 "pwdlastset mixup"); */
2649 torture_assert_int_equal(tctx, pwdlastset5, pwdlastset21,
2650 "pwdlastset mixup");
2652 *pwdlastset = pwdlastset21;
2654 torture_comment(tctx, "(pwdlastset: %lld)\n", *pwdlastset);
2659 static bool test_SamLogon_Creds(struct dcerpc_pipe *p, struct torture_context *tctx,
2660 struct cli_credentials *machine_credentials,
2661 struct cli_credentials *test_credentials,
2662 struct netlogon_creds_CredentialState *creds,
2663 NTSTATUS expected_result)
2666 struct netr_LogonSamLogon r;
2667 struct netr_Authenticator auth, auth2;
2668 union netr_LogonLevel logon;
2669 union netr_Validation validation;
2670 uint8_t authoritative;
2671 struct netr_NetworkInfo ninfo;
2672 DATA_BLOB names_blob, chal, lm_resp, nt_resp;
2673 int flags = CLI_CRED_NTLM_AUTH;
2675 if (lp_client_lanman_auth(tctx->lp_ctx)) {
2676 flags |= CLI_CRED_LANMAN_AUTH;
2679 if (lp_client_ntlmv2_auth(tctx->lp_ctx)) {
2680 flags |= CLI_CRED_NTLMv2_AUTH;
2683 cli_credentials_get_ntlm_username_domain(test_credentials, tctx,
2684 &ninfo.identity_info.account_name.string,
2685 &ninfo.identity_info.domain_name.string);
2687 generate_random_buffer(ninfo.challenge,
2688 sizeof(ninfo.challenge));
2689 chal = data_blob_const(ninfo.challenge,
2690 sizeof(ninfo.challenge));
2692 names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(machine_credentials),
2693 cli_credentials_get_domain(machine_credentials));
2695 status = cli_credentials_get_ntlm_response(test_credentials, tctx,
2701 torture_assert_ntstatus_ok(tctx, status, "cli_credentials_get_ntlm_response failed");
2703 ninfo.lm.data = lm_resp.data;
2704 ninfo.lm.length = lm_resp.length;
2706 ninfo.nt.data = nt_resp.data;
2707 ninfo.nt.length = nt_resp.length;
2709 ninfo.identity_info.parameter_control =
2710 MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT |
2711 MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;
2712 ninfo.identity_info.logon_id_low = 0;
2713 ninfo.identity_info.logon_id_high = 0;
2714 ninfo.identity_info.workstation.string = cli_credentials_get_workstation(machine_credentials);
2716 logon.network = &ninfo;
2718 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2719 r.in.computer_name = cli_credentials_get_workstation(machine_credentials);
2720 r.in.credential = &auth;
2721 r.in.return_authenticator = &auth2;
2722 r.in.logon_level = 2;
2723 r.in.logon = &logon;
2724 r.out.validation = &validation;
2725 r.out.authoritative = &authoritative;
2727 d_printf("Testing LogonSamLogon with name %s\n", ninfo.identity_info.account_name.string);
2730 netlogon_creds_client_authenticator(creds, &auth);
2732 r.in.validation_level = 2;
2734 status = dcerpc_netr_LogonSamLogon(p, tctx, &r);
2735 if (!NT_STATUS_IS_OK(status)) {
2736 torture_assert_ntstatus_equal(tctx, status, expected_result, "LogonSamLogon failed");
2739 torture_assert_ntstatus_ok(tctx, status, "LogonSamLogon failed");
2742 torture_assert(tctx, netlogon_creds_client_check(creds, &r.out.return_authenticator->cred),
2743 "Credential chaining failed");
2748 static bool test_SamLogon(struct torture_context *tctx,
2749 struct dcerpc_pipe *p,
2750 struct cli_credentials *machine_credentials,
2751 struct cli_credentials *test_credentials,
2752 NTSTATUS expected_result)
2754 struct netlogon_creds_CredentialState *creds;
2756 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
2760 return test_SamLogon_Creds(p, tctx, machine_credentials, test_credentials,
2761 creds, expected_result);
2764 static bool test_SamLogon_with_creds(struct torture_context *tctx,
2765 struct dcerpc_pipe *p,
2766 struct cli_credentials *machine_creds,
2767 const char *acct_name,
2769 NTSTATUS expected_samlogon_result)
2772 struct cli_credentials *test_credentials;
2774 test_credentials = cli_credentials_init(tctx);
2776 cli_credentials_set_workstation(test_credentials,
2777 TEST_ACCOUNT_NAME_PWD, CRED_SPECIFIED);
2778 cli_credentials_set_domain(test_credentials,
2779 lp_workgroup(tctx->lp_ctx), CRED_SPECIFIED);
2780 cli_credentials_set_username(test_credentials,
2781 acct_name, CRED_SPECIFIED);
2782 cli_credentials_set_password(test_credentials,
2783 password, CRED_SPECIFIED);
2784 cli_credentials_set_secure_channel_type(test_credentials, SEC_CHAN_BDC);
2786 printf("testing samlogon as %s@%s password: %s\n",
2787 acct_name, TEST_ACCOUNT_NAME_PWD, password);
2789 if (!test_SamLogon(tctx, p, machine_creds, test_credentials,
2790 expected_samlogon_result)) {
2791 torture_warning(tctx, "new password did not work\n");
2798 static bool test_SetPassword_level(struct dcerpc_pipe *p,
2799 struct dcerpc_pipe *np,
2800 struct torture_context *tctx,
2801 struct policy_handle *handle,
2803 uint32_t fields_present,
2804 uint8_t password_expired,
2805 bool *matched_expected_error,
2807 const char *acct_name,
2809 struct cli_credentials *machine_creds,
2810 bool use_queryinfo2,
2812 NTSTATUS expected_samlogon_result)
2814 const char *fields = NULL;
2821 fields = talloc_asprintf(tctx, "(fields_present: 0x%08x)",
2828 torture_comment(tctx, "Testing SetUserInfo%s level %d call "
2829 "(password_expired: %d) %s\n",
2830 use_setinfo2 ? "2":"", level, password_expired,
2831 fields ? fields : "");
2833 if (!test_SetUserPass_level_ex(p, tctx, handle, level,
2838 matched_expected_error)) {
2842 if (!test_QueryUserInfo_pwdlastset(p, tctx, handle,
2848 if (*matched_expected_error == true) {
2852 if (!test_SamLogon_with_creds(tctx, np,
2856 expected_samlogon_result)) {
2863 static bool test_SetPassword_pwdlastset(struct dcerpc_pipe *p,
2864 struct torture_context *tctx,
2865 uint32_t acct_flags,
2866 const char *acct_name,
2867 struct policy_handle *handle,
2869 struct cli_credentials *machine_credentials)
2871 int s = 0, q = 0, f = 0, l = 0, z = 0;
2874 bool set_levels[] = { false, true };
2875 bool query_levels[] = { false, true };
2876 uint32_t levels[] = { 18, 21, 23, 24, 25, 26 };
2877 uint32_t nonzeros[] = { 1, 24 };
2878 uint32_t fields_present[] = {
2880 SAMR_FIELD_EXPIRED_FLAG,
2881 SAMR_FIELD_LAST_PWD_CHANGE,
2882 SAMR_FIELD_EXPIRED_FLAG | SAMR_FIELD_LAST_PWD_CHANGE,
2884 SAMR_FIELD_NT_PASSWORD_PRESENT,
2885 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
2886 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
2887 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
2888 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
2889 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
2890 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE | SAMR_FIELD_EXPIRED_FLAG
2893 struct dcerpc_pipe *np = NULL;
2895 if (torture_setting_bool(tctx, "samba3", false)) {
2897 printf("Samba3 has second granularity, setting delay to: %d\n",
2901 status = torture_rpc_connection(tctx, &np, &ndr_table_netlogon);
2902 if (!NT_STATUS_IS_OK(status)) {
2906 /* set to 1 to enable testing for all possible opcode
2907 (SetUserInfo, SetUserInfo2, QueryUserInfo, QueryUserInfo2)
2910 #define TEST_SET_LEVELS 1
2911 #define TEST_QUERY_LEVELS 1
2913 for (l=0; l<ARRAY_SIZE(levels); l++) {
2914 for (z=0; z<ARRAY_SIZE(nonzeros); z++) {
2915 for (f=0; f<ARRAY_SIZE(fields_present); f++) {
2916 #ifdef TEST_SET_LEVELS
2917 for (s=0; s<ARRAY_SIZE(set_levels); s++) {
2919 #ifdef TEST_QUERY_LEVELS
2920 for (q=0; q<ARRAY_SIZE(query_levels); q++) {
2922 NTTIME pwdlastset_old = 0;
2923 NTTIME pwdlastset_new = 0;
2924 bool matched_expected_error = false;
2925 NTSTATUS expected_samlogon_result = NT_STATUS_ACCOUNT_DISABLED;
2927 torture_comment(tctx, "------------------------------\n"
2928 "Testing pwdLastSet attribute for flags: 0x%08x "
2929 "(s: %d (l: %d), q: %d)\n",
2930 acct_flags, s, levels[l], q);
2932 switch (levels[l]) {
2936 if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
2937 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT))) {
2938 expected_samlogon_result = NT_STATUS_WRONG_PASSWORD;
2946 /* set a password and force password change (pwdlastset 0) by
2947 * setting the password expired flag to a non-0 value */
2949 if (!test_SetPassword_level(p, np, tctx, handle,
2953 &matched_expected_error,
2957 machine_credentials,
2960 expected_samlogon_result)) {
2964 if (matched_expected_error == true) {
2965 /* skipping on expected failure */
2969 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
2970 * set without the SAMR_FIELD_EXPIRED_FLAG */
2972 switch (levels[l]) {
2976 if ((pwdlastset_new != 0) &&
2977 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
2978 torture_comment(tctx, "not considering a non-0 "
2979 "pwdLastSet as a an error as the "
2980 "SAMR_FIELD_EXPIRED_FLAG has not "
2985 if (pwdlastset_new != 0) {
2986 torture_warning(tctx, "pwdLastSet test failed: "
2987 "expected pwdLastSet 0 but got %lld\n",
2994 switch (levels[l]) {
2998 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
2999 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3000 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3001 (pwdlastset_old >= pwdlastset_new)) {
3002 torture_warning(tctx, "pwdlastset not increasing\n");
3007 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3008 (pwdlastset_old >= pwdlastset_new)) {
3009 torture_warning(tctx, "pwdlastset not increasing\n");
3019 /* set a password, pwdlastset needs to get updated (increased
3020 * value), password_expired value used here is 0 */
3022 if (!test_SetPassword_level(p, np, tctx, handle,
3026 &matched_expected_error,
3030 machine_credentials,
3033 expected_samlogon_result)) {
3037 /* when a password has been changed, pwdlastset must not be 0 afterwards
3038 * and must be larger then the old value */
3040 switch (levels[l]) {
3045 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3046 * password has been changed, old and new pwdlastset
3047 * need to be the same value */
3049 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3050 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3051 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3053 torture_assert_int_equal(tctx, pwdlastset_old,
3054 pwdlastset_new, "pwdlastset must be equal");
3058 if (pwdlastset_old >= pwdlastset_new) {
3059 torture_warning(tctx, "pwdLastSet test failed: "
3060 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
3061 pwdlastset_old, pwdlastset_new);
3064 if (pwdlastset_new == 0) {
3065 torture_warning(tctx, "pwdLastSet test failed: "
3066 "expected non-0 pwdlastset, got: %lld\n",
3072 switch (levels[l]) {
3076 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3077 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3078 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3079 (pwdlastset_old >= pwdlastset_new)) {
3080 torture_warning(tctx, "pwdlastset not increasing\n");
3085 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3086 (pwdlastset_old >= pwdlastset_new)) {
3087 torture_warning(tctx, "pwdlastset not increasing\n");
3093 pwdlastset_old = pwdlastset_new;
3099 /* set a password, pwdlastset needs to get updated (increased
3100 * value), password_expired value used here is 0 */
3102 if (!test_SetPassword_level(p, np, tctx, handle,
3106 &matched_expected_error,
3110 machine_credentials,
3113 expected_samlogon_result)) {
3117 /* when a password has been changed, pwdlastset must not be 0 afterwards
3118 * and must be larger then the old value */
3120 switch (levels[l]) {
3125 /* if no password has been changed, old and new pwdlastset
3126 * need to be the same value */
3128 if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3129 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3131 torture_assert_int_equal(tctx, pwdlastset_old,
3132 pwdlastset_new, "pwdlastset must be equal");
3136 if (pwdlastset_old >= pwdlastset_new) {
3137 torture_warning(tctx, "pwdLastSet test failed: "
3138 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
3139 pwdlastset_old, pwdlastset_new);
3142 if (pwdlastset_new == 0) {
3143 torture_warning(tctx, "pwdLastSet test failed: "
3144 "expected non-0 pwdlastset, got: %lld\n",
3152 /* set a password and force password change (pwdlastset 0) by
3153 * setting the password expired flag to a non-0 value */
3155 if (!test_SetPassword_level(p, np, tctx, handle,