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 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, __LINE__, 0);
443 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, __LINE__, 0);
444 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, __LINE__,
445 SAMR_FIELD_ACCT_EXPIRY);
446 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, __LINE__,
447 SAMR_FIELD_ACCT_EXPIRY);
448 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, __LINE__,
449 SAMR_FIELD_ACCT_EXPIRY);
451 TEST_USERINFO_INT(4, logon_hours.bits[3], 3, logon_hours.bits[3], 1, 0);
452 TEST_USERINFO_INT(4, logon_hours.bits[3], 5, logon_hours.bits[3], 2, 0);
453 TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
454 TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4,
455 SAMR_FIELD_LOGON_HOURS);
457 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
458 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
459 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
461 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
462 (base_acct_flags | ACB_DISABLED),
463 (base_acct_flags | ACB_DISABLED | user_extra_flags),
466 /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
467 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
468 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
469 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
471 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
472 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
473 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
477 /* The 'autolock' flag doesn't stick - check this */
478 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
479 (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK),
480 (base_acct_flags | ACB_DISABLED | user_extra_flags),
483 /* Removing the 'disabled' flag doesn't stick - check this */
484 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
486 (base_acct_flags | ACB_DISABLED | user_extra_flags),
489 /* The 'store plaintext' flag does stick */
490 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
491 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED),
492 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags),
494 /* The 'use DES' flag does stick */
495 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
496 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY),
497 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags),
499 /* The 'don't require kerberos pre-authentication flag does stick */
500 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
501 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH),
502 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags),
504 /* The 'no kerberos PAC required' flag sticks */
505 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
506 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD),
507 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags),
510 TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags,
511 (base_acct_flags | ACB_DISABLED),
512 (base_acct_flags | ACB_DISABLED | user_extra_flags),
513 SAMR_FIELD_ACCT_FLAGS);
516 /* these fail with win2003 - it appears you can't set the primary gid?
517 the set succeeds, but the gid isn't changed. Very weird! */
518 TEST_USERINFO_INT(9, primary_gid, 1, primary_gid, 513);
519 TEST_USERINFO_INT(9, primary_gid, 3, primary_gid, 513);
520 TEST_USERINFO_INT(9, primary_gid, 5, primary_gid, 513);
521 TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
528 generate a random password for password change tests
530 static char *samr_rand_pass_silent(TALLOC_CTX *mem_ctx, int min_len)
532 size_t len = MAX(8, min_len) + (random() % 6);
533 char *s = generate_random_str(mem_ctx, len);
537 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
539 char *s = samr_rand_pass_silent(mem_ctx, min_len);
540 printf("Generated password '%s'\n", s);
546 generate a random password for password change tests
548 static DATA_BLOB samr_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
551 DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
552 generate_random_buffer(password.data, password.length);
554 for (i=0; i < len; i++) {
555 if (((uint16_t *)password.data)[i] == 0) {
556 ((uint16_t *)password.data)[i] = 1;
564 generate a random password for password change tests (fixed length)
566 static char *samr_rand_pass_fixed_len(TALLOC_CTX *mem_ctx, int len)
568 char *s = generate_random_str(mem_ctx, len);
569 printf("Generated password '%s'\n", s);
573 static bool test_SetUserPass(struct dcerpc_pipe *p, struct torture_context *tctx,
574 struct policy_handle *handle, char **password)
577 struct samr_SetUserInfo s;
578 union samr_UserInfo u;
580 DATA_BLOB session_key;
582 struct samr_GetUserPwInfo pwp;
583 struct samr_PwInfo info;
584 int policy_min_pw_len = 0;
585 pwp.in.user_handle = handle;
586 pwp.out.info = &info;
588 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
589 if (NT_STATUS_IS_OK(status)) {
590 policy_min_pw_len = pwp.out.info->min_password_length;
592 newpass = samr_rand_pass(tctx, policy_min_pw_len);
594 s.in.user_handle = handle;
598 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
599 u.info24.password_expired = 0;
601 status = dcerpc_fetch_session_key(p, &session_key);
602 if (!NT_STATUS_IS_OK(status)) {
603 printf("SetUserInfo level %u - no session key - %s\n",
604 s.in.level, nt_errstr(status));
608 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
610 torture_comment(tctx, "Testing SetUserInfo level 24 (set password)\n");
612 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
613 if (!NT_STATUS_IS_OK(status)) {
614 printf("SetUserInfo level %u failed - %s\n",
615 s.in.level, nt_errstr(status));
625 static bool test_SetUserPass_23(struct dcerpc_pipe *p, struct torture_context *tctx,
626 struct policy_handle *handle, uint32_t fields_present,
630 struct samr_SetUserInfo s;
631 union samr_UserInfo u;
633 DATA_BLOB session_key;
635 struct samr_GetUserPwInfo pwp;
636 struct samr_PwInfo info;
637 int policy_min_pw_len = 0;
638 pwp.in.user_handle = handle;
639 pwp.out.info = &info;
641 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
642 if (NT_STATUS_IS_OK(status)) {
643 policy_min_pw_len = pwp.out.info->min_password_length;
645 newpass = samr_rand_pass(tctx, policy_min_pw_len);
647 s.in.user_handle = handle;
653 u.info23.info.fields_present = fields_present;
655 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
657 status = dcerpc_fetch_session_key(p, &session_key);
658 if (!NT_STATUS_IS_OK(status)) {
659 printf("SetUserInfo level %u - no session key - %s\n",
660 s.in.level, nt_errstr(status));
664 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
666 torture_comment(tctx, "Testing SetUserInfo level 23 (set password)\n");
668 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
669 if (!NT_STATUS_IS_OK(status)) {
670 printf("SetUserInfo level %u failed - %s\n",
671 s.in.level, nt_errstr(status));
677 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
679 status = dcerpc_fetch_session_key(p, &session_key);
680 if (!NT_STATUS_IS_OK(status)) {
681 printf("SetUserInfo level %u - no session key - %s\n",
682 s.in.level, nt_errstr(status));
686 /* This should break the key nicely */
687 session_key.length--;
688 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
690 torture_comment(tctx, "Testing SetUserInfo level 23 (set password) with wrong password\n");
692 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
693 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
694 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
695 s.in.level, nt_errstr(status));
703 static bool test_SetUserPassEx(struct dcerpc_pipe *p, struct torture_context *tctx,
704 struct policy_handle *handle, bool makeshort,
708 struct samr_SetUserInfo s;
709 union samr_UserInfo u;
711 DATA_BLOB session_key;
712 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
713 uint8_t confounder[16];
715 struct MD5Context ctx;
716 struct samr_GetUserPwInfo pwp;
717 struct samr_PwInfo info;
718 int policy_min_pw_len = 0;
719 pwp.in.user_handle = handle;
720 pwp.out.info = &info;
722 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
723 if (NT_STATUS_IS_OK(status)) {
724 policy_min_pw_len = pwp.out.info->min_password_length;
726 if (makeshort && policy_min_pw_len) {
727 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len - 1);
729 newpass = samr_rand_pass(tctx, policy_min_pw_len);
732 s.in.user_handle = handle;
736 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
737 u.info26.password_expired = 0;
739 status = dcerpc_fetch_session_key(p, &session_key);
740 if (!NT_STATUS_IS_OK(status)) {
741 printf("SetUserInfo level %u - no session key - %s\n",
742 s.in.level, nt_errstr(status));
746 generate_random_buffer((uint8_t *)confounder, 16);
749 MD5Update(&ctx, confounder, 16);
750 MD5Update(&ctx, session_key.data, session_key.length);
751 MD5Final(confounded_session_key.data, &ctx);
753 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
754 memcpy(&u.info26.password.data[516], confounder, 16);
756 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex)\n");
758 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
759 if (!NT_STATUS_IS_OK(status)) {
760 printf("SetUserInfo level %u failed - %s\n",
761 s.in.level, nt_errstr(status));
767 /* This should break the key nicely */
768 confounded_session_key.data[0]++;
770 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
771 memcpy(&u.info26.password.data[516], confounder, 16);
773 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
775 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
776 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
777 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
778 s.in.level, nt_errstr(status));
787 static bool test_SetUserPass_25(struct dcerpc_pipe *p, struct torture_context *tctx,
788 struct policy_handle *handle, uint32_t fields_present,
792 struct samr_SetUserInfo s;
793 union samr_UserInfo u;
795 DATA_BLOB session_key;
796 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
797 struct MD5Context ctx;
798 uint8_t confounder[16];
800 struct samr_GetUserPwInfo pwp;
801 struct samr_PwInfo info;
802 int policy_min_pw_len = 0;
803 pwp.in.user_handle = handle;
804 pwp.out.info = &info;
806 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
807 if (NT_STATUS_IS_OK(status)) {
808 policy_min_pw_len = pwp.out.info->min_password_length;
810 newpass = samr_rand_pass(tctx, policy_min_pw_len);
812 s.in.user_handle = handle;
818 u.info25.info.fields_present = fields_present;
820 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
822 status = dcerpc_fetch_session_key(p, &session_key);
823 if (!NT_STATUS_IS_OK(status)) {
824 printf("SetUserInfo level %u - no session key - %s\n",
825 s.in.level, nt_errstr(status));
829 generate_random_buffer((uint8_t *)confounder, 16);
832 MD5Update(&ctx, confounder, 16);
833 MD5Update(&ctx, session_key.data, session_key.length);
834 MD5Final(confounded_session_key.data, &ctx);
836 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
837 memcpy(&u.info25.password.data[516], confounder, 16);
839 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex)\n");
841 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
842 if (!NT_STATUS_IS_OK(status)) {
843 printf("SetUserInfo level %u failed - %s\n",
844 s.in.level, nt_errstr(status));
850 /* This should break the key nicely */
851 confounded_session_key.data[0]++;
853 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
854 memcpy(&u.info25.password.data[516], confounder, 16);
856 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
858 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
859 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
860 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
861 s.in.level, nt_errstr(status));
868 static bool test_SetUserPass_18(struct dcerpc_pipe *p, struct torture_context *tctx,
869 struct policy_handle *handle, char **password)
872 struct samr_SetUserInfo s;
873 union samr_UserInfo u;
875 DATA_BLOB session_key;
877 struct samr_GetUserPwInfo pwp;
878 struct samr_PwInfo info;
879 int policy_min_pw_len = 0;
880 uint8_t lm_hash[16], nt_hash[16];
882 pwp.in.user_handle = handle;
883 pwp.out.info = &info;
885 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
886 if (NT_STATUS_IS_OK(status)) {
887 policy_min_pw_len = pwp.out.info->min_password_length;
889 newpass = samr_rand_pass(tctx, policy_min_pw_len);
891 s.in.user_handle = handle;
897 u.info18.nt_pwd_active = true;
898 u.info18.lm_pwd_active = true;
900 E_md4hash(newpass, nt_hash);
901 E_deshash(newpass, lm_hash);
903 status = dcerpc_fetch_session_key(p, &session_key);
904 if (!NT_STATUS_IS_OK(status)) {
905 printf("SetUserInfo level %u - no session key - %s\n",
906 s.in.level, nt_errstr(status));
912 in = data_blob_const(nt_hash, 16);
913 out = data_blob_talloc_zero(tctx, 16);
914 sess_crypt_blob(&out, &in, &session_key, true);
915 memcpy(u.info18.nt_pwd.hash, out.data, out.length);
919 in = data_blob_const(lm_hash, 16);
920 out = data_blob_talloc_zero(tctx, 16);
921 sess_crypt_blob(&out, &in, &session_key, true);
922 memcpy(u.info18.lm_pwd.hash, out.data, out.length);
925 torture_comment(tctx, "Testing SetUserInfo level 18 (set password hash)\n");
927 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
928 if (!NT_STATUS_IS_OK(status)) {
929 printf("SetUserInfo level %u failed - %s\n",
930 s.in.level, nt_errstr(status));
939 static bool test_SetUserPass_21(struct dcerpc_pipe *p, struct torture_context *tctx,
940 struct policy_handle *handle, uint32_t fields_present,
944 struct samr_SetUserInfo s;
945 union samr_UserInfo u;
947 DATA_BLOB session_key;
949 struct samr_GetUserPwInfo pwp;
950 struct samr_PwInfo info;
951 int policy_min_pw_len = 0;
952 uint8_t lm_hash[16], nt_hash[16];
954 pwp.in.user_handle = handle;
955 pwp.out.info = &info;
957 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
958 if (NT_STATUS_IS_OK(status)) {
959 policy_min_pw_len = pwp.out.info->min_password_length;
961 newpass = samr_rand_pass(tctx, policy_min_pw_len);
963 s.in.user_handle = handle;
967 E_md4hash(newpass, nt_hash);
968 E_deshash(newpass, lm_hash);
972 u.info21.fields_present = fields_present;
974 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
975 u.info21.lm_owf_password.length = 16;
976 u.info21.lm_owf_password.size = 16;
977 u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
978 u.info21.lm_password_set = true;
981 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
982 u.info21.nt_owf_password.length = 16;
983 u.info21.nt_owf_password.size = 16;
984 u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
985 u.info21.nt_password_set = true;
988 status = dcerpc_fetch_session_key(p, &session_key);
989 if (!NT_STATUS_IS_OK(status)) {
990 printf("SetUserInfo level %u - no session key - %s\n",
991 s.in.level, nt_errstr(status));
995 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
997 in = data_blob_const(u.info21.lm_owf_password.array,
998 u.info21.lm_owf_password.length);
999 out = data_blob_talloc_zero(tctx, 16);
1000 sess_crypt_blob(&out, &in, &session_key, true);
1001 u.info21.lm_owf_password.array = (uint16_t *)out.data;
1004 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1006 in = data_blob_const(u.info21.nt_owf_password.array,
1007 u.info21.nt_owf_password.length);
1008 out = data_blob_talloc_zero(tctx, 16);
1009 sess_crypt_blob(&out, &in, &session_key, true);
1010 u.info21.nt_owf_password.array = (uint16_t *)out.data;
1013 torture_comment(tctx, "Testing SetUserInfo level 21 (set password hash)\n");
1015 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1016 if (!NT_STATUS_IS_OK(status)) {
1017 printf("SetUserInfo level %u failed - %s\n",
1018 s.in.level, nt_errstr(status));
1021 *password = newpass;
1024 /* try invalid length */
1025 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1027 u.info21.nt_owf_password.length++;
1029 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1031 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1032 printf("SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1033 s.in.level, nt_errstr(status));
1038 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1040 u.info21.lm_owf_password.length++;
1042 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1044 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1045 printf("SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1046 s.in.level, nt_errstr(status));
1054 static bool test_SetUserPass_level_ex(struct dcerpc_pipe *p,
1055 struct torture_context *tctx,
1056 struct policy_handle *handle,
1058 uint32_t fields_present,
1059 char **password, uint8_t password_expired,
1061 bool *matched_expected_error)
1064 NTSTATUS expected_error = NT_STATUS_OK;
1065 struct samr_SetUserInfo s;
1066 struct samr_SetUserInfo2 s2;
1067 union samr_UserInfo u;
1069 DATA_BLOB session_key;
1070 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
1071 struct MD5Context ctx;
1072 uint8_t confounder[16];
1074 struct samr_GetUserPwInfo pwp;
1075 struct samr_PwInfo info;
1076 int policy_min_pw_len = 0;
1077 const char *comment = NULL;
1078 uint8_t lm_hash[16], nt_hash[16];
1080 pwp.in.user_handle = handle;
1081 pwp.out.info = &info;
1083 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1084 if (NT_STATUS_IS_OK(status)) {
1085 policy_min_pw_len = pwp.out.info->min_password_length;
1087 newpass = samr_rand_pass_silent(tctx, policy_min_pw_len);
1090 s2.in.user_handle = handle;
1092 s2.in.level = level;
1094 s.in.user_handle = handle;
1099 if (fields_present & SAMR_FIELD_COMMENT) {
1100 comment = talloc_asprintf(tctx, "comment: %ld\n", time(NULL));
1107 E_md4hash(newpass, nt_hash);
1108 E_deshash(newpass, lm_hash);
1110 u.info18.nt_pwd_active = true;
1111 u.info18.lm_pwd_active = true;
1112 u.info18.password_expired = password_expired;
1114 memcpy(u.info18.lm_pwd.hash, lm_hash, 16);
1115 memcpy(u.info18.nt_pwd.hash, nt_hash, 16);
1119 E_md4hash(newpass, nt_hash);
1120 E_deshash(newpass, lm_hash);
1122 u.info21.fields_present = fields_present;
1123 u.info21.password_expired = password_expired;
1124 u.info21.comment.string = comment;
1126 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1127 u.info21.lm_owf_password.length = 16;
1128 u.info21.lm_owf_password.size = 16;
1129 u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
1130 u.info21.lm_password_set = true;
1133 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1134 u.info21.nt_owf_password.length = 16;
1135 u.info21.nt_owf_password.size = 16;
1136 u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
1137 u.info21.nt_password_set = true;
1142 u.info23.info.fields_present = fields_present;
1143 u.info23.info.password_expired = password_expired;
1144 u.info23.info.comment.string = comment;
1146 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
1150 u.info24.password_expired = password_expired;
1152 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
1156 u.info25.info.fields_present = fields_present;
1157 u.info25.info.password_expired = password_expired;
1158 u.info25.info.comment.string = comment;
1160 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
1164 u.info26.password_expired = password_expired;
1166 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
1171 status = dcerpc_fetch_session_key(p, &session_key);
1172 if (!NT_STATUS_IS_OK(status)) {
1173 printf("SetUserInfo level %u - no session key - %s\n",
1174 s.in.level, nt_errstr(status));
1178 generate_random_buffer((uint8_t *)confounder, 16);
1181 MD5Update(&ctx, confounder, 16);
1182 MD5Update(&ctx, session_key.data, session_key.length);
1183 MD5Final(confounded_session_key.data, &ctx);
1189 in = data_blob_const(u.info18.nt_pwd.hash, 16);
1190 out = data_blob_talloc_zero(tctx, 16);
1191 sess_crypt_blob(&out, &in, &session_key, true);
1192 memcpy(u.info18.nt_pwd.hash, out.data, out.length);
1196 in = data_blob_const(u.info18.lm_pwd.hash, 16);
1197 out = data_blob_talloc_zero(tctx, 16);
1198 sess_crypt_blob(&out, &in, &session_key, true);
1199 memcpy(u.info18.lm_pwd.hash, out.data, out.length);
1204 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1206 in = data_blob_const(u.info21.lm_owf_password.array,
1207 u.info21.lm_owf_password.length);
1208 out = data_blob_talloc_zero(tctx, 16);
1209 sess_crypt_blob(&out, &in, &session_key, true);
1210 u.info21.lm_owf_password.array = (uint16_t *)out.data;
1212 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1214 in = data_blob_const(u.info21.nt_owf_password.array,
1215 u.info21.nt_owf_password.length);
1216 out = data_blob_talloc_zero(tctx, 16);
1217 sess_crypt_blob(&out, &in, &session_key, true);
1218 u.info21.nt_owf_password.array = (uint16_t *)out.data;
1222 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
1225 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
1228 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
1229 memcpy(&u.info25.password.data[516], confounder, 16);
1232 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
1233 memcpy(&u.info26.password.data[516], confounder, 16);
1238 status = dcerpc_samr_SetUserInfo2(p, tctx, &s2);
1240 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1243 if (!NT_STATUS_IS_OK(status)) {
1244 if (fields_present == 0) {
1245 expected_error = NT_STATUS_INVALID_PARAMETER;
1247 if (fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
1248 expected_error = NT_STATUS_ACCESS_DENIED;
1252 if (!NT_STATUS_IS_OK(expected_error)) {
1254 torture_assert_ntstatus_equal(tctx,
1256 expected_error, "SetUserInfo2 failed");
1258 torture_assert_ntstatus_equal(tctx,
1260 expected_error, "SetUserInfo failed");
1262 *matched_expected_error = true;
1266 if (!NT_STATUS_IS_OK(status)) {
1267 printf("SetUserInfo%s level %u failed - %s\n",
1268 use_setinfo2 ? "2":"", level, nt_errstr(status));
1271 *password = newpass;
1277 static bool test_SetAliasInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1278 struct policy_handle *handle)
1281 struct samr_SetAliasInfo r;
1282 struct samr_QueryAliasInfo q;
1283 union samr_AliasInfo *info;
1284 uint16_t levels[] = {2, 3};
1288 /* Ignoring switch level 1, as that includes the number of members for the alias
1289 * and setting this to a wrong value might have negative consequences
1292 for (i=0;i<ARRAY_SIZE(levels);i++) {
1293 torture_comment(tctx, "Testing SetAliasInfo level %u\n", levels[i]);
1295 r.in.alias_handle = handle;
1296 r.in.level = levels[i];
1297 r.in.info = talloc(tctx, union samr_AliasInfo);
1298 switch (r.in.level) {
1299 case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
1300 case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
1301 "Test Description, should test I18N as well"); break;
1302 case ALIASINFOALL: printf("ALIASINFOALL ignored\n"); break;
1305 status = dcerpc_samr_SetAliasInfo(p, tctx, &r);
1306 if (!NT_STATUS_IS_OK(status)) {
1307 printf("SetAliasInfo level %u failed - %s\n",
1308 levels[i], nt_errstr(status));
1312 q.in.alias_handle = handle;
1313 q.in.level = levels[i];
1316 status = dcerpc_samr_QueryAliasInfo(p, tctx, &q);
1317 if (!NT_STATUS_IS_OK(status)) {
1318 printf("QueryAliasInfo level %u failed - %s\n",
1319 levels[i], nt_errstr(status));
1327 static bool test_GetGroupsForUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1328 struct policy_handle *user_handle)
1330 struct samr_GetGroupsForUser r;
1331 struct samr_RidWithAttributeArray *rids = NULL;
1334 torture_comment(tctx, "testing GetGroupsForUser\n");
1336 r.in.user_handle = user_handle;
1339 status = dcerpc_samr_GetGroupsForUser(p, tctx, &r);
1340 torture_assert_ntstatus_ok(tctx, status, "GetGroupsForUser");
1346 static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1347 struct lsa_String *domain_name)
1350 struct samr_GetDomPwInfo r;
1351 struct samr_PwInfo info;
1353 r.in.domain_name = domain_name;
1356 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1358 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1359 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1361 r.in.domain_name->string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1362 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1364 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1365 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1367 r.in.domain_name->string = "\\\\__NONAME__";
1368 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1370 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1371 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1373 r.in.domain_name->string = "\\\\Builtin";
1374 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1376 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1377 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1382 static bool test_GetUserPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1383 struct policy_handle *handle)
1386 struct samr_GetUserPwInfo r;
1387 struct samr_PwInfo info;
1389 torture_comment(tctx, "Testing GetUserPwInfo\n");
1391 r.in.user_handle = handle;
1394 status = dcerpc_samr_GetUserPwInfo(p, tctx, &r);
1395 torture_assert_ntstatus_ok(tctx, status, "GetUserPwInfo");
1400 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, struct torture_context *tctx,
1401 struct policy_handle *domain_handle, const char *name,
1405 struct samr_LookupNames n;
1406 struct lsa_String sname[2];
1407 struct samr_Ids rids, types;
1409 init_lsa_String(&sname[0], name);
1411 n.in.domain_handle = domain_handle;
1415 n.out.types = &types;
1416 status = dcerpc_samr_LookupNames(p, tctx, &n);
1417 if (NT_STATUS_IS_OK(status)) {
1418 *rid = n.out.rids->ids[0];
1423 init_lsa_String(&sname[1], "xxNONAMExx");
1425 status = dcerpc_samr_LookupNames(p, tctx, &n);
1426 if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
1427 printf("LookupNames[2] failed - %s\n", nt_errstr(status));
1428 if (NT_STATUS_IS_OK(status)) {
1429 return NT_STATUS_UNSUCCESSFUL;
1435 status = dcerpc_samr_LookupNames(p, tctx, &n);
1436 if (!NT_STATUS_IS_OK(status)) {
1437 printf("LookupNames[0] failed - %s\n", nt_errstr(status));
1441 init_lsa_String(&sname[0], "xxNONAMExx");
1443 status = dcerpc_samr_LookupNames(p, tctx, &n);
1444 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1445 printf("LookupNames[1 bad name] failed - %s\n", nt_errstr(status));
1446 if (NT_STATUS_IS_OK(status)) {
1447 return NT_STATUS_UNSUCCESSFUL;
1452 init_lsa_String(&sname[0], "xxNONAMExx");
1453 init_lsa_String(&sname[1], "xxNONAME2xx");
1455 status = dcerpc_samr_LookupNames(p, tctx, &n);
1456 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1457 printf("LookupNames[2 bad names] failed - %s\n", nt_errstr(status));
1458 if (NT_STATUS_IS_OK(status)) {
1459 return NT_STATUS_UNSUCCESSFUL;
1464 return NT_STATUS_OK;
1467 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1468 struct policy_handle *domain_handle,
1469 const char *name, struct policy_handle *user_handle)
1472 struct samr_OpenUser r;
1475 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
1476 if (!NT_STATUS_IS_OK(status)) {
1480 r.in.domain_handle = domain_handle;
1481 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1483 r.out.user_handle = user_handle;
1484 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
1485 if (!NT_STATUS_IS_OK(status)) {
1486 printf("OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(status));
1493 static bool test_ChangePasswordNT3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1494 struct policy_handle *handle)
1497 struct samr_ChangePasswordUser r;
1499 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1500 struct policy_handle user_handle;
1501 char *oldpass = "test";
1502 char *newpass = "test2";
1503 uint8_t old_nt_hash[16], new_nt_hash[16];
1504 uint8_t old_lm_hash[16], new_lm_hash[16];
1506 status = test_OpenUser_byname(p, mem_ctx, handle, "testuser", &user_handle);
1507 if (!NT_STATUS_IS_OK(status)) {
1511 printf("Testing ChangePasswordUser for user 'testuser'\n");
1513 printf("old password: %s\n", oldpass);
1514 printf("new password: %s\n", newpass);
1516 E_md4hash(oldpass, old_nt_hash);
1517 E_md4hash(newpass, new_nt_hash);
1518 E_deshash(oldpass, old_lm_hash);
1519 E_deshash(newpass, new_lm_hash);
1521 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1522 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1523 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1524 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1525 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1526 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1528 r.in.handle = &user_handle;
1529 r.in.lm_present = 1;
1530 r.in.old_lm_crypted = &hash1;
1531 r.in.new_lm_crypted = &hash2;
1532 r.in.nt_present = 1;
1533 r.in.old_nt_crypted = &hash3;
1534 r.in.new_nt_crypted = &hash4;
1535 r.in.cross1_present = 1;
1536 r.in.nt_cross = &hash5;
1537 r.in.cross2_present = 1;
1538 r.in.lm_cross = &hash6;
1540 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1541 if (!NT_STATUS_IS_OK(status)) {
1542 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1546 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1554 static bool test_ChangePasswordUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1555 const char *acct_name,
1556 struct policy_handle *handle, char **password)
1559 struct samr_ChangePasswordUser r;
1561 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1562 struct policy_handle user_handle;
1564 uint8_t old_nt_hash[16], new_nt_hash[16];
1565 uint8_t old_lm_hash[16], new_lm_hash[16];
1566 bool changed = true;
1569 struct samr_GetUserPwInfo pwp;
1570 struct samr_PwInfo info;
1571 int policy_min_pw_len = 0;
1573 status = test_OpenUser_byname(p, tctx, handle, acct_name, &user_handle);
1574 if (!NT_STATUS_IS_OK(status)) {
1577 pwp.in.user_handle = &user_handle;
1578 pwp.out.info = &info;
1580 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1581 if (NT_STATUS_IS_OK(status)) {
1582 policy_min_pw_len = pwp.out.info->min_password_length;
1584 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1586 torture_comment(tctx, "Testing ChangePasswordUser\n");
1588 torture_assert(tctx, *password != NULL,
1589 "Failing ChangePasswordUser as old password was NULL. Previous test failed?");
1591 oldpass = *password;
1593 E_md4hash(oldpass, old_nt_hash);
1594 E_md4hash(newpass, new_nt_hash);
1595 E_deshash(oldpass, old_lm_hash);
1596 E_deshash(newpass, new_lm_hash);
1598 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1599 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1600 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1601 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1602 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1603 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1605 r.in.user_handle = &user_handle;
1606 r.in.lm_present = 1;
1607 /* Break the LM hash */
1609 r.in.old_lm_crypted = &hash1;
1610 r.in.new_lm_crypted = &hash2;
1611 r.in.nt_present = 1;
1612 r.in.old_nt_crypted = &hash3;
1613 r.in.new_nt_crypted = &hash4;
1614 r.in.cross1_present = 1;
1615 r.in.nt_cross = &hash5;
1616 r.in.cross2_present = 1;
1617 r.in.lm_cross = &hash6;
1619 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1620 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1621 "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash");
1623 /* Unbreak the LM hash */
1626 r.in.user_handle = &user_handle;
1627 r.in.lm_present = 1;
1628 r.in.old_lm_crypted = &hash1;
1629 r.in.new_lm_crypted = &hash2;
1630 /* Break the NT hash */
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 "expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash");
1644 /* Unbreak the NT 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 r.in.nt_present = 1;
1652 r.in.old_nt_crypted = &hash3;
1653 r.in.new_nt_crypted = &hash4;
1654 r.in.cross1_present = 1;
1655 r.in.nt_cross = &hash5;
1656 r.in.cross2_present = 1;
1657 /* Break the LM cross */
1659 r.in.lm_cross = &hash6;
1661 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1662 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1663 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status));
1667 /* Unbreak the LM cross */
1670 r.in.user_handle = &user_handle;
1671 r.in.lm_present = 1;
1672 r.in.old_lm_crypted = &hash1;
1673 r.in.new_lm_crypted = &hash2;
1674 r.in.nt_present = 1;
1675 r.in.old_nt_crypted = &hash3;
1676 r.in.new_nt_crypted = &hash4;
1677 r.in.cross1_present = 1;
1678 /* Break the NT cross */
1680 r.in.nt_cross = &hash5;
1681 r.in.cross2_present = 1;
1682 r.in.lm_cross = &hash6;
1684 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1685 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1686 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status));
1690 /* Unbreak the NT cross */
1694 /* Reset the hashes to not broken values */
1695 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1696 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1697 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1698 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1699 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1700 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1702 r.in.user_handle = &user_handle;
1703 r.in.lm_present = 1;
1704 r.in.old_lm_crypted = &hash1;
1705 r.in.new_lm_crypted = &hash2;
1706 r.in.nt_present = 1;
1707 r.in.old_nt_crypted = &hash3;
1708 r.in.new_nt_crypted = &hash4;
1709 r.in.cross1_present = 1;
1710 r.in.nt_cross = &hash5;
1711 r.in.cross2_present = 0;
1712 r.in.lm_cross = NULL;
1714 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1715 if (NT_STATUS_IS_OK(status)) {
1717 *password = newpass;
1718 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1719 printf("ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(status));
1724 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1726 E_md4hash(oldpass, old_nt_hash);
1727 E_md4hash(newpass, new_nt_hash);
1728 E_deshash(oldpass, old_lm_hash);
1729 E_deshash(newpass, new_lm_hash);
1732 /* Reset the hashes to not broken values */
1733 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1734 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1735 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1736 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1737 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1738 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1740 r.in.user_handle = &user_handle;
1741 r.in.lm_present = 1;
1742 r.in.old_lm_crypted = &hash1;
1743 r.in.new_lm_crypted = &hash2;
1744 r.in.nt_present = 1;
1745 r.in.old_nt_crypted = &hash3;
1746 r.in.new_nt_crypted = &hash4;
1747 r.in.cross1_present = 0;
1748 r.in.nt_cross = NULL;
1749 r.in.cross2_present = 1;
1750 r.in.lm_cross = &hash6;
1752 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1753 if (NT_STATUS_IS_OK(status)) {
1755 *password = newpass;
1756 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1757 printf("ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status));
1762 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1764 E_md4hash(oldpass, old_nt_hash);
1765 E_md4hash(newpass, new_nt_hash);
1766 E_deshash(oldpass, old_lm_hash);
1767 E_deshash(newpass, new_lm_hash);
1770 /* Reset the hashes to not broken values */
1771 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1772 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1773 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1774 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1775 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1776 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1778 r.in.user_handle = &user_handle;
1779 r.in.lm_present = 1;
1780 r.in.old_lm_crypted = &hash1;
1781 r.in.new_lm_crypted = &hash2;
1782 r.in.nt_present = 1;
1783 r.in.old_nt_crypted = &hash3;
1784 r.in.new_nt_crypted = &hash4;
1785 r.in.cross1_present = 1;
1786 r.in.nt_cross = &hash5;
1787 r.in.cross2_present = 1;
1788 r.in.lm_cross = &hash6;
1790 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1791 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1792 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1793 } else if (!NT_STATUS_IS_OK(status)) {
1794 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1798 *password = newpass;
1801 r.in.user_handle = &user_handle;
1802 r.in.lm_present = 1;
1803 r.in.old_lm_crypted = &hash1;
1804 r.in.new_lm_crypted = &hash2;
1805 r.in.nt_present = 1;
1806 r.in.old_nt_crypted = &hash3;
1807 r.in.new_nt_crypted = &hash4;
1808 r.in.cross1_present = 1;
1809 r.in.nt_cross = &hash5;
1810 r.in.cross2_present = 1;
1811 r.in.lm_cross = &hash6;
1814 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1815 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1816 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1817 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1818 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status));
1824 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
1832 static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
1833 const char *acct_name,
1834 struct policy_handle *handle, char **password)
1837 struct samr_OemChangePasswordUser2 r;
1839 struct samr_Password lm_verifier;
1840 struct samr_CryptPassword lm_pass;
1841 struct lsa_AsciiString server, account, account_bad;
1844 uint8_t old_lm_hash[16], new_lm_hash[16];
1846 struct samr_GetDomPwInfo dom_pw_info;
1847 struct samr_PwInfo info;
1848 int policy_min_pw_len = 0;
1850 struct lsa_String domain_name;
1852 domain_name.string = "";
1853 dom_pw_info.in.domain_name = &domain_name;
1854 dom_pw_info.out.info = &info;
1856 torture_comment(tctx, "Testing OemChangePasswordUser2\n");
1858 torture_assert(tctx, *password != NULL,
1859 "Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?");
1861 oldpass = *password;
1863 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
1864 if (NT_STATUS_IS_OK(status)) {
1865 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
1868 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1870 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1871 account.string = acct_name;
1873 E_deshash(oldpass, old_lm_hash);
1874 E_deshash(newpass, new_lm_hash);
1876 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1877 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1878 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1880 r.in.server = &server;
1881 r.in.account = &account;
1882 r.in.password = &lm_pass;
1883 r.in.hash = &lm_verifier;
1885 /* Break the verification */
1886 lm_verifier.hash[0]++;
1888 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1890 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1891 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1892 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1897 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1898 /* Break the old password */
1900 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1901 /* unbreak it for the next operation */
1903 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1905 r.in.server = &server;
1906 r.in.account = &account;
1907 r.in.password = &lm_pass;
1908 r.in.hash = &lm_verifier;
1910 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1912 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1913 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1914 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1919 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1920 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1922 r.in.server = &server;
1923 r.in.account = &account;
1924 r.in.password = &lm_pass;
1927 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1929 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1930 && !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1931 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
1936 /* This shouldn't be a valid name */
1937 account_bad.string = TEST_ACCOUNT_NAME "XX";
1938 r.in.account = &account_bad;
1940 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1942 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1943 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
1948 /* This shouldn't be a valid name */
1949 account_bad.string = TEST_ACCOUNT_NAME "XX";
1950 r.in.account = &account_bad;
1951 r.in.password = &lm_pass;
1952 r.in.hash = &lm_verifier;
1954 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1956 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1957 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1962 /* This shouldn't be a valid name */
1963 account_bad.string = TEST_ACCOUNT_NAME "XX";
1964 r.in.account = &account_bad;
1965 r.in.password = NULL;
1966 r.in.hash = &lm_verifier;
1968 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1970 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1971 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
1976 E_deshash(oldpass, old_lm_hash);
1977 E_deshash(newpass, new_lm_hash);
1979 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1980 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1981 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1983 r.in.server = &server;
1984 r.in.account = &account;
1985 r.in.password = &lm_pass;
1986 r.in.hash = &lm_verifier;
1988 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1989 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1990 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1991 } else if (!NT_STATUS_IS_OK(status)) {
1992 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
1995 *password = newpass;
2002 static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
2003 const char *acct_name,
2005 char *newpass, bool allow_password_restriction)
2008 struct samr_ChangePasswordUser2 r;
2010 struct lsa_String server, account;
2011 struct samr_CryptPassword nt_pass, lm_pass;
2012 struct samr_Password nt_verifier, lm_verifier;
2014 uint8_t old_nt_hash[16], new_nt_hash[16];
2015 uint8_t old_lm_hash[16], new_lm_hash[16];
2017 struct samr_GetDomPwInfo dom_pw_info;
2018 struct samr_PwInfo info;
2020 struct lsa_String domain_name;
2022 domain_name.string = "";
2023 dom_pw_info.in.domain_name = &domain_name;
2024 dom_pw_info.out.info = &info;
2026 torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name);
2028 torture_assert(tctx, *password != NULL,
2029 "Failing ChangePasswordUser2 as old password was NULL. Previous test failed?");
2030 oldpass = *password;
2033 int policy_min_pw_len = 0;
2034 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
2035 if (NT_STATUS_IS_OK(status)) {
2036 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
2039 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2042 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2043 init_lsa_String(&account, acct_name);
2045 E_md4hash(oldpass, old_nt_hash);
2046 E_md4hash(newpass, new_nt_hash);
2048 E_deshash(oldpass, old_lm_hash);
2049 E_deshash(newpass, new_lm_hash);
2051 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
2052 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2053 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2055 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2056 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2057 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2059 r.in.server = &server;
2060 r.in.account = &account;
2061 r.in.nt_password = &nt_pass;
2062 r.in.nt_verifier = &nt_verifier;
2064 r.in.lm_password = &lm_pass;
2065 r.in.lm_verifier = &lm_verifier;
2067 status = dcerpc_samr_ChangePasswordUser2(p, tctx, &r);
2068 if (allow_password_restriction && NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2069 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
2070 } else if (!NT_STATUS_IS_OK(status)) {
2071 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
2074 *password = newpass;
2081 bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tctx,
2082 const char *account_string,
2083 int policy_min_pw_len,
2085 const char *newpass,
2086 NTTIME last_password_change,
2087 bool handle_reject_reason)
2090 struct samr_ChangePasswordUser3 r;
2092 struct lsa_String server, account, account_bad;
2093 struct samr_CryptPassword nt_pass, lm_pass;
2094 struct samr_Password nt_verifier, lm_verifier;
2096 uint8_t old_nt_hash[16], new_nt_hash[16];
2097 uint8_t old_lm_hash[16], new_lm_hash[16];
2099 struct samr_DomInfo1 *dominfo = NULL;
2100 struct samr_ChangeReject *reject = NULL;
2102 torture_comment(tctx, "Testing ChangePasswordUser3\n");
2104 if (newpass == NULL) {
2106 if (policy_min_pw_len == 0) {
2107 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2109 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len);
2111 } while (check_password_quality(newpass) == false);
2113 torture_comment(tctx, "Using password '%s'\n", newpass);
2116 torture_assert(tctx, *password != NULL,
2117 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2119 oldpass = *password;
2120 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2121 init_lsa_String(&account, account_string);
2123 E_md4hash(oldpass, old_nt_hash);
2124 E_md4hash(newpass, new_nt_hash);
2126 E_deshash(oldpass, old_lm_hash);
2127 E_deshash(newpass, new_lm_hash);
2129 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2130 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2131 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2133 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2134 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2135 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2137 /* Break the verification */
2138 nt_verifier.hash[0]++;
2140 r.in.server = &server;
2141 r.in.account = &account;
2142 r.in.nt_password = &nt_pass;
2143 r.in.nt_verifier = &nt_verifier;
2145 r.in.lm_password = &lm_pass;
2146 r.in.lm_verifier = &lm_verifier;
2147 r.in.password3 = NULL;
2148 r.out.dominfo = &dominfo;
2149 r.out.reject = &reject;
2151 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2152 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
2153 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
2154 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
2159 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2160 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2161 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2163 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2164 /* Break the NT hash */
2166 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2167 /* Unbreak it again */
2169 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2171 r.in.server = &server;
2172 r.in.account = &account;
2173 r.in.nt_password = &nt_pass;
2174 r.in.nt_verifier = &nt_verifier;
2176 r.in.lm_password = &lm_pass;
2177 r.in.lm_verifier = &lm_verifier;
2178 r.in.password3 = NULL;
2179 r.out.dominfo = &dominfo;
2180 r.out.reject = &reject;
2182 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2183 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
2184 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
2185 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
2190 /* This shouldn't be a valid name */
2191 init_lsa_String(&account_bad, talloc_asprintf(tctx, "%sXX", account_string));
2193 r.in.account = &account_bad;
2194 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2195 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
2196 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
2201 E_md4hash(oldpass, old_nt_hash);
2202 E_md4hash(newpass, new_nt_hash);
2204 E_deshash(oldpass, old_lm_hash);
2205 E_deshash(newpass, new_lm_hash);
2207 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2208 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2209 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2211 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2212 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2213 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2215 r.in.server = &server;
2216 r.in.account = &account;
2217 r.in.nt_password = &nt_pass;
2218 r.in.nt_verifier = &nt_verifier;
2220 r.in.lm_password = &lm_pass;
2221 r.in.lm_verifier = &lm_verifier;
2222 r.in.password3 = NULL;
2223 r.out.dominfo = &dominfo;
2224 r.out.reject = &reject;
2226 unix_to_nt_time(&t, time(NULL));
2228 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2230 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
2233 && handle_reject_reason
2234 && (!null_nttime(last_password_change) || !dominfo->min_password_age)) {
2235 if (dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
2237 if (reject && (reject->reason != SAMR_REJECT_OTHER)) {
2238 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2239 SAMR_REJECT_OTHER, reject->reason);
2244 /* We tested the order of precendence which is as follows:
2253 if ((dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
2254 (last_password_change + dominfo->min_password_age > t)) {
2256 if (reject->reason != SAMR_REJECT_OTHER) {
2257 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2258 SAMR_REJECT_OTHER, reject->reason);
2262 } else if ((dominfo->min_password_length > 0) &&
2263 (strlen(newpass) < dominfo->min_password_length)) {
2265 if (reject->reason != SAMR_REJECT_TOO_SHORT) {
2266 printf("expected SAMR_REJECT_TOO_SHORT (%d), got %d\n",
2267 SAMR_REJECT_TOO_SHORT, reject->reason);
2271 } else if ((dominfo->password_history_length > 0) &&
2272 strequal(oldpass, newpass)) {
2274 if (reject->reason != SAMR_REJECT_IN_HISTORY) {
2275 printf("expected SAMR_REJECT_IN_HISTORY (%d), got %d\n",
2276 SAMR_REJECT_IN_HISTORY, reject->reason);
2279 } else if (dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
2281 if (reject->reason != SAMR_REJECT_COMPLEXITY) {
2282 printf("expected SAMR_REJECT_COMPLEXITY (%d), got %d\n",
2283 SAMR_REJECT_COMPLEXITY, reject->reason);
2289 if (reject->reason == SAMR_REJECT_TOO_SHORT) {
2290 /* retry with adjusted size */
2291 return test_ChangePasswordUser3(p, tctx, account_string,
2292 dominfo->min_password_length,
2293 password, NULL, 0, false);
2297 } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2298 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2299 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2300 SAMR_REJECT_OTHER, reject->reason);
2303 /* Perhaps the server has a 'min password age' set? */
2306 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3");
2307 *password = talloc_strdup(tctx, newpass);
2313 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_context *tctx,
2314 const char *account_string,
2315 struct policy_handle *handle,
2319 struct samr_ChangePasswordUser3 r;
2320 struct samr_SetUserInfo s;
2321 union samr_UserInfo u;
2322 DATA_BLOB session_key;
2323 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
2324 uint8_t confounder[16];
2325 struct MD5Context ctx;
2328 struct lsa_String server, account;
2329 struct samr_CryptPassword nt_pass;
2330 struct samr_Password nt_verifier;
2331 DATA_BLOB new_random_pass;
2334 uint8_t old_nt_hash[16], new_nt_hash[16];
2336 struct samr_DomInfo1 *dominfo = NULL;
2337 struct samr_ChangeReject *reject = NULL;
2339 new_random_pass = samr_very_rand_pass(tctx, 128);
2341 torture_assert(tctx, *password != NULL,
2342 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2344 oldpass = *password;
2345 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2346 init_lsa_String(&account, account_string);
2348 s.in.user_handle = handle;
2354 u.info25.info.fields_present = SAMR_FIELD_NT_PASSWORD_PRESENT;
2356 set_pw_in_buffer(u.info25.password.data, &new_random_pass);
2358 status = dcerpc_fetch_session_key(p, &session_key);
2359 if (!NT_STATUS_IS_OK(status)) {
2360 printf("SetUserInfo level %u - no session key - %s\n",
2361 s.in.level, nt_errstr(status));
2365 generate_random_buffer((uint8_t *)confounder, 16);
2368 MD5Update(&ctx, confounder, 16);
2369 MD5Update(&ctx, session_key.data, session_key.length);
2370 MD5Final(confounded_session_key.data, &ctx);
2372 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
2373 memcpy(&u.info25.password.data[516], confounder, 16);
2375 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
2377 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
2378 if (!NT_STATUS_IS_OK(status)) {
2379 printf("SetUserInfo level %u failed - %s\n",
2380 s.in.level, nt_errstr(status));
2384 torture_comment(tctx, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
2386 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2388 new_random_pass = samr_very_rand_pass(tctx, 128);
2390 mdfour(new_nt_hash, new_random_pass.data, new_random_pass.length);
2392 set_pw_in_buffer(nt_pass.data, &new_random_pass);
2393 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2394 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2396 r.in.server = &server;
2397 r.in.account = &account;
2398 r.in.nt_password = &nt_pass;
2399 r.in.nt_verifier = &nt_verifier;
2401 r.in.lm_password = NULL;
2402 r.in.lm_verifier = NULL;
2403 r.in.password3 = NULL;
2404 r.out.dominfo = &dominfo;
2405 r.out.reject = &reject;
2407 unix_to_nt_time(&t, time(NULL));
2409 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2411 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2412 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2413 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2414 SAMR_REJECT_OTHER, reject->reason);
2417 /* Perhaps the server has a 'min password age' set? */
2419 } else if (!NT_STATUS_IS_OK(status)) {
2420 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
2424 newpass = samr_rand_pass(tctx, 128);
2426 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2428 E_md4hash(newpass, new_nt_hash);
2430 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2431 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2432 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2434 r.in.server = &server;
2435 r.in.account = &account;
2436 r.in.nt_password = &nt_pass;
2437 r.in.nt_verifier = &nt_verifier;
2439 r.in.lm_password = NULL;
2440 r.in.lm_verifier = NULL;
2441 r.in.password3 = NULL;
2442 r.out.dominfo = &dominfo;
2443 r.out.reject = &reject;
2445 unix_to_nt_time(&t, time(NULL));
2447 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2449 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2450 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2451 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2452 SAMR_REJECT_OTHER, reject->reason);
2455 /* Perhaps the server has a 'min password age' set? */
2458 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3 (on second random password)");
2459 *password = talloc_strdup(tctx, newpass);
2466 static bool test_GetMembersInAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2467 struct policy_handle *alias_handle)
2469 struct samr_GetMembersInAlias r;
2470 struct lsa_SidArray sids;
2473 torture_comment(tctx, "Testing GetMembersInAlias\n");
2475 r.in.alias_handle = alias_handle;
2478 status = dcerpc_samr_GetMembersInAlias(p, tctx, &r);
2479 torture_assert_ntstatus_ok(tctx, status, "GetMembersInAlias");
2484 static bool test_AddMemberToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2485 struct policy_handle *alias_handle,
2486 const struct dom_sid *domain_sid)
2488 struct samr_AddAliasMember r;
2489 struct samr_DeleteAliasMember d;
2491 struct dom_sid *sid;
2493 sid = dom_sid_add_rid(tctx, domain_sid, 512);
2495 torture_comment(tctx, "testing AddAliasMember\n");
2496 r.in.alias_handle = alias_handle;
2499 status = dcerpc_samr_AddAliasMember(p, tctx, &r);
2500 torture_assert_ntstatus_ok(tctx, status, "AddAliasMember");
2502 d.in.alias_handle = alias_handle;
2505 status = dcerpc_samr_DeleteAliasMember(p, tctx, &d);
2506 torture_assert_ntstatus_ok(tctx, status, "DelAliasMember");
2511 static bool test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2512 struct policy_handle *alias_handle)
2514 struct samr_AddMultipleMembersToAlias a;
2515 struct samr_RemoveMultipleMembersFromAlias r;
2517 struct lsa_SidArray sids;
2519 torture_comment(tctx, "testing AddMultipleMembersToAlias\n");
2520 a.in.alias_handle = alias_handle;
2524 sids.sids = talloc_array(tctx, struct lsa_SidPtr, 3);
2526 sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2527 sids.sids[1].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-2");
2528 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-3");
2530 status = dcerpc_samr_AddMultipleMembersToAlias(p, tctx, &a);
2531 torture_assert_ntstatus_ok(tctx, status, "AddMultipleMembersToAlias");
2534 torture_comment(tctx, "testing RemoveMultipleMembersFromAlias\n");
2535 r.in.alias_handle = alias_handle;
2538 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2539 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2541 /* strange! removing twice doesn't give any error */
2542 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2543 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2545 /* but removing an alias that isn't there does */
2546 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-4");
2548 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2549 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, "RemoveMultipleMembersFromAlias");
2554 static bool test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2555 struct policy_handle *user_handle)
2557 struct samr_TestPrivateFunctionsUser r;
2560 torture_comment(tctx, "Testing TestPrivateFunctionsUser\n");
2562 r.in.user_handle = user_handle;
2564 status = dcerpc_samr_TestPrivateFunctionsUser(p, tctx, &r);
2565 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsUser");
2570 static bool test_QueryUserInfo_pwdlastset(struct dcerpc_pipe *p,
2571 struct torture_context *tctx,
2572 struct policy_handle *handle,
2577 uint16_t levels[] = { /* 3, */ 5, 21 };
2579 NTTIME pwdlastset3 = 0;
2580 NTTIME pwdlastset5 = 0;
2581 NTTIME pwdlastset21 = 0;
2583 torture_comment(tctx, "Testing QueryUserInfo%s level 5 and 21 call ",
2584 use_info2 ? "2":"");
2586 for (i=0; i<ARRAY_SIZE(levels); i++) {
2588 struct samr_QueryUserInfo r;
2589 struct samr_QueryUserInfo2 r2;
2590 union samr_UserInfo *info;
2593 r2.in.user_handle = handle;
2594 r2.in.level = levels[i];
2595 r2.out.info = &info;
2596 status = dcerpc_samr_QueryUserInfo2(p, tctx, &r2);
2599 r.in.user_handle = handle;
2600 r.in.level = levels[i];
2602 status = dcerpc_samr_QueryUserInfo(p, tctx, &r);
2605 if (!NT_STATUS_IS_OK(status) &&
2606 !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
2607 printf("QueryUserInfo%s level %u failed - %s\n",
2608 use_info2 ? "2":"", levels[i], nt_errstr(status));
2612 switch (levels[i]) {
2614 pwdlastset3 = info->info3.last_password_change;
2617 pwdlastset5 = info->info5.last_password_change;
2620 pwdlastset21 = info->info21.last_password_change;
2626 /* torture_assert_int_equal(tctx, pwdlastset3, pwdlastset5,
2627 "pwdlastset mixup"); */
2628 torture_assert_int_equal(tctx, pwdlastset5, pwdlastset21,
2629 "pwdlastset mixup");
2631 *pwdlastset = pwdlastset21;
2633 torture_comment(tctx, "(pwdlastset: %lld)\n", *pwdlastset);
2638 static bool test_SamLogon_Creds(struct dcerpc_pipe *p, struct torture_context *tctx,
2639 struct cli_credentials *machine_credentials,
2640 struct cli_credentials *test_credentials,
2641 struct netlogon_creds_CredentialState *creds,
2642 NTSTATUS expected_result)
2645 struct netr_LogonSamLogon r;
2646 struct netr_Authenticator auth, auth2;
2647 union netr_LogonLevel logon;
2648 union netr_Validation validation;
2649 uint8_t authoritative;
2650 struct netr_NetworkInfo ninfo;
2651 DATA_BLOB names_blob, chal, lm_resp, nt_resp;
2652 int flags = CLI_CRED_NTLM_AUTH;
2654 if (lp_client_lanman_auth(tctx->lp_ctx)) {
2655 flags |= CLI_CRED_LANMAN_AUTH;
2658 if (lp_client_ntlmv2_auth(tctx->lp_ctx)) {
2659 flags |= CLI_CRED_NTLMv2_AUTH;
2662 cli_credentials_get_ntlm_username_domain(test_credentials, tctx,
2663 &ninfo.identity_info.account_name.string,
2664 &ninfo.identity_info.domain_name.string);
2666 generate_random_buffer(ninfo.challenge,
2667 sizeof(ninfo.challenge));
2668 chal = data_blob_const(ninfo.challenge,
2669 sizeof(ninfo.challenge));
2671 names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(machine_credentials),
2672 cli_credentials_get_domain(machine_credentials));
2674 status = cli_credentials_get_ntlm_response(test_credentials, tctx,
2680 torture_assert_ntstatus_ok(tctx, status, "cli_credentials_get_ntlm_response failed");
2682 ninfo.lm.data = lm_resp.data;
2683 ninfo.lm.length = lm_resp.length;
2685 ninfo.nt.data = nt_resp.data;
2686 ninfo.nt.length = nt_resp.length;
2688 ninfo.identity_info.parameter_control =
2689 MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT |
2690 MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;
2691 ninfo.identity_info.logon_id_low = 0;
2692 ninfo.identity_info.logon_id_high = 0;
2693 ninfo.identity_info.workstation.string = cli_credentials_get_workstation(machine_credentials);
2695 logon.network = &ninfo;
2697 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2698 r.in.computer_name = cli_credentials_get_workstation(machine_credentials);
2699 r.in.credential = &auth;
2700 r.in.return_authenticator = &auth2;
2701 r.in.logon_level = 2;
2702 r.in.logon = &logon;
2703 r.out.validation = &validation;
2704 r.out.authoritative = &authoritative;
2706 d_printf("Testing LogonSamLogon with name %s\n", ninfo.identity_info.account_name.string);
2709 netlogon_creds_client_authenticator(creds, &auth);
2711 r.in.validation_level = 2;
2713 status = dcerpc_netr_LogonSamLogon(p, tctx, &r);
2714 if (!NT_STATUS_IS_OK(status)) {
2715 torture_assert_ntstatus_equal(tctx, status, expected_result, "LogonSamLogon failed");
2718 torture_assert_ntstatus_ok(tctx, status, "LogonSamLogon failed");
2721 torture_assert(tctx, netlogon_creds_client_check(creds, &r.out.return_authenticator->cred),
2722 "Credential chaining failed");
2727 static bool test_SamLogon(struct torture_context *tctx,
2728 struct dcerpc_pipe *p,
2729 struct cli_credentials *machine_credentials,
2730 struct cli_credentials *test_credentials,
2731 NTSTATUS expected_result)
2733 struct netlogon_creds_CredentialState *creds;
2735 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
2739 return test_SamLogon_Creds(p, tctx, machine_credentials, test_credentials,
2740 creds, expected_result);
2743 static bool test_SamLogon_with_creds(struct torture_context *tctx,
2744 struct dcerpc_pipe *p,
2745 struct cli_credentials *machine_creds,
2746 const char *acct_name,
2748 NTSTATUS expected_samlogon_result)
2751 struct cli_credentials *test_credentials;
2753 test_credentials = cli_credentials_init(tctx);
2755 cli_credentials_set_workstation(test_credentials,
2756 TEST_ACCOUNT_NAME_PWD, CRED_SPECIFIED);
2757 cli_credentials_set_domain(test_credentials,
2758 lp_workgroup(tctx->lp_ctx), CRED_SPECIFIED);
2759 cli_credentials_set_username(test_credentials,
2760 acct_name, CRED_SPECIFIED);
2761 cli_credentials_set_password(test_credentials,
2762 password, CRED_SPECIFIED);
2763 cli_credentials_set_secure_channel_type(test_credentials, SEC_CHAN_BDC);
2765 printf("testing samlogon as %s@%s password: %s\n",
2766 acct_name, TEST_ACCOUNT_NAME_PWD, password);
2768 if (!test_SamLogon(tctx, p, machine_creds, test_credentials,
2769 expected_samlogon_result)) {
2770 torture_warning(tctx, "new password did not work\n");
2777 static bool test_SetPassword_level(struct dcerpc_pipe *p,
2778 struct dcerpc_pipe *np,
2779 struct torture_context *tctx,
2780 struct policy_handle *handle,
2782 uint32_t fields_present,
2783 uint8_t password_expired,
2784 bool *matched_expected_error,
2786 const char *acct_name,
2788 struct cli_credentials *machine_creds,
2789 bool use_queryinfo2,
2791 NTSTATUS expected_samlogon_result)
2793 const char *fields = NULL;
2800 fields = talloc_asprintf(tctx, "(fields_present: 0x%08x)",
2807 torture_comment(tctx, "Testing SetUserInfo%s level %d call "
2808 "(password_expired: %d) %s\n",
2809 use_setinfo2 ? "2":"", level, password_expired,
2810 fields ? fields : "");
2812 if (!test_SetUserPass_level_ex(p, tctx, handle, level,
2817 matched_expected_error)) {
2821 if (!test_QueryUserInfo_pwdlastset(p, tctx, handle,
2827 if (*matched_expected_error == true) {
2831 if (!test_SamLogon_with_creds(tctx, np,
2835 expected_samlogon_result)) {
2842 static bool test_SetPassword_pwdlastset(struct dcerpc_pipe *p,
2843 struct torture_context *tctx,
2844 uint32_t acct_flags,
2845 const char *acct_name,
2846 struct policy_handle *handle,
2848 struct cli_credentials *machine_credentials)
2850 int s = 0, q = 0, f = 0, l = 0, z = 0;
2853 bool set_levels[] = { false, true };
2854 bool query_levels[] = { false, true };
2855 uint32_t levels[] = { 18, 21, 23, 24, 25, 26 };
2856 uint32_t nonzeros[] = { 1, 24 };
2857 uint32_t fields_present[] = {
2859 SAMR_FIELD_EXPIRED_FLAG,
2860 SAMR_FIELD_LAST_PWD_CHANGE,
2861 SAMR_FIELD_EXPIRED_FLAG | SAMR_FIELD_LAST_PWD_CHANGE,
2863 SAMR_FIELD_NT_PASSWORD_PRESENT,
2864 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
2865 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
2866 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
2867 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
2868 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
2869 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE | SAMR_FIELD_EXPIRED_FLAG
2872 struct dcerpc_pipe *np = NULL;
2874 if (torture_setting_bool(tctx, "samba3", false)) {
2876 printf("Samba3 has second granularity, setting delay to: %d\n",
2880 status = torture_rpc_connection(tctx, &np, &ndr_table_netlogon);
2881 if (!NT_STATUS_IS_OK(status)) {
2885 /* set to 1 to enable testing for all possible opcode
2886 (SetUserInfo, SetUserInfo2, QueryUserInfo, QueryUserInfo2)
2889 #define TEST_SET_LEVELS 1
2890 #define TEST_QUERY_LEVELS 1
2892 for (l=0; l<ARRAY_SIZE(levels); l++) {
2893 for (z=0; z<ARRAY_SIZE(nonzeros); z++) {
2894 for (f=0; f<ARRAY_SIZE(fields_present); f++) {
2895 #ifdef TEST_SET_LEVELS
2896 for (s=0; s<ARRAY_SIZE(set_levels); s++) {
2898 #ifdef TEST_QUERY_LEVELS
2899 for (q=0; q<ARRAY_SIZE(query_levels); q++) {
2901 NTTIME pwdlastset_old = 0;
2902 NTTIME pwdlastset_new = 0;
2903 bool matched_expected_error = false;
2904 NTSTATUS expected_samlogon_result = NT_STATUS_ACCOUNT_DISABLED;
2906 torture_comment(tctx, "------------------------------\n"
2907 "Testing pwdLastSet attribute for flags: 0x%08x "
2908 "(s: %d (l: %d), q: %d)\n",
2909 acct_flags, s, levels[l], q);
2911 switch (levels[l]) {
2915 if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
2916 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT))) {
2917 expected_samlogon_result = NT_STATUS_WRONG_PASSWORD;
2925 /* set a password and force password change (pwdlastset 0) by
2926 * setting the password expired flag to a non-0 value */
2928 if (!test_SetPassword_level(p, np, tctx, handle,
2932 &matched_expected_error,
2936 machine_credentials,
2939 expected_samlogon_result)) {
2943 if (matched_expected_error == true) {
2944 /* skipping on expected failure */
2948 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
2949 * set without the SAMR_FIELD_EXPIRED_FLAG */
2951 switch (levels[l]) {
2955 if ((pwdlastset_new != 0) &&
2956 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
2957 torture_comment(tctx, "not considering a non-0 "
2958 "pwdLastSet as a an error as the "
2959 "SAMR_FIELD_EXPIRED_FLAG has not "
2964 if (pwdlastset_new != 0) {
2965 torture_warning(tctx, "pwdLastSet test failed: "
2966 "expected pwdLastSet 0 but got %lld\n",
2973 switch (levels[l]) {
2977 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
2978 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
2979 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
2980 (pwdlastset_old >= pwdlastset_new)) {
2981 torture_warning(tctx, "pwdlastset not increasing\n");
2986 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
2987 (pwdlastset_old >= pwdlastset_new)) {
2988 torture_warning(tctx, "pwdlastset not increasing\n");
2998 /* set a password, pwdlastset needs to get updated (increased
2999 * value), password_expired value used here is 0 */
3001 if (!test_SetPassword_level(p, np, tctx, handle,
3005 &matched_expected_error,
3009 machine_credentials,
3012 expected_samlogon_result)) {
3016 /* when a password has been changed, pwdlastset must not be 0 afterwards
3017 * and must be larger then the old value */
3019 switch (levels[l]) {
3024 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3025 * password has been changed, old and new pwdlastset
3026 * need to be the same value */
3028 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3029 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3030 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3032 torture_assert_int_equal(tctx, pwdlastset_old,
3033 pwdlastset_new, "pwdlastset must be equal");
3037 if (pwdlastset_old >= pwdlastset_new) {
3038 torture_warning(tctx, "pwdLastSet test failed: "
3039 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
3040 pwdlastset_old, pwdlastset_new);
3043 if (pwdlastset_new == 0) {
3044 torture_warning(tctx, "pwdLastSet test failed: "
3045 "expected non-0 pwdlastset, got: %lld\n",
3051 switch (levels[l]) {
3055 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3056 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3057 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3058 (pwdlastset_old >= pwdlastset_new)) {
3059 torture_warning(tctx, "pwdlastset not increasing\n");
3064 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3065 (pwdlastset_old >= pwdlastset_new)) {
3066 torture_warning(tctx, "pwdlastset not increasing\n");
3072 pwdlastset_old = pwdlastset_new;
3078 /* set a password, pwdlastset needs to get updated (increased
3079 * value), password_expired value used here is 0 */
3081 if (!test_SetPassword_level(p, np, tctx, handle,
3085 &matched_expected_error,
3089 machine_credentials,
3092 expected_samlogon_result)) {
3096 /* when a password has been changed, pwdlastset must not be 0 afterwards
3097 * and must be larger then the old value */
3099 switch (levels[l]) {
3104 /* if no password has been changed, old and new pwdlastset
3105 * need to be the same value */
3107 if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3108 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3110 torture_assert_int_equal(tctx, pwdlastset_old,
3111 pwdlastset_new, "pwdlastset must be equal");
3115 if (pwdlastset_old >= pwdlastset_new) {
3116 torture_warning(tctx, "pwdLastSet test failed: "
3117 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
3118 pwdlastset_old, pwdlastset_new);
3121 if (pwdlastset_new == 0) {
3122 torture_warning(tctx, "pwdLastSet test failed: "
3123 "expected non-0 pwdlastset, got: %lld\n",
3131 /* set a password and force password change (pwdlastset 0) by
3132 * setting the password expired flag to a non-0 value */
3134 if (!test_SetPassword_level(p, np, tctx, handle,
3138 &matched_expected_error,
3142 machine_credentials,
3145 expected_samlogon_result)) {
3149 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3150 * set without the SAMR_FIELD_EXPIRED_FLAG */
3152 switch (levels[l]) {