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 TEST_USERINFO_STRING(2, comment, 1, comment, "xx2-1 comment", 0);
325 TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
326 TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment",
329 test_account_name = talloc_asprintf(tctx, "%sxx7-1", base_account_name);
330 TEST_USERINFO_STRING(7, account_name, 1, account_name, base_account_name, 0);
331 test_account_name = talloc_asprintf(tctx, "%sxx7-3", base_account_name);
332 TEST_USERINFO_STRING(7, account_name, 3, account_name, base_account_name, 0);
333 test_account_name = talloc_asprintf(tctx, "%sxx7-5", base_account_name);
334 TEST_USERINFO_STRING(7, account_name, 5, account_name, base_account_name, 0);
335 test_account_name = talloc_asprintf(tctx, "%sxx7-6", base_account_name);
336 TEST_USERINFO_STRING(7, account_name, 6, account_name, base_account_name, 0);
337 test_account_name = talloc_asprintf(tctx, "%sxx7-7", base_account_name);
338 TEST_USERINFO_STRING(7, account_name, 7, account_name, base_account_name, 0);
339 test_account_name = talloc_asprintf(tctx, "%sxx7-21", base_account_name);
340 TEST_USERINFO_STRING(7, account_name, 21, account_name, base_account_name, 0);
341 test_account_name = base_account_name;
342 TEST_USERINFO_STRING(21, account_name, 21, account_name, base_account_name,
343 SAMR_FIELD_ACCOUNT_NAME);
345 TEST_USERINFO_STRING(6, full_name, 1, full_name, "xx6-1 full_name", 0);
346 TEST_USERINFO_STRING(6, full_name, 3, full_name, "xx6-3 full_name", 0);
347 TEST_USERINFO_STRING(6, full_name, 5, full_name, "xx6-5 full_name", 0);
348 TEST_USERINFO_STRING(6, full_name, 6, full_name, "xx6-6 full_name", 0);
349 TEST_USERINFO_STRING(6, full_name, 8, full_name, "xx6-8 full_name", 0);
350 TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
351 TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
352 TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name",
353 SAMR_FIELD_FULL_NAME);
355 TEST_USERINFO_STRING(6, full_name, 1, full_name, "", 0);
356 TEST_USERINFO_STRING(6, full_name, 3, full_name, "", 0);
357 TEST_USERINFO_STRING(6, full_name, 5, full_name, "", 0);
358 TEST_USERINFO_STRING(6, full_name, 6, full_name, "", 0);
359 TEST_USERINFO_STRING(6, full_name, 8, full_name, "", 0);
360 TEST_USERINFO_STRING(6, full_name, 21, full_name, "", 0);
361 TEST_USERINFO_STRING(8, full_name, 21, full_name, "", 0);
362 TEST_USERINFO_STRING(21, full_name, 21, full_name, "",
363 SAMR_FIELD_FULL_NAME);
365 TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
366 TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
367 TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
368 TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script",
369 SAMR_FIELD_LOGON_SCRIPT);
371 TEST_USERINFO_STRING(12, profile_path, 3, profile_path, "xx12-3 profile_path", 0);
372 TEST_USERINFO_STRING(12, profile_path, 5, profile_path, "xx12-5 profile_path", 0);
373 TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
374 TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path",
375 SAMR_FIELD_PROFILE_PATH);
377 TEST_USERINFO_STRING(10, home_directory, 3, home_directory, "xx10-3 home_directory", 0);
378 TEST_USERINFO_STRING(10, home_directory, 5, home_directory, "xx10-5 home_directory", 0);
379 TEST_USERINFO_STRING(10, home_directory, 21, home_directory, "xx10-21 home_directory", 0);
380 TEST_USERINFO_STRING(21, home_directory, 21, home_directory, "xx21-21 home_directory",
381 SAMR_FIELD_HOME_DIRECTORY);
382 TEST_USERINFO_STRING(21, home_directory, 10, home_directory, "xx21-10 home_directory",
383 SAMR_FIELD_HOME_DIRECTORY);
385 TEST_USERINFO_STRING(10, home_drive, 3, home_drive, "xx10-3 home_drive", 0);
386 TEST_USERINFO_STRING(10, home_drive, 5, home_drive, "xx10-5 home_drive", 0);
387 TEST_USERINFO_STRING(10, home_drive, 21, home_drive, "xx10-21 home_drive", 0);
388 TEST_USERINFO_STRING(21, home_drive, 21, home_drive, "xx21-21 home_drive",
389 SAMR_FIELD_HOME_DRIVE);
390 TEST_USERINFO_STRING(21, home_drive, 10, home_drive, "xx21-10 home_drive",
391 SAMR_FIELD_HOME_DRIVE);
393 TEST_USERINFO_STRING(13, description, 1, description, "xx13-1 description", 0);
394 TEST_USERINFO_STRING(13, description, 5, description, "xx13-5 description", 0);
395 TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
396 TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description",
397 SAMR_FIELD_DESCRIPTION);
399 TEST_USERINFO_STRING(14, workstations, 3, workstations, "14workstation3", 0);
400 TEST_USERINFO_STRING(14, workstations, 5, workstations, "14workstation4", 0);
401 TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
402 TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21",
403 SAMR_FIELD_WORKSTATIONS);
404 TEST_USERINFO_STRING(21, workstations, 3, workstations, "21workstation3",
405 SAMR_FIELD_WORKSTATIONS);
406 TEST_USERINFO_STRING(21, workstations, 5, workstations, "21workstation5",
407 SAMR_FIELD_WORKSTATIONS);
408 TEST_USERINFO_STRING(21, workstations, 14, workstations, "21workstation14",
409 SAMR_FIELD_WORKSTATIONS);
411 TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
412 TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "xx21-21 parameters",
413 SAMR_FIELD_PARAMETERS);
414 TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "xx21-20 parameters",
415 SAMR_FIELD_PARAMETERS);
416 /* also empty user parameters are allowed */
417 TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "", 0);
418 TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "",
419 SAMR_FIELD_PARAMETERS);
420 TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "",
421 SAMR_FIELD_PARAMETERS);
423 TEST_USERINFO_INT(2, country_code, 2, country_code, __LINE__, 0);
424 TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
425 TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__,
426 SAMR_FIELD_COUNTRY_CODE);
427 TEST_USERINFO_INT(21, country_code, 2, country_code, __LINE__,
428 SAMR_FIELD_COUNTRY_CODE);
430 TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
431 TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__,
432 SAMR_FIELD_CODE_PAGE);
433 TEST_USERINFO_INT(21, code_page, 2, code_page, __LINE__,
434 SAMR_FIELD_CODE_PAGE);
436 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, __LINE__, 0);
437 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, __LINE__, 0);
438 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, __LINE__,
439 SAMR_FIELD_ACCT_EXPIRY);
440 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, __LINE__,
441 SAMR_FIELD_ACCT_EXPIRY);
442 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, __LINE__,
443 SAMR_FIELD_ACCT_EXPIRY);
445 TEST_USERINFO_INT(4, logon_hours.bits[3], 3, logon_hours.bits[3], 1, 0);
446 TEST_USERINFO_INT(4, logon_hours.bits[3], 5, logon_hours.bits[3], 2, 0);
447 TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
448 TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4,
449 SAMR_FIELD_LOGON_HOURS);
451 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
452 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
453 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
455 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
456 (base_acct_flags | ACB_DISABLED),
457 (base_acct_flags | ACB_DISABLED | user_extra_flags),
460 /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
461 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
462 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
463 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
465 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
466 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
467 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
471 /* The 'autolock' flag doesn't stick - check this */
472 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
473 (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK),
474 (base_acct_flags | ACB_DISABLED | user_extra_flags),
477 /* Removing the 'disabled' flag doesn't stick - check this */
478 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
480 (base_acct_flags | ACB_DISABLED | user_extra_flags),
483 /* The 'store plaintext' flag does stick */
484 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
485 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED),
486 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags),
488 /* The 'use DES' flag does stick */
489 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
490 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY),
491 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags),
493 /* The 'don't require kerberos pre-authentication flag does stick */
494 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
495 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH),
496 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags),
498 /* The 'no kerberos PAC required' flag sticks */
499 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
500 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD),
501 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags),
504 TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags,
505 (base_acct_flags | ACB_DISABLED),
506 (base_acct_flags | ACB_DISABLED | user_extra_flags),
507 SAMR_FIELD_ACCT_FLAGS);
510 /* these fail with win2003 - it appears you can't set the primary gid?
511 the set succeeds, but the gid isn't changed. Very weird! */
512 TEST_USERINFO_INT(9, primary_gid, 1, primary_gid, 513);
513 TEST_USERINFO_INT(9, primary_gid, 3, primary_gid, 513);
514 TEST_USERINFO_INT(9, primary_gid, 5, primary_gid, 513);
515 TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
522 generate a random password for password change tests
524 static char *samr_rand_pass_silent(TALLOC_CTX *mem_ctx, int min_len)
526 size_t len = MAX(8, min_len) + (random() % 6);
527 char *s = generate_random_str(mem_ctx, len);
531 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
533 char *s = samr_rand_pass_silent(mem_ctx, min_len);
534 printf("Generated password '%s'\n", s);
540 generate a random password for password change tests
542 static DATA_BLOB samr_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
545 DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
546 generate_random_buffer(password.data, password.length);
548 for (i=0; i < len; i++) {
549 if (((uint16_t *)password.data)[i] == 0) {
550 ((uint16_t *)password.data)[i] = 1;
558 generate a random password for password change tests (fixed length)
560 static char *samr_rand_pass_fixed_len(TALLOC_CTX *mem_ctx, int len)
562 char *s = generate_random_str(mem_ctx, len);
563 printf("Generated password '%s'\n", s);
567 static bool test_SetUserPass(struct dcerpc_pipe *p, struct torture_context *tctx,
568 struct policy_handle *handle, char **password)
571 struct samr_SetUserInfo s;
572 union samr_UserInfo u;
574 DATA_BLOB session_key;
576 struct samr_GetUserPwInfo pwp;
577 struct samr_PwInfo info;
578 int policy_min_pw_len = 0;
579 pwp.in.user_handle = handle;
580 pwp.out.info = &info;
582 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
583 if (NT_STATUS_IS_OK(status)) {
584 policy_min_pw_len = pwp.out.info->min_password_length;
586 newpass = samr_rand_pass(tctx, policy_min_pw_len);
588 s.in.user_handle = handle;
592 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
593 u.info24.password_expired = 0;
595 status = dcerpc_fetch_session_key(p, &session_key);
596 if (!NT_STATUS_IS_OK(status)) {
597 printf("SetUserInfo level %u - no session key - %s\n",
598 s.in.level, nt_errstr(status));
602 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
604 torture_comment(tctx, "Testing SetUserInfo level 24 (set password)\n");
606 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
607 if (!NT_STATUS_IS_OK(status)) {
608 printf("SetUserInfo level %u failed - %s\n",
609 s.in.level, nt_errstr(status));
619 static bool test_SetUserPass_23(struct dcerpc_pipe *p, struct torture_context *tctx,
620 struct policy_handle *handle, uint32_t fields_present,
624 struct samr_SetUserInfo s;
625 union samr_UserInfo u;
627 DATA_BLOB session_key;
629 struct samr_GetUserPwInfo pwp;
630 struct samr_PwInfo info;
631 int policy_min_pw_len = 0;
632 pwp.in.user_handle = handle;
633 pwp.out.info = &info;
635 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
636 if (NT_STATUS_IS_OK(status)) {
637 policy_min_pw_len = pwp.out.info->min_password_length;
639 newpass = samr_rand_pass(tctx, policy_min_pw_len);
641 s.in.user_handle = handle;
647 u.info23.info.fields_present = fields_present;
649 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
651 status = dcerpc_fetch_session_key(p, &session_key);
652 if (!NT_STATUS_IS_OK(status)) {
653 printf("SetUserInfo level %u - no session key - %s\n",
654 s.in.level, nt_errstr(status));
658 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
660 torture_comment(tctx, "Testing SetUserInfo level 23 (set password)\n");
662 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
663 if (!NT_STATUS_IS_OK(status)) {
664 printf("SetUserInfo level %u failed - %s\n",
665 s.in.level, nt_errstr(status));
671 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
673 status = dcerpc_fetch_session_key(p, &session_key);
674 if (!NT_STATUS_IS_OK(status)) {
675 printf("SetUserInfo level %u - no session key - %s\n",
676 s.in.level, nt_errstr(status));
680 /* This should break the key nicely */
681 session_key.length--;
682 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
684 torture_comment(tctx, "Testing SetUserInfo level 23 (set password) with wrong password\n");
686 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
687 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
688 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
689 s.in.level, nt_errstr(status));
697 static bool test_SetUserPassEx(struct dcerpc_pipe *p, struct torture_context *tctx,
698 struct policy_handle *handle, bool makeshort,
702 struct samr_SetUserInfo s;
703 union samr_UserInfo u;
705 DATA_BLOB session_key;
706 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
707 uint8_t confounder[16];
709 struct MD5Context ctx;
710 struct samr_GetUserPwInfo pwp;
711 struct samr_PwInfo info;
712 int policy_min_pw_len = 0;
713 pwp.in.user_handle = handle;
714 pwp.out.info = &info;
716 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
717 if (NT_STATUS_IS_OK(status)) {
718 policy_min_pw_len = pwp.out.info->min_password_length;
720 if (makeshort && policy_min_pw_len) {
721 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len - 1);
723 newpass = samr_rand_pass(tctx, policy_min_pw_len);
726 s.in.user_handle = handle;
730 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
731 u.info26.password_expired = 0;
733 status = dcerpc_fetch_session_key(p, &session_key);
734 if (!NT_STATUS_IS_OK(status)) {
735 printf("SetUserInfo level %u - no session key - %s\n",
736 s.in.level, nt_errstr(status));
740 generate_random_buffer((uint8_t *)confounder, 16);
743 MD5Update(&ctx, confounder, 16);
744 MD5Update(&ctx, session_key.data, session_key.length);
745 MD5Final(confounded_session_key.data, &ctx);
747 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
748 memcpy(&u.info26.password.data[516], confounder, 16);
750 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex)\n");
752 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
753 if (!NT_STATUS_IS_OK(status)) {
754 printf("SetUserInfo level %u failed - %s\n",
755 s.in.level, nt_errstr(status));
761 /* This should break the key nicely */
762 confounded_session_key.data[0]++;
764 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
765 memcpy(&u.info26.password.data[516], confounder, 16);
767 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
769 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
770 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
771 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
772 s.in.level, nt_errstr(status));
781 static bool test_SetUserPass_25(struct dcerpc_pipe *p, struct torture_context *tctx,
782 struct policy_handle *handle, uint32_t fields_present,
786 struct samr_SetUserInfo s;
787 union samr_UserInfo u;
789 DATA_BLOB session_key;
790 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
791 struct MD5Context ctx;
792 uint8_t confounder[16];
794 struct samr_GetUserPwInfo pwp;
795 struct samr_PwInfo info;
796 int policy_min_pw_len = 0;
797 pwp.in.user_handle = handle;
798 pwp.out.info = &info;
800 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
801 if (NT_STATUS_IS_OK(status)) {
802 policy_min_pw_len = pwp.out.info->min_password_length;
804 newpass = samr_rand_pass(tctx, policy_min_pw_len);
806 s.in.user_handle = handle;
812 u.info25.info.fields_present = fields_present;
814 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
816 status = dcerpc_fetch_session_key(p, &session_key);
817 if (!NT_STATUS_IS_OK(status)) {
818 printf("SetUserInfo level %u - no session key - %s\n",
819 s.in.level, nt_errstr(status));
823 generate_random_buffer((uint8_t *)confounder, 16);
826 MD5Update(&ctx, confounder, 16);
827 MD5Update(&ctx, session_key.data, session_key.length);
828 MD5Final(confounded_session_key.data, &ctx);
830 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
831 memcpy(&u.info25.password.data[516], confounder, 16);
833 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex)\n");
835 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
836 if (!NT_STATUS_IS_OK(status)) {
837 printf("SetUserInfo level %u failed - %s\n",
838 s.in.level, nt_errstr(status));
844 /* This should break the key nicely */
845 confounded_session_key.data[0]++;
847 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
848 memcpy(&u.info25.password.data[516], confounder, 16);
850 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
852 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
853 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
854 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
855 s.in.level, nt_errstr(status));
862 static bool test_SetUserPass_18(struct dcerpc_pipe *p, struct torture_context *tctx,
863 struct policy_handle *handle, char **password)
866 struct samr_SetUserInfo s;
867 union samr_UserInfo u;
869 DATA_BLOB session_key;
871 struct samr_GetUserPwInfo pwp;
872 struct samr_PwInfo info;
873 int policy_min_pw_len = 0;
874 uint8_t lm_hash[16], nt_hash[16];
876 pwp.in.user_handle = handle;
877 pwp.out.info = &info;
879 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
880 if (NT_STATUS_IS_OK(status)) {
881 policy_min_pw_len = pwp.out.info->min_password_length;
883 newpass = samr_rand_pass(tctx, policy_min_pw_len);
885 s.in.user_handle = handle;
891 u.info18.nt_pwd_active = true;
892 u.info18.lm_pwd_active = true;
894 E_md4hash(newpass, nt_hash);
895 E_deshash(newpass, lm_hash);
897 status = dcerpc_fetch_session_key(p, &session_key);
898 if (!NT_STATUS_IS_OK(status)) {
899 printf("SetUserInfo level %u - no session key - %s\n",
900 s.in.level, nt_errstr(status));
906 in = data_blob_const(nt_hash, 16);
907 out = data_blob_talloc_zero(tctx, 16);
908 sess_crypt_blob(&out, &in, &session_key, true);
909 memcpy(u.info18.nt_pwd.hash, out.data, out.length);
913 in = data_blob_const(lm_hash, 16);
914 out = data_blob_talloc_zero(tctx, 16);
915 sess_crypt_blob(&out, &in, &session_key, true);
916 memcpy(u.info18.lm_pwd.hash, out.data, out.length);
919 torture_comment(tctx, "Testing SetUserInfo level 18 (set password hash)\n");
921 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
922 if (!NT_STATUS_IS_OK(status)) {
923 printf("SetUserInfo level %u failed - %s\n",
924 s.in.level, nt_errstr(status));
933 static bool test_SetUserPass_21(struct dcerpc_pipe *p, struct torture_context *tctx,
934 struct policy_handle *handle, uint32_t fields_present,
938 struct samr_SetUserInfo s;
939 union samr_UserInfo u;
941 DATA_BLOB session_key;
943 struct samr_GetUserPwInfo pwp;
944 struct samr_PwInfo info;
945 int policy_min_pw_len = 0;
946 uint8_t lm_hash[16], nt_hash[16];
948 pwp.in.user_handle = handle;
949 pwp.out.info = &info;
951 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
952 if (NT_STATUS_IS_OK(status)) {
953 policy_min_pw_len = pwp.out.info->min_password_length;
955 newpass = samr_rand_pass(tctx, policy_min_pw_len);
957 s.in.user_handle = handle;
961 E_md4hash(newpass, nt_hash);
962 E_deshash(newpass, lm_hash);
966 u.info21.fields_present = fields_present;
968 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
969 u.info21.lm_owf_password.length = 16;
970 u.info21.lm_owf_password.size = 16;
971 u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
972 u.info21.lm_password_set = true;
975 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
976 u.info21.nt_owf_password.length = 16;
977 u.info21.nt_owf_password.size = 16;
978 u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
979 u.info21.nt_password_set = true;
982 status = dcerpc_fetch_session_key(p, &session_key);
983 if (!NT_STATUS_IS_OK(status)) {
984 printf("SetUserInfo level %u - no session key - %s\n",
985 s.in.level, nt_errstr(status));
989 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
991 in = data_blob_const(u.info21.lm_owf_password.array,
992 u.info21.lm_owf_password.length);
993 out = data_blob_talloc_zero(tctx, 16);
994 sess_crypt_blob(&out, &in, &session_key, true);
995 u.info21.lm_owf_password.array = (uint16_t *)out.data;
998 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1000 in = data_blob_const(u.info21.nt_owf_password.array,
1001 u.info21.nt_owf_password.length);
1002 out = data_blob_talloc_zero(tctx, 16);
1003 sess_crypt_blob(&out, &in, &session_key, true);
1004 u.info21.nt_owf_password.array = (uint16_t *)out.data;
1007 torture_comment(tctx, "Testing SetUserInfo level 21 (set password hash)\n");
1009 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1010 if (!NT_STATUS_IS_OK(status)) {
1011 printf("SetUserInfo level %u failed - %s\n",
1012 s.in.level, nt_errstr(status));
1015 *password = newpass;
1018 /* try invalid length */
1019 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1021 u.info21.nt_owf_password.length++;
1023 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1025 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1026 printf("SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1027 s.in.level, nt_errstr(status));
1032 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1034 u.info21.lm_owf_password.length++;
1036 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1038 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1039 printf("SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1040 s.in.level, nt_errstr(status));
1048 static bool test_SetUserPass_level_ex(struct dcerpc_pipe *p,
1049 struct torture_context *tctx,
1050 struct policy_handle *handle,
1052 uint32_t fields_present,
1053 char **password, uint8_t password_expired,
1055 bool *matched_expected_error)
1058 NTSTATUS expected_error = NT_STATUS_OK;
1059 struct samr_SetUserInfo s;
1060 struct samr_SetUserInfo2 s2;
1061 union samr_UserInfo u;
1063 DATA_BLOB session_key;
1064 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
1065 struct MD5Context ctx;
1066 uint8_t confounder[16];
1068 struct samr_GetUserPwInfo pwp;
1069 struct samr_PwInfo info;
1070 int policy_min_pw_len = 0;
1071 const char *comment = NULL;
1072 uint8_t lm_hash[16], nt_hash[16];
1074 pwp.in.user_handle = handle;
1075 pwp.out.info = &info;
1077 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1078 if (NT_STATUS_IS_OK(status)) {
1079 policy_min_pw_len = pwp.out.info->min_password_length;
1081 newpass = samr_rand_pass_silent(tctx, policy_min_pw_len);
1084 s2.in.user_handle = handle;
1086 s2.in.level = level;
1088 s.in.user_handle = handle;
1093 if (fields_present & SAMR_FIELD_COMMENT) {
1094 comment = talloc_asprintf(tctx, "comment: %ld\n", time(NULL));
1101 E_md4hash(newpass, nt_hash);
1102 E_deshash(newpass, lm_hash);
1104 u.info18.nt_pwd_active = true;
1105 u.info18.lm_pwd_active = true;
1106 u.info18.password_expired = password_expired;
1108 memcpy(u.info18.lm_pwd.hash, lm_hash, 16);
1109 memcpy(u.info18.nt_pwd.hash, nt_hash, 16);
1113 E_md4hash(newpass, nt_hash);
1114 E_deshash(newpass, lm_hash);
1116 u.info21.fields_present = fields_present;
1117 u.info21.password_expired = password_expired;
1118 u.info21.comment.string = comment;
1120 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1121 u.info21.lm_owf_password.length = 16;
1122 u.info21.lm_owf_password.size = 16;
1123 u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
1124 u.info21.lm_password_set = true;
1127 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1128 u.info21.nt_owf_password.length = 16;
1129 u.info21.nt_owf_password.size = 16;
1130 u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
1131 u.info21.nt_password_set = true;
1136 u.info23.info.fields_present = fields_present;
1137 u.info23.info.password_expired = password_expired;
1138 u.info23.info.comment.string = comment;
1140 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
1144 u.info24.password_expired = password_expired;
1146 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
1150 u.info25.info.fields_present = fields_present;
1151 u.info25.info.password_expired = password_expired;
1152 u.info25.info.comment.string = comment;
1154 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
1158 u.info26.password_expired = password_expired;
1160 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
1165 status = dcerpc_fetch_session_key(p, &session_key);
1166 if (!NT_STATUS_IS_OK(status)) {
1167 printf("SetUserInfo level %u - no session key - %s\n",
1168 s.in.level, nt_errstr(status));
1172 generate_random_buffer((uint8_t *)confounder, 16);
1175 MD5Update(&ctx, confounder, 16);
1176 MD5Update(&ctx, session_key.data, session_key.length);
1177 MD5Final(confounded_session_key.data, &ctx);
1183 in = data_blob_const(u.info18.nt_pwd.hash, 16);
1184 out = data_blob_talloc_zero(tctx, 16);
1185 sess_crypt_blob(&out, &in, &session_key, true);
1186 memcpy(u.info18.nt_pwd.hash, out.data, out.length);
1190 in = data_blob_const(u.info18.lm_pwd.hash, 16);
1191 out = data_blob_talloc_zero(tctx, 16);
1192 sess_crypt_blob(&out, &in, &session_key, true);
1193 memcpy(u.info18.lm_pwd.hash, out.data, out.length);
1198 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1200 in = data_blob_const(u.info21.lm_owf_password.array,
1201 u.info21.lm_owf_password.length);
1202 out = data_blob_talloc_zero(tctx, 16);
1203 sess_crypt_blob(&out, &in, &session_key, true);
1204 u.info21.lm_owf_password.array = (uint16_t *)out.data;
1206 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1208 in = data_blob_const(u.info21.nt_owf_password.array,
1209 u.info21.nt_owf_password.length);
1210 out = data_blob_talloc_zero(tctx, 16);
1211 sess_crypt_blob(&out, &in, &session_key, true);
1212 u.info21.nt_owf_password.array = (uint16_t *)out.data;
1216 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
1219 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
1222 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
1223 memcpy(&u.info25.password.data[516], confounder, 16);
1226 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
1227 memcpy(&u.info26.password.data[516], confounder, 16);
1232 status = dcerpc_samr_SetUserInfo2(p, tctx, &s2);
1234 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1237 if (!NT_STATUS_IS_OK(status)) {
1238 if (fields_present == 0) {
1239 expected_error = NT_STATUS_INVALID_PARAMETER;
1241 if (fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
1242 expected_error = NT_STATUS_ACCESS_DENIED;
1246 if (!NT_STATUS_IS_OK(expected_error)) {
1248 torture_assert_ntstatus_equal(tctx,
1250 expected_error, "SetUserInfo2 failed");
1252 torture_assert_ntstatus_equal(tctx,
1254 expected_error, "SetUserInfo failed");
1256 *matched_expected_error = true;
1260 if (!NT_STATUS_IS_OK(status)) {
1261 printf("SetUserInfo%s level %u failed - %s\n",
1262 use_setinfo2 ? "2":"", level, nt_errstr(status));
1265 *password = newpass;
1271 static bool test_SetAliasInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1272 struct policy_handle *handle)
1275 struct samr_SetAliasInfo r;
1276 struct samr_QueryAliasInfo q;
1277 union samr_AliasInfo *info;
1278 uint16_t levels[] = {2, 3};
1282 /* Ignoring switch level 1, as that includes the number of members for the alias
1283 * and setting this to a wrong value might have negative consequences
1286 for (i=0;i<ARRAY_SIZE(levels);i++) {
1287 torture_comment(tctx, "Testing SetAliasInfo level %u\n", levels[i]);
1289 r.in.alias_handle = handle;
1290 r.in.level = levels[i];
1291 r.in.info = talloc(tctx, union samr_AliasInfo);
1292 switch (r.in.level) {
1293 case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
1294 case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
1295 "Test Description, should test I18N as well"); break;
1296 case ALIASINFOALL: printf("ALIASINFOALL ignored\n"); break;
1299 status = dcerpc_samr_SetAliasInfo(p, tctx, &r);
1300 if (!NT_STATUS_IS_OK(status)) {
1301 printf("SetAliasInfo level %u failed - %s\n",
1302 levels[i], nt_errstr(status));
1306 q.in.alias_handle = handle;
1307 q.in.level = levels[i];
1310 status = dcerpc_samr_QueryAliasInfo(p, tctx, &q);
1311 if (!NT_STATUS_IS_OK(status)) {
1312 printf("QueryAliasInfo level %u failed - %s\n",
1313 levels[i], nt_errstr(status));
1321 static bool test_GetGroupsForUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1322 struct policy_handle *user_handle)
1324 struct samr_GetGroupsForUser r;
1325 struct samr_RidWithAttributeArray *rids = NULL;
1328 torture_comment(tctx, "testing GetGroupsForUser\n");
1330 r.in.user_handle = user_handle;
1333 status = dcerpc_samr_GetGroupsForUser(p, tctx, &r);
1334 torture_assert_ntstatus_ok(tctx, status, "GetGroupsForUser");
1340 static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1341 struct lsa_String *domain_name)
1344 struct samr_GetDomPwInfo r;
1345 struct samr_PwInfo info;
1347 r.in.domain_name = domain_name;
1350 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1352 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1353 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1355 r.in.domain_name->string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
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 = "\\\\__NONAME__";
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 = "\\\\Builtin";
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");
1376 static bool test_GetUserPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1377 struct policy_handle *handle)
1380 struct samr_GetUserPwInfo r;
1381 struct samr_PwInfo info;
1383 torture_comment(tctx, "Testing GetUserPwInfo\n");
1385 r.in.user_handle = handle;
1388 status = dcerpc_samr_GetUserPwInfo(p, tctx, &r);
1389 torture_assert_ntstatus_ok(tctx, status, "GetUserPwInfo");
1394 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, struct torture_context *tctx,
1395 struct policy_handle *domain_handle, const char *name,
1399 struct samr_LookupNames n;
1400 struct lsa_String sname[2];
1401 struct samr_Ids rids, types;
1403 init_lsa_String(&sname[0], name);
1405 n.in.domain_handle = domain_handle;
1409 n.out.types = &types;
1410 status = dcerpc_samr_LookupNames(p, tctx, &n);
1411 if (NT_STATUS_IS_OK(status)) {
1412 *rid = n.out.rids->ids[0];
1417 init_lsa_String(&sname[1], "xxNONAMExx");
1419 status = dcerpc_samr_LookupNames(p, tctx, &n);
1420 if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
1421 printf("LookupNames[2] failed - %s\n", nt_errstr(status));
1422 if (NT_STATUS_IS_OK(status)) {
1423 return NT_STATUS_UNSUCCESSFUL;
1429 status = dcerpc_samr_LookupNames(p, tctx, &n);
1430 if (!NT_STATUS_IS_OK(status)) {
1431 printf("LookupNames[0] failed - %s\n", nt_errstr(status));
1435 init_lsa_String(&sname[0], "xxNONAMExx");
1437 status = dcerpc_samr_LookupNames(p, tctx, &n);
1438 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1439 printf("LookupNames[1 bad name] failed - %s\n", nt_errstr(status));
1440 if (NT_STATUS_IS_OK(status)) {
1441 return NT_STATUS_UNSUCCESSFUL;
1446 init_lsa_String(&sname[0], "xxNONAMExx");
1447 init_lsa_String(&sname[1], "xxNONAME2xx");
1449 status = dcerpc_samr_LookupNames(p, tctx, &n);
1450 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1451 printf("LookupNames[2 bad names] failed - %s\n", nt_errstr(status));
1452 if (NT_STATUS_IS_OK(status)) {
1453 return NT_STATUS_UNSUCCESSFUL;
1458 return NT_STATUS_OK;
1461 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1462 struct policy_handle *domain_handle,
1463 const char *name, struct policy_handle *user_handle)
1466 struct samr_OpenUser r;
1469 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
1470 if (!NT_STATUS_IS_OK(status)) {
1474 r.in.domain_handle = domain_handle;
1475 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1477 r.out.user_handle = user_handle;
1478 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
1479 if (!NT_STATUS_IS_OK(status)) {
1480 printf("OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(status));
1487 static bool test_ChangePasswordNT3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1488 struct policy_handle *handle)
1491 struct samr_ChangePasswordUser r;
1493 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1494 struct policy_handle user_handle;
1495 char *oldpass = "test";
1496 char *newpass = "test2";
1497 uint8_t old_nt_hash[16], new_nt_hash[16];
1498 uint8_t old_lm_hash[16], new_lm_hash[16];
1500 status = test_OpenUser_byname(p, mem_ctx, handle, "testuser", &user_handle);
1501 if (!NT_STATUS_IS_OK(status)) {
1505 printf("Testing ChangePasswordUser for user 'testuser'\n");
1507 printf("old password: %s\n", oldpass);
1508 printf("new password: %s\n", newpass);
1510 E_md4hash(oldpass, old_nt_hash);
1511 E_md4hash(newpass, new_nt_hash);
1512 E_deshash(oldpass, old_lm_hash);
1513 E_deshash(newpass, new_lm_hash);
1515 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1516 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1517 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1518 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1519 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1520 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1522 r.in.handle = &user_handle;
1523 r.in.lm_present = 1;
1524 r.in.old_lm_crypted = &hash1;
1525 r.in.new_lm_crypted = &hash2;
1526 r.in.nt_present = 1;
1527 r.in.old_nt_crypted = &hash3;
1528 r.in.new_nt_crypted = &hash4;
1529 r.in.cross1_present = 1;
1530 r.in.nt_cross = &hash5;
1531 r.in.cross2_present = 1;
1532 r.in.lm_cross = &hash6;
1534 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1535 if (!NT_STATUS_IS_OK(status)) {
1536 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1540 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1548 static bool test_ChangePasswordUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1549 const char *acct_name,
1550 struct policy_handle *handle, char **password)
1553 struct samr_ChangePasswordUser r;
1555 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1556 struct policy_handle user_handle;
1558 uint8_t old_nt_hash[16], new_nt_hash[16];
1559 uint8_t old_lm_hash[16], new_lm_hash[16];
1560 bool changed = true;
1563 struct samr_GetUserPwInfo pwp;
1564 struct samr_PwInfo info;
1565 int policy_min_pw_len = 0;
1567 status = test_OpenUser_byname(p, tctx, handle, acct_name, &user_handle);
1568 if (!NT_STATUS_IS_OK(status)) {
1571 pwp.in.user_handle = &user_handle;
1572 pwp.out.info = &info;
1574 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1575 if (NT_STATUS_IS_OK(status)) {
1576 policy_min_pw_len = pwp.out.info->min_password_length;
1578 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1580 torture_comment(tctx, "Testing ChangePasswordUser\n");
1582 torture_assert(tctx, *password != NULL,
1583 "Failing ChangePasswordUser as old password was NULL. Previous test failed?");
1585 oldpass = *password;
1587 E_md4hash(oldpass, old_nt_hash);
1588 E_md4hash(newpass, new_nt_hash);
1589 E_deshash(oldpass, old_lm_hash);
1590 E_deshash(newpass, new_lm_hash);
1592 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1593 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1594 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1595 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1596 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1597 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1599 r.in.user_handle = &user_handle;
1600 r.in.lm_present = 1;
1601 /* Break the LM hash */
1603 r.in.old_lm_crypted = &hash1;
1604 r.in.new_lm_crypted = &hash2;
1605 r.in.nt_present = 1;
1606 r.in.old_nt_crypted = &hash3;
1607 r.in.new_nt_crypted = &hash4;
1608 r.in.cross1_present = 1;
1609 r.in.nt_cross = &hash5;
1610 r.in.cross2_present = 1;
1611 r.in.lm_cross = &hash6;
1613 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1614 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1615 "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash");
1617 /* Unbreak the LM hash */
1620 r.in.user_handle = &user_handle;
1621 r.in.lm_present = 1;
1622 r.in.old_lm_crypted = &hash1;
1623 r.in.new_lm_crypted = &hash2;
1624 /* Break the NT hash */
1626 r.in.nt_present = 1;
1627 r.in.old_nt_crypted = &hash3;
1628 r.in.new_nt_crypted = &hash4;
1629 r.in.cross1_present = 1;
1630 r.in.nt_cross = &hash5;
1631 r.in.cross2_present = 1;
1632 r.in.lm_cross = &hash6;
1634 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1635 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1636 "expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash");
1638 /* Unbreak the NT hash */
1641 r.in.user_handle = &user_handle;
1642 r.in.lm_present = 1;
1643 r.in.old_lm_crypted = &hash1;
1644 r.in.new_lm_crypted = &hash2;
1645 r.in.nt_present = 1;
1646 r.in.old_nt_crypted = &hash3;
1647 r.in.new_nt_crypted = &hash4;
1648 r.in.cross1_present = 1;
1649 r.in.nt_cross = &hash5;
1650 r.in.cross2_present = 1;
1651 /* Break the LM cross */
1653 r.in.lm_cross = &hash6;
1655 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1656 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1657 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status));
1661 /* Unbreak the LM cross */
1664 r.in.user_handle = &user_handle;
1665 r.in.lm_present = 1;
1666 r.in.old_lm_crypted = &hash1;
1667 r.in.new_lm_crypted = &hash2;
1668 r.in.nt_present = 1;
1669 r.in.old_nt_crypted = &hash3;
1670 r.in.new_nt_crypted = &hash4;
1671 r.in.cross1_present = 1;
1672 /* Break the NT cross */
1674 r.in.nt_cross = &hash5;
1675 r.in.cross2_present = 1;
1676 r.in.lm_cross = &hash6;
1678 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1679 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1680 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status));
1684 /* Unbreak the NT cross */
1688 /* Reset the hashes to not broken values */
1689 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1690 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1691 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1692 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1693 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1694 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1696 r.in.user_handle = &user_handle;
1697 r.in.lm_present = 1;
1698 r.in.old_lm_crypted = &hash1;
1699 r.in.new_lm_crypted = &hash2;
1700 r.in.nt_present = 1;
1701 r.in.old_nt_crypted = &hash3;
1702 r.in.new_nt_crypted = &hash4;
1703 r.in.cross1_present = 1;
1704 r.in.nt_cross = &hash5;
1705 r.in.cross2_present = 0;
1706 r.in.lm_cross = NULL;
1708 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1709 if (NT_STATUS_IS_OK(status)) {
1711 *password = newpass;
1712 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1713 printf("ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(status));
1718 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1720 E_md4hash(oldpass, old_nt_hash);
1721 E_md4hash(newpass, new_nt_hash);
1722 E_deshash(oldpass, old_lm_hash);
1723 E_deshash(newpass, new_lm_hash);
1726 /* Reset the hashes to not broken values */
1727 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1728 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1729 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1730 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1731 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1732 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1734 r.in.user_handle = &user_handle;
1735 r.in.lm_present = 1;
1736 r.in.old_lm_crypted = &hash1;
1737 r.in.new_lm_crypted = &hash2;
1738 r.in.nt_present = 1;
1739 r.in.old_nt_crypted = &hash3;
1740 r.in.new_nt_crypted = &hash4;
1741 r.in.cross1_present = 0;
1742 r.in.nt_cross = NULL;
1743 r.in.cross2_present = 1;
1744 r.in.lm_cross = &hash6;
1746 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1747 if (NT_STATUS_IS_OK(status)) {
1749 *password = newpass;
1750 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1751 printf("ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status));
1756 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1758 E_md4hash(oldpass, old_nt_hash);
1759 E_md4hash(newpass, new_nt_hash);
1760 E_deshash(oldpass, old_lm_hash);
1761 E_deshash(newpass, new_lm_hash);
1764 /* Reset the hashes to not broken values */
1765 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1766 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1767 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1768 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1769 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1770 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1772 r.in.user_handle = &user_handle;
1773 r.in.lm_present = 1;
1774 r.in.old_lm_crypted = &hash1;
1775 r.in.new_lm_crypted = &hash2;
1776 r.in.nt_present = 1;
1777 r.in.old_nt_crypted = &hash3;
1778 r.in.new_nt_crypted = &hash4;
1779 r.in.cross1_present = 1;
1780 r.in.nt_cross = &hash5;
1781 r.in.cross2_present = 1;
1782 r.in.lm_cross = &hash6;
1784 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1785 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1786 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1787 } else if (!NT_STATUS_IS_OK(status)) {
1788 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1792 *password = newpass;
1795 r.in.user_handle = &user_handle;
1796 r.in.lm_present = 1;
1797 r.in.old_lm_crypted = &hash1;
1798 r.in.new_lm_crypted = &hash2;
1799 r.in.nt_present = 1;
1800 r.in.old_nt_crypted = &hash3;
1801 r.in.new_nt_crypted = &hash4;
1802 r.in.cross1_present = 1;
1803 r.in.nt_cross = &hash5;
1804 r.in.cross2_present = 1;
1805 r.in.lm_cross = &hash6;
1808 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1809 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1810 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1811 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1812 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status));
1818 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
1826 static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
1827 const char *acct_name,
1828 struct policy_handle *handle, char **password)
1831 struct samr_OemChangePasswordUser2 r;
1833 struct samr_Password lm_verifier;
1834 struct samr_CryptPassword lm_pass;
1835 struct lsa_AsciiString server, account, account_bad;
1838 uint8_t old_lm_hash[16], new_lm_hash[16];
1840 struct samr_GetDomPwInfo dom_pw_info;
1841 struct samr_PwInfo info;
1842 int policy_min_pw_len = 0;
1844 struct lsa_String domain_name;
1846 domain_name.string = "";
1847 dom_pw_info.in.domain_name = &domain_name;
1848 dom_pw_info.out.info = &info;
1850 torture_comment(tctx, "Testing OemChangePasswordUser2\n");
1852 torture_assert(tctx, *password != NULL,
1853 "Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?");
1855 oldpass = *password;
1857 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
1858 if (NT_STATUS_IS_OK(status)) {
1859 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
1862 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1864 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1865 account.string = acct_name;
1867 E_deshash(oldpass, old_lm_hash);
1868 E_deshash(newpass, new_lm_hash);
1870 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1871 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1872 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1874 r.in.server = &server;
1875 r.in.account = &account;
1876 r.in.password = &lm_pass;
1877 r.in.hash = &lm_verifier;
1879 /* Break the verification */
1880 lm_verifier.hash[0]++;
1882 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1884 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1885 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1886 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1891 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1892 /* Break the old password */
1894 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1895 /* unbreak it for the next operation */
1897 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1899 r.in.server = &server;
1900 r.in.account = &account;
1901 r.in.password = &lm_pass;
1902 r.in.hash = &lm_verifier;
1904 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1906 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1907 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1908 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1913 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1914 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1916 r.in.server = &server;
1917 r.in.account = &account;
1918 r.in.password = &lm_pass;
1921 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1923 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1924 && !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1925 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
1930 /* This shouldn't be a valid name */
1931 account_bad.string = TEST_ACCOUNT_NAME "XX";
1932 r.in.account = &account_bad;
1934 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1936 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1937 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
1942 /* This shouldn't be a valid name */
1943 account_bad.string = TEST_ACCOUNT_NAME "XX";
1944 r.in.account = &account_bad;
1945 r.in.password = &lm_pass;
1946 r.in.hash = &lm_verifier;
1948 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1950 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1951 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1956 /* This shouldn't be a valid name */
1957 account_bad.string = TEST_ACCOUNT_NAME "XX";
1958 r.in.account = &account_bad;
1959 r.in.password = NULL;
1960 r.in.hash = &lm_verifier;
1962 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1964 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1965 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
1970 E_deshash(oldpass, old_lm_hash);
1971 E_deshash(newpass, new_lm_hash);
1973 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1974 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1975 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1977 r.in.server = &server;
1978 r.in.account = &account;
1979 r.in.password = &lm_pass;
1980 r.in.hash = &lm_verifier;
1982 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1983 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1984 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1985 } else if (!NT_STATUS_IS_OK(status)) {
1986 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
1989 *password = newpass;
1996 static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
1997 const char *acct_name,
1999 char *newpass, bool allow_password_restriction)
2002 struct samr_ChangePasswordUser2 r;
2004 struct lsa_String server, account;
2005 struct samr_CryptPassword nt_pass, lm_pass;
2006 struct samr_Password nt_verifier, lm_verifier;
2008 uint8_t old_nt_hash[16], new_nt_hash[16];
2009 uint8_t old_lm_hash[16], new_lm_hash[16];
2011 struct samr_GetDomPwInfo dom_pw_info;
2012 struct samr_PwInfo info;
2014 struct lsa_String domain_name;
2016 domain_name.string = "";
2017 dom_pw_info.in.domain_name = &domain_name;
2018 dom_pw_info.out.info = &info;
2020 torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name);
2022 torture_assert(tctx, *password != NULL,
2023 "Failing ChangePasswordUser2 as old password was NULL. Previous test failed?");
2024 oldpass = *password;
2027 int policy_min_pw_len = 0;
2028 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
2029 if (NT_STATUS_IS_OK(status)) {
2030 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
2033 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2036 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2037 init_lsa_String(&account, acct_name);
2039 E_md4hash(oldpass, old_nt_hash);
2040 E_md4hash(newpass, new_nt_hash);
2042 E_deshash(oldpass, old_lm_hash);
2043 E_deshash(newpass, new_lm_hash);
2045 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
2046 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2047 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2049 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2050 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2051 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2053 r.in.server = &server;
2054 r.in.account = &account;
2055 r.in.nt_password = &nt_pass;
2056 r.in.nt_verifier = &nt_verifier;
2058 r.in.lm_password = &lm_pass;
2059 r.in.lm_verifier = &lm_verifier;
2061 status = dcerpc_samr_ChangePasswordUser2(p, tctx, &r);
2062 if (allow_password_restriction && NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2063 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
2064 } else if (!NT_STATUS_IS_OK(status)) {
2065 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
2068 *password = newpass;
2075 bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tctx,
2076 const char *account_string,
2077 int policy_min_pw_len,
2079 const char *newpass,
2080 NTTIME last_password_change,
2081 bool handle_reject_reason)
2084 struct samr_ChangePasswordUser3 r;
2086 struct lsa_String server, account, account_bad;
2087 struct samr_CryptPassword nt_pass, lm_pass;
2088 struct samr_Password nt_verifier, lm_verifier;
2090 uint8_t old_nt_hash[16], new_nt_hash[16];
2091 uint8_t old_lm_hash[16], new_lm_hash[16];
2093 struct samr_DomInfo1 *dominfo = NULL;
2094 struct samr_ChangeReject *reject = NULL;
2096 torture_comment(tctx, "Testing ChangePasswordUser3\n");
2098 if (newpass == NULL) {
2100 if (policy_min_pw_len == 0) {
2101 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2103 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len);
2105 } while (check_password_quality(newpass) == false);
2107 torture_comment(tctx, "Using password '%s'\n", newpass);
2110 torture_assert(tctx, *password != NULL,
2111 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2113 oldpass = *password;
2114 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2115 init_lsa_String(&account, account_string);
2117 E_md4hash(oldpass, old_nt_hash);
2118 E_md4hash(newpass, new_nt_hash);
2120 E_deshash(oldpass, old_lm_hash);
2121 E_deshash(newpass, new_lm_hash);
2123 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2124 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2125 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2127 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2128 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2129 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2131 /* Break the verification */
2132 nt_verifier.hash[0]++;
2134 r.in.server = &server;
2135 r.in.account = &account;
2136 r.in.nt_password = &nt_pass;
2137 r.in.nt_verifier = &nt_verifier;
2139 r.in.lm_password = &lm_pass;
2140 r.in.lm_verifier = &lm_verifier;
2141 r.in.password3 = NULL;
2142 r.out.dominfo = &dominfo;
2143 r.out.reject = &reject;
2145 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2146 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
2147 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
2148 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
2153 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2154 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2155 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2157 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2158 /* Break the NT hash */
2160 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2161 /* Unbreak it again */
2163 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2165 r.in.server = &server;
2166 r.in.account = &account;
2167 r.in.nt_password = &nt_pass;
2168 r.in.nt_verifier = &nt_verifier;
2170 r.in.lm_password = &lm_pass;
2171 r.in.lm_verifier = &lm_verifier;
2172 r.in.password3 = NULL;
2173 r.out.dominfo = &dominfo;
2174 r.out.reject = &reject;
2176 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2177 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
2178 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
2179 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
2184 /* This shouldn't be a valid name */
2185 init_lsa_String(&account_bad, talloc_asprintf(tctx, "%sXX", account_string));
2187 r.in.account = &account_bad;
2188 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2189 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
2190 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
2195 E_md4hash(oldpass, old_nt_hash);
2196 E_md4hash(newpass, new_nt_hash);
2198 E_deshash(oldpass, old_lm_hash);
2199 E_deshash(newpass, new_lm_hash);
2201 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2202 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2203 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2205 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2206 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2207 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2209 r.in.server = &server;
2210 r.in.account = &account;
2211 r.in.nt_password = &nt_pass;
2212 r.in.nt_verifier = &nt_verifier;
2214 r.in.lm_password = &lm_pass;
2215 r.in.lm_verifier = &lm_verifier;
2216 r.in.password3 = NULL;
2217 r.out.dominfo = &dominfo;
2218 r.out.reject = &reject;
2220 unix_to_nt_time(&t, time(NULL));
2222 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2224 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
2227 && handle_reject_reason
2228 && (!null_nttime(last_password_change) || !dominfo->min_password_age)) {
2229 if (dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
2231 if (reject && (reject->reason != SAMR_REJECT_OTHER)) {
2232 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2233 SAMR_REJECT_OTHER, reject->reason);
2238 /* We tested the order of precendence which is as follows:
2247 if ((dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
2248 (last_password_change + dominfo->min_password_age > t)) {
2250 if (reject->reason != SAMR_REJECT_OTHER) {
2251 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2252 SAMR_REJECT_OTHER, reject->reason);
2256 } else if ((dominfo->min_password_length > 0) &&
2257 (strlen(newpass) < dominfo->min_password_length)) {
2259 if (reject->reason != SAMR_REJECT_TOO_SHORT) {
2260 printf("expected SAMR_REJECT_TOO_SHORT (%d), got %d\n",
2261 SAMR_REJECT_TOO_SHORT, reject->reason);
2265 } else if ((dominfo->password_history_length > 0) &&
2266 strequal(oldpass, newpass)) {
2268 if (reject->reason != SAMR_REJECT_IN_HISTORY) {
2269 printf("expected SAMR_REJECT_IN_HISTORY (%d), got %d\n",
2270 SAMR_REJECT_IN_HISTORY, reject->reason);
2273 } else if (dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
2275 if (reject->reason != SAMR_REJECT_COMPLEXITY) {
2276 printf("expected SAMR_REJECT_COMPLEXITY (%d), got %d\n",
2277 SAMR_REJECT_COMPLEXITY, reject->reason);
2283 if (reject->reason == SAMR_REJECT_TOO_SHORT) {
2284 /* retry with adjusted size */
2285 return test_ChangePasswordUser3(p, tctx, account_string,
2286 dominfo->min_password_length,
2287 password, NULL, 0, false);
2291 } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2292 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2293 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2294 SAMR_REJECT_OTHER, reject->reason);
2297 /* Perhaps the server has a 'min password age' set? */
2300 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3");
2301 *password = talloc_strdup(tctx, newpass);
2307 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_context *tctx,
2308 const char *account_string,
2309 struct policy_handle *handle,
2313 struct samr_ChangePasswordUser3 r;
2314 struct samr_SetUserInfo s;
2315 union samr_UserInfo u;
2316 DATA_BLOB session_key;
2317 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
2318 uint8_t confounder[16];
2319 struct MD5Context ctx;
2322 struct lsa_String server, account;
2323 struct samr_CryptPassword nt_pass;
2324 struct samr_Password nt_verifier;
2325 DATA_BLOB new_random_pass;
2328 uint8_t old_nt_hash[16], new_nt_hash[16];
2330 struct samr_DomInfo1 *dominfo = NULL;
2331 struct samr_ChangeReject *reject = NULL;
2333 new_random_pass = samr_very_rand_pass(tctx, 128);
2335 torture_assert(tctx, *password != NULL,
2336 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2338 oldpass = *password;
2339 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2340 init_lsa_String(&account, account_string);
2342 s.in.user_handle = handle;
2348 u.info25.info.fields_present = SAMR_FIELD_NT_PASSWORD_PRESENT;
2350 set_pw_in_buffer(u.info25.password.data, &new_random_pass);
2352 status = dcerpc_fetch_session_key(p, &session_key);
2353 if (!NT_STATUS_IS_OK(status)) {
2354 printf("SetUserInfo level %u - no session key - %s\n",
2355 s.in.level, nt_errstr(status));
2359 generate_random_buffer((uint8_t *)confounder, 16);
2362 MD5Update(&ctx, confounder, 16);
2363 MD5Update(&ctx, session_key.data, session_key.length);
2364 MD5Final(confounded_session_key.data, &ctx);
2366 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
2367 memcpy(&u.info25.password.data[516], confounder, 16);
2369 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
2371 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
2372 if (!NT_STATUS_IS_OK(status)) {
2373 printf("SetUserInfo level %u failed - %s\n",
2374 s.in.level, nt_errstr(status));
2378 torture_comment(tctx, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
2380 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2382 new_random_pass = samr_very_rand_pass(tctx, 128);
2384 mdfour(new_nt_hash, new_random_pass.data, new_random_pass.length);
2386 set_pw_in_buffer(nt_pass.data, &new_random_pass);
2387 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2388 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2390 r.in.server = &server;
2391 r.in.account = &account;
2392 r.in.nt_password = &nt_pass;
2393 r.in.nt_verifier = &nt_verifier;
2395 r.in.lm_password = NULL;
2396 r.in.lm_verifier = NULL;
2397 r.in.password3 = NULL;
2398 r.out.dominfo = &dominfo;
2399 r.out.reject = &reject;
2401 unix_to_nt_time(&t, time(NULL));
2403 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2405 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2406 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2407 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2408 SAMR_REJECT_OTHER, reject->reason);
2411 /* Perhaps the server has a 'min password age' set? */
2413 } else if (!NT_STATUS_IS_OK(status)) {
2414 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
2418 newpass = samr_rand_pass(tctx, 128);
2420 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2422 E_md4hash(newpass, new_nt_hash);
2424 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2425 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2426 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2428 r.in.server = &server;
2429 r.in.account = &account;
2430 r.in.nt_password = &nt_pass;
2431 r.in.nt_verifier = &nt_verifier;
2433 r.in.lm_password = NULL;
2434 r.in.lm_verifier = NULL;
2435 r.in.password3 = NULL;
2436 r.out.dominfo = &dominfo;
2437 r.out.reject = &reject;
2439 unix_to_nt_time(&t, time(NULL));
2441 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2443 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2444 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2445 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2446 SAMR_REJECT_OTHER, reject->reason);
2449 /* Perhaps the server has a 'min password age' set? */
2452 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3 (on second random password)");
2453 *password = talloc_strdup(tctx, newpass);
2460 static bool test_GetMembersInAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2461 struct policy_handle *alias_handle)
2463 struct samr_GetMembersInAlias r;
2464 struct lsa_SidArray sids;
2467 torture_comment(tctx, "Testing GetMembersInAlias\n");
2469 r.in.alias_handle = alias_handle;
2472 status = dcerpc_samr_GetMembersInAlias(p, tctx, &r);
2473 torture_assert_ntstatus_ok(tctx, status, "GetMembersInAlias");
2478 static bool test_AddMemberToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2479 struct policy_handle *alias_handle,
2480 const struct dom_sid *domain_sid)
2482 struct samr_AddAliasMember r;
2483 struct samr_DeleteAliasMember d;
2485 struct dom_sid *sid;
2487 sid = dom_sid_add_rid(tctx, domain_sid, 512);
2489 torture_comment(tctx, "testing AddAliasMember\n");
2490 r.in.alias_handle = alias_handle;
2493 status = dcerpc_samr_AddAliasMember(p, tctx, &r);
2494 torture_assert_ntstatus_ok(tctx, status, "AddAliasMember");
2496 d.in.alias_handle = alias_handle;
2499 status = dcerpc_samr_DeleteAliasMember(p, tctx, &d);
2500 torture_assert_ntstatus_ok(tctx, status, "DelAliasMember");
2505 static bool test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2506 struct policy_handle *alias_handle)
2508 struct samr_AddMultipleMembersToAlias a;
2509 struct samr_RemoveMultipleMembersFromAlias r;
2511 struct lsa_SidArray sids;
2513 torture_comment(tctx, "testing AddMultipleMembersToAlias\n");
2514 a.in.alias_handle = alias_handle;
2518 sids.sids = talloc_array(tctx, struct lsa_SidPtr, 3);
2520 sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2521 sids.sids[1].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-2");
2522 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-3");
2524 status = dcerpc_samr_AddMultipleMembersToAlias(p, tctx, &a);
2525 torture_assert_ntstatus_ok(tctx, status, "AddMultipleMembersToAlias");
2528 torture_comment(tctx, "testing RemoveMultipleMembersFromAlias\n");
2529 r.in.alias_handle = alias_handle;
2532 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2533 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2535 /* strange! removing twice doesn't give any error */
2536 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2537 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2539 /* but removing an alias that isn't there does */
2540 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-4");
2542 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2543 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, "RemoveMultipleMembersFromAlias");
2548 static bool test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2549 struct policy_handle *user_handle)
2551 struct samr_TestPrivateFunctionsUser r;
2554 torture_comment(tctx, "Testing TestPrivateFunctionsUser\n");
2556 r.in.user_handle = user_handle;
2558 status = dcerpc_samr_TestPrivateFunctionsUser(p, tctx, &r);
2559 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsUser");
2564 static bool test_QueryUserInfo_pwdlastset(struct dcerpc_pipe *p,
2565 struct torture_context *tctx,
2566 struct policy_handle *handle,
2571 uint16_t levels[] = { /* 3, */ 5, 21 };
2573 NTTIME pwdlastset3 = 0;
2574 NTTIME pwdlastset5 = 0;
2575 NTTIME pwdlastset21 = 0;
2577 torture_comment(tctx, "Testing QueryUserInfo%s level 5 and 21 call ",
2578 use_info2 ? "2":"");
2580 for (i=0; i<ARRAY_SIZE(levels); i++) {
2582 struct samr_QueryUserInfo r;
2583 struct samr_QueryUserInfo2 r2;
2584 union samr_UserInfo *info;
2587 r2.in.user_handle = handle;
2588 r2.in.level = levels[i];
2589 r2.out.info = &info;
2590 status = dcerpc_samr_QueryUserInfo2(p, tctx, &r2);
2593 r.in.user_handle = handle;
2594 r.in.level = levels[i];
2596 status = dcerpc_samr_QueryUserInfo(p, tctx, &r);
2599 if (!NT_STATUS_IS_OK(status) &&
2600 !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
2601 printf("QueryUserInfo%s level %u failed - %s\n",
2602 use_info2 ? "2":"", levels[i], nt_errstr(status));
2606 switch (levels[i]) {
2608 pwdlastset3 = info->info3.last_password_change;
2611 pwdlastset5 = info->info5.last_password_change;
2614 pwdlastset21 = info->info21.last_password_change;
2620 /* torture_assert_int_equal(tctx, pwdlastset3, pwdlastset5,
2621 "pwdlastset mixup"); */
2622 torture_assert_int_equal(tctx, pwdlastset5, pwdlastset21,
2623 "pwdlastset mixup");
2625 *pwdlastset = pwdlastset21;
2627 torture_comment(tctx, "(pwdlastset: %lld)\n", *pwdlastset);
2632 static bool test_SamLogon_Creds(struct dcerpc_pipe *p, struct torture_context *tctx,
2633 struct cli_credentials *machine_credentials,
2634 struct cli_credentials *test_credentials,
2635 struct netlogon_creds_CredentialState *creds,
2636 NTSTATUS expected_result)
2639 struct netr_LogonSamLogon r;
2640 struct netr_Authenticator auth, auth2;
2641 union netr_LogonLevel logon;
2642 union netr_Validation validation;
2643 uint8_t authoritative;
2644 struct netr_NetworkInfo ninfo;
2645 DATA_BLOB names_blob, chal, lm_resp, nt_resp;
2646 int flags = CLI_CRED_NTLM_AUTH;
2648 if (lp_client_lanman_auth(tctx->lp_ctx)) {
2649 flags |= CLI_CRED_LANMAN_AUTH;
2652 if (lp_client_ntlmv2_auth(tctx->lp_ctx)) {
2653 flags |= CLI_CRED_NTLMv2_AUTH;
2656 cli_credentials_get_ntlm_username_domain(test_credentials, tctx,
2657 &ninfo.identity_info.account_name.string,
2658 &ninfo.identity_info.domain_name.string);
2660 generate_random_buffer(ninfo.challenge,
2661 sizeof(ninfo.challenge));
2662 chal = data_blob_const(ninfo.challenge,
2663 sizeof(ninfo.challenge));
2665 names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(machine_credentials),
2666 cli_credentials_get_domain(machine_credentials));
2668 status = cli_credentials_get_ntlm_response(test_credentials, tctx,
2674 torture_assert_ntstatus_ok(tctx, status, "cli_credentials_get_ntlm_response failed");
2676 ninfo.lm.data = lm_resp.data;
2677 ninfo.lm.length = lm_resp.length;
2679 ninfo.nt.data = nt_resp.data;
2680 ninfo.nt.length = nt_resp.length;
2682 ninfo.identity_info.parameter_control =
2683 MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT |
2684 MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;
2685 ninfo.identity_info.logon_id_low = 0;
2686 ninfo.identity_info.logon_id_high = 0;
2687 ninfo.identity_info.workstation.string = cli_credentials_get_workstation(machine_credentials);
2689 logon.network = &ninfo;
2691 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2692 r.in.computer_name = cli_credentials_get_workstation(machine_credentials);
2693 r.in.credential = &auth;
2694 r.in.return_authenticator = &auth2;
2695 r.in.logon_level = 2;
2696 r.in.logon = &logon;
2697 r.out.validation = &validation;
2698 r.out.authoritative = &authoritative;
2700 d_printf("Testing LogonSamLogon with name %s\n", ninfo.identity_info.account_name.string);
2703 netlogon_creds_client_authenticator(creds, &auth);
2705 r.in.validation_level = 2;
2707 status = dcerpc_netr_LogonSamLogon(p, tctx, &r);
2708 if (!NT_STATUS_IS_OK(status)) {
2709 torture_assert_ntstatus_equal(tctx, status, expected_result, "LogonSamLogon failed");
2712 torture_assert_ntstatus_ok(tctx, status, "LogonSamLogon failed");
2715 torture_assert(tctx, netlogon_creds_client_check(creds, &r.out.return_authenticator->cred),
2716 "Credential chaining failed");
2721 static bool test_SamLogon(struct torture_context *tctx,
2722 struct dcerpc_pipe *p,
2723 struct cli_credentials *machine_credentials,
2724 struct cli_credentials *test_credentials,
2725 NTSTATUS expected_result)
2727 struct netlogon_creds_CredentialState *creds;
2729 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
2733 return test_SamLogon_Creds(p, tctx, machine_credentials, test_credentials,
2734 creds, expected_result);
2737 static bool test_SamLogon_with_creds(struct torture_context *tctx,
2738 struct dcerpc_pipe *p,
2739 struct cli_credentials *machine_creds,
2740 const char *acct_name,
2742 NTSTATUS expected_samlogon_result)
2745 struct cli_credentials *test_credentials;
2747 test_credentials = cli_credentials_init(tctx);
2749 cli_credentials_set_workstation(test_credentials,
2750 TEST_ACCOUNT_NAME_PWD, CRED_SPECIFIED);
2751 cli_credentials_set_domain(test_credentials,
2752 lp_workgroup(tctx->lp_ctx), CRED_SPECIFIED);
2753 cli_credentials_set_username(test_credentials,
2754 acct_name, CRED_SPECIFIED);
2755 cli_credentials_set_password(test_credentials,
2756 password, CRED_SPECIFIED);
2757 cli_credentials_set_secure_channel_type(test_credentials, SEC_CHAN_BDC);
2759 printf("testing samlogon as %s@%s password: %s\n",
2760 acct_name, TEST_ACCOUNT_NAME_PWD, password);
2762 if (!test_SamLogon(tctx, p, machine_creds, test_credentials,
2763 expected_samlogon_result)) {
2764 torture_warning(tctx, "new password did not work\n");
2771 static bool test_SetPassword_level(struct dcerpc_pipe *p,
2772 struct dcerpc_pipe *np,
2773 struct torture_context *tctx,
2774 struct policy_handle *handle,
2776 uint32_t fields_present,
2777 uint8_t password_expired,
2778 bool *matched_expected_error,
2780 const char *acct_name,
2782 struct cli_credentials *machine_creds,
2783 bool use_queryinfo2,
2785 NTSTATUS expected_samlogon_result)
2787 const char *fields = NULL;
2794 fields = talloc_asprintf(tctx, "(fields_present: 0x%08x)",
2801 torture_comment(tctx, "Testing SetUserInfo%s level %d call "
2802 "(password_expired: %d) %s\n",
2803 use_setinfo2 ? "2":"", level, password_expired,
2804 fields ? fields : "");
2806 if (!test_SetUserPass_level_ex(p, tctx, handle, level,
2811 matched_expected_error)) {
2815 if (!test_QueryUserInfo_pwdlastset(p, tctx, handle,
2821 if (*matched_expected_error == true) {
2825 if (!test_SamLogon_with_creds(tctx, np,
2829 expected_samlogon_result)) {
2836 static bool test_SetPassword_pwdlastset(struct dcerpc_pipe *p,
2837 struct torture_context *tctx,
2838 uint32_t acct_flags,
2839 const char *acct_name,
2840 struct policy_handle *handle,
2842 struct cli_credentials *machine_credentials)
2844 int s = 0, q = 0, f = 0, l = 0, z = 0;
2847 bool set_levels[] = { false, true };
2848 bool query_levels[] = { false, true };
2849 uint32_t levels[] = { 18, 21, 23, 24, 25, 26 };
2850 uint32_t nonzeros[] = { 1, 24 };
2851 uint32_t fields_present[] = {
2853 SAMR_FIELD_EXPIRED_FLAG,
2854 SAMR_FIELD_LAST_PWD_CHANGE,
2855 SAMR_FIELD_EXPIRED_FLAG | SAMR_FIELD_LAST_PWD_CHANGE,
2857 SAMR_FIELD_NT_PASSWORD_PRESENT,
2858 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
2859 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
2860 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
2861 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
2862 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
2863 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE | SAMR_FIELD_EXPIRED_FLAG
2866 struct dcerpc_pipe *np = NULL;
2868 if (torture_setting_bool(tctx, "samba3", false)) {
2870 printf("Samba3 has second granularity, setting delay to: %d\n",
2874 status = torture_rpc_connection(tctx, &np, &ndr_table_netlogon);
2875 if (!NT_STATUS_IS_OK(status)) {
2879 /* set to 1 to enable testing for all possible opcode
2880 (SetUserInfo, SetUserInfo2, QueryUserInfo, QueryUserInfo2)
2883 #define TEST_SET_LEVELS 1
2884 #define TEST_QUERY_LEVELS 1
2886 for (l=0; l<ARRAY_SIZE(levels); l++) {
2887 for (z=0; z<ARRAY_SIZE(nonzeros); z++) {
2888 for (f=0; f<ARRAY_SIZE(fields_present); f++) {
2889 #ifdef TEST_SET_LEVELS
2890 for (s=0; s<ARRAY_SIZE(set_levels); s++) {
2892 #ifdef TEST_QUERY_LEVELS
2893 for (q=0; q<ARRAY_SIZE(query_levels); q++) {
2895 NTTIME pwdlastset_old = 0;
2896 NTTIME pwdlastset_new = 0;
2897 bool matched_expected_error = false;
2898 NTSTATUS expected_samlogon_result = NT_STATUS_ACCOUNT_DISABLED;
2900 torture_comment(tctx, "------------------------------\n"
2901 "Testing pwdLastSet attribute for flags: 0x%08x "
2902 "(s: %d (l: %d), q: %d)\n",
2903 acct_flags, s, levels[l], q);
2905 switch (levels[l]) {
2909 if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
2910 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT))) {
2911 expected_samlogon_result = NT_STATUS_WRONG_PASSWORD;
2919 /* set a password and force password change (pwdlastset 0) by
2920 * setting the password expired flag to a non-0 value */
2922 if (!test_SetPassword_level(p, np, tctx, handle,
2926 &matched_expected_error,
2930 machine_credentials,
2933 expected_samlogon_result)) {
2937 if (matched_expected_error == true) {
2938 /* skipping on expected failure */
2942 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
2943 * set without the SAMR_FIELD_EXPIRED_FLAG */
2945 switch (levels[l]) {
2949 if ((pwdlastset_new != 0) &&
2950 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
2951 torture_comment(tctx, "not considering a non-0 "
2952 "pwdLastSet as a an error as the "
2953 "SAMR_FIELD_EXPIRED_FLAG has not "
2958 if (pwdlastset_new != 0) {
2959 torture_warning(tctx, "pwdLastSet test failed: "
2960 "expected pwdLastSet 0 but got %lld\n",
2967 switch (levels[l]) {
2971 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
2972 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
2973 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
2974 (pwdlastset_old >= pwdlastset_new)) {
2975 torture_warning(tctx, "pwdlastset not increasing\n");
2980 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
2981 (pwdlastset_old >= pwdlastset_new)) {
2982 torture_warning(tctx, "pwdlastset not increasing\n");
2992 /* set a password, pwdlastset needs to get updated (increased
2993 * value), password_expired value used here is 0 */
2995 if (!test_SetPassword_level(p, np, tctx, handle,
2999 &matched_expected_error,
3003 machine_credentials,
3006 expected_samlogon_result)) {
3010 /* when a password has been changed, pwdlastset must not be 0 afterwards
3011 * and must be larger then the old value */
3013 switch (levels[l]) {
3018 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3019 * password has been changed, old and new pwdlastset
3020 * need to be the same value */
3022 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3023 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3024 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3026 torture_assert_int_equal(tctx, pwdlastset_old,
3027 pwdlastset_new, "pwdlastset must be equal");
3031 if (pwdlastset_old >= pwdlastset_new) {
3032 torture_warning(tctx, "pwdLastSet test failed: "
3033 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
3034 pwdlastset_old, pwdlastset_new);
3037 if (pwdlastset_new == 0) {
3038 torture_warning(tctx, "pwdLastSet test failed: "
3039 "expected non-0 pwdlastset, got: %lld\n",
3045 switch (levels[l]) {
3049 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3050 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3051 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3052 (pwdlastset_old >= pwdlastset_new)) {
3053 torture_warning(tctx, "pwdlastset not increasing\n");
3058 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3059 (pwdlastset_old >= pwdlastset_new)) {
3060 torture_warning(tctx, "pwdlastset not increasing\n");
3066 pwdlastset_old = pwdlastset_new;
3072 /* set a password, pwdlastset needs to get updated (increased
3073 * value), password_expired value used here is 0 */
3075 if (!test_SetPassword_level(p, np, tctx, handle,
3079 &matched_expected_error,
3083 machine_credentials,
3086 expected_samlogon_result)) {
3090 /* when a password has been changed, pwdlastset must not be 0 afterwards
3091 * and must be larger then the old value */
3093 switch (levels[l]) {
3098 /* if no password has been changed, old and new pwdlastset
3099 * need to be the same value */
3101 if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3102 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3104 torture_assert_int_equal(tctx, pwdlastset_old,
3105 pwdlastset_new, "pwdlastset must be equal");
3109 if (pwdlastset_old >= pwdlastset_new) {
3110 torture_warning(tctx, "pwdLastSet test failed: "
3111 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
3112 pwdlastset_old, pwdlastset_new);
3115 if (pwdlastset_new == 0) {
3116 torture_warning(tctx, "pwdLastSet test failed: "
3117 "expected non-0 pwdlastset, got: %lld\n",
3125 /* set a password and force password change (pwdlastset 0) by
3126 * setting the password expired flag to a non-0 value */
3128 if (!test_SetPassword_level(p, np, tctx, handle,
3132 &matched_expected_error,
3136 machine_credentials,
3139 expected_samlogon_result)) {
3143 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3144 * set without the SAMR_FIELD_EXPIRED_FLAG */
3146 switch (levels[l]) {
3150 if ((pwdlastset_new != 0) &&
3151 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
3152 torture_comment(tctx, "not considering a non-0 "
3153 "pwdLastSet as a an error as the "
3154 "SAMR_FIELD_EXPIRED_FLAG has not "
3159 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3160 * password has been changed, old and new pwdlastset
3161 * need to be the same value */
3163 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3164 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3165 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3167 torture_assert_int_equal(tctx, pwdlastset_old,
3168 pwdlastset_new, "pwdlastset must be equal");
3173 if (pwdlastset_old == pwdlastset_new) {
3174 torture_warning(tctx, "pwdLastSet test failed: "
3175 "expected last pwdlastset (%lld) != new pwdlastset (%lld)\n",
3176 pwdlastset_old, pwdlastset_new);
3180 if (pwdlastset_new != 0) {
3181 torture_warning(tctx, "pwdLastSet test failed: "
3182 "expected pwdLastSet 0, got %lld\n",
3189 switch (levels[l]) {
3193 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3194 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3195 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3196 (pwdlastset_old >= pwdlastset_new)) {
3197 torture_warning(tctx, "pwdlastset not increasing\n");
3202 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3203 (pwdlastset_old >= pwdlastset_new)) {
3204 torture_warning(tctx, "pwdlastset not increasing\n");
3210 /* if the level we are testing does not have a fields_present
3211 * field, skip all fields present tests by setting f to to
3213 switch (levels[l]) {
3217 f = ARRAY_SIZE(fields_present);
3221 #ifdef TEST_QUERY_LEVELS
3224 #ifdef TEST_SET_LEVELS
3227 } /* fields present */
3231 #undef TEST_SET_LEVELS
3232 #undef TEST_QUERY_LEVELS
3237 static bool test_user_ops(struct dcerpc_pipe *p,
3238 struct torture_context *tctx,
3239 struct policy_handle *user_handle,
3240 struct policy_handle *domain_handle,
3241 uint32_t base_acct_flags,
3242 const char *base_acct_name, enum torture_samr_choice which_ops,
3243 struct cli_credentials *machine_credentials)
3245 char *password = NULL;
3246 struct samr_QueryUserInfo q;
3247 union samr_UserInfo *info;
3253 const uint32_t password_fields[] = {
3254 SAMR_FIELD_NT_PASSWORD_PRESENT,
3255 SAMR_FIELD_LM_PASSWORD_PRESENT,
3256 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
3260 status = test_LookupName(p, tctx, domain_handle, base_acct_name, &rid);
3261 if (!NT_STATUS_IS_OK(status)) {
3265 switch (which_ops) {
3266 case TORTURE_SAMR_USER_ATTRIBUTES:
3267 if (!test_QuerySecurity(p, tctx, user_handle)) {
3271 if (!test_QueryUserInfo(p, tctx, user_handle)) {
3275 if (!test_QueryUserInfo2(p, tctx, user_handle)) {
3279 if (!test_SetUserInfo(p, tctx, user_handle, base_acct_flags,
3284 if (!test_GetUserPwInfo(p, tctx, user_handle)) {
3288 if (!test_TestPrivateFunctionsUser(p, tctx, user_handle)) {
3292 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
3296 case TORTURE_SAMR_PASSWORDS:
3297 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
3298 char simple_pass[9];
3299 char *v = generate_random_str(tctx, 1);
3301 ZERO_STRUCT(simple_pass);
3302 memset(simple_pass, *v, sizeof(simple_pass) - 1);
3304 printf("Testing machine account password policy rules\n");
3306 /* Workstation trust accounts don't seem to need to honour password quality policy */
3307 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
3311 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
3315 /* reset again, to allow another 'user' password change */
3316 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
3320 /* Try a 'short' password */
3321 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
3325 /* Try a compleatly random password */
3326 if (!test_ChangePasswordRandomBytes(p, tctx, base_acct_name, user_handle, &password)) {
3331 for (i = 0; password_fields[i]; i++) {
3332 if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
3336 /* check it was set right */
3337 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3342 for (i = 0; password_fields[i]; i++) {
3343 if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
3347 /* check it was set right */
3348 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3353 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
3357 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
3361 if (torture_setting_bool(tctx, "samba4", false)) {
3362 printf("skipping Set Password level 18 and 21 against Samba4\n");
3365 if (!test_SetUserPass_18(p, tctx, user_handle, &password)) {
3369 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3373 for (i = 0; password_fields[i]; i++) {
3375 if (password_fields[i] == SAMR_FIELD_LM_PASSWORD_PRESENT) {
3376 /* we need to skip as that would break
3377 * the ChangePasswordUser3 verify */
3381 if (!test_SetUserPass_21(p, tctx, user_handle, password_fields[i], &password)) {
3385 /* check it was set right */
3386 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3392 q.in.user_handle = user_handle;
3396 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
3397 if (!NT_STATUS_IS_OK(status)) {
3398 printf("QueryUserInfo level %u failed - %s\n",
3399 q.in.level, nt_errstr(status));
3402 uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
3403 if ((info->info5.acct_flags) != expected_flags) {
3404 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
3405 info->info5.acct_flags,
3409 if (info->info5.rid != rid) {
3410 printf("QuerUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
3411 info->info5.rid, rid);
3418 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
3420 /* test last password change timestamp behaviour */
3421 if (!test_SetPassword_pwdlastset(p, tctx, base_acct_flags,
3423 user_handle, &password,
3424 machine_credentials)) {
3429 torture_comment(tctx, "pwdLastSet test succeeded\n");
3431 torture_warning(tctx, "pwdLastSet test failed\n");
3436 case TORTURE_SAMR_OTHER:
3437 /* We just need the account to exist */
3443 static bool test_alias_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
3444 struct policy_handle *alias_handle,
3445 const struct dom_sid *domain_sid)
3449 if (!test_QuerySecurity(p, tctx, alias_handle)) {
3453 if (!test_QueryAliasInfo(p, tctx, alias_handle)) {
3457 if (!test_SetAliasInfo(p, tctx, alias_handle)) {
3461 if (!test_AddMemberToAlias(p, tctx, alias_handle, domain_sid)) {
3465 if (torture_setting_bool(tctx, "samba4", false)) {
3466 printf("skipping MultipleMembers Alias tests against Samba4\n");
3470 if (!test_AddMultipleMembersToAlias(p, tctx, alias_handle)) {
3478 static bool test_DeleteUser(struct dcerpc_pipe *p, struct torture_context *tctx,
3479 struct policy_handle *user_handle)
3481 struct samr_DeleteUser d;
3483 torture_comment(tctx, "Testing DeleteUser\n");
3485 d.in.user_handle = user_handle;
3486 d.out.user_handle = user_handle;
3488 status = dcerpc_samr_DeleteUser(p, tctx, &d);
3489 torture_assert_ntstatus_ok(tctx, status, "DeleteUser");
3494 bool test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3495 struct policy_handle *handle, const char *name)
3498 struct samr_DeleteUser d;
3499 struct policy_handle user_handle;
3502 status = test_LookupName(p, mem_ctx, handle, name, &rid);
3503 if (!NT_STATUS_IS_OK(status)) {
3507 status = test_OpenUser_byname(p, mem_ctx, handle, name, &user_handle);
3508 if (!NT_STATUS_IS_OK(status)) {
3512 d.in.user_handle = &user_handle;
3513 d.out.user_handle = &user_handle;
3514 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
3515 if (!NT_STATUS_IS_OK(status)) {
3522 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
3527 static bool test_DeleteGroup_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3528 struct policy_handle *handle, const char *name)
3531 struct samr_OpenGroup r;
3532 struct samr_DeleteDomainGroup d;
3533 struct policy_handle group_handle;
3536 status = test_LookupName(p, mem_ctx, handle, name, &rid);
3537 if (!NT_STATUS_IS_OK(status)) {
3541 r.in.domain_handle = handle;
3542 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3544 r.out.group_handle = &group_handle;
3545 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
3546 if (!NT_STATUS_IS_OK(status)) {
3550 d.in.group_handle = &group_handle;
3551 d.out.group_handle = &group_handle;
3552 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
3553 if (!NT_STATUS_IS_OK(status)) {
3560 printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
3565 static bool test_DeleteAlias_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3566 struct policy_handle *domain_handle, const char *name)
3569 struct samr_OpenAlias r;
3570 struct samr_DeleteDomAlias d;
3571 struct policy_handle alias_handle;
3574 printf("testing DeleteAlias_byname\n");
3576 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
3577 if (!NT_STATUS_IS_OK(status)) {
3581 r.in.domain_handle = domain_handle;
3582 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3584 r.out.alias_handle = &alias_handle;
3585 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
3586 if (!NT_STATUS_IS_OK(status)) {
3590 d.in.alias_handle = &alias_handle;
3591 d.out.alias_handle = &alias_handle;
3592 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
3593 if (!NT_STATUS_IS_OK(status)) {
3600 printf("DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
3604 static bool test_DeleteAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3605 struct policy_handle *alias_handle)
3607 struct samr_DeleteDomAlias d;
3610 printf("Testing DeleteAlias\n");
3612 d.in.alias_handle = alias_handle;
3613 d.out.alias_handle = alias_handle;
3615 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
3616 if (!NT_STATUS_IS_OK(status)) {
3617 printf("DeleteAlias failed - %s\n", nt_errstr(status));
3624 static bool test_CreateAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
3625 struct policy_handle *domain_handle,