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,
3626 struct policy_handle *alias_handle,
3627 const struct dom_sid *domain_sid)
3630 struct samr_CreateDomAlias r;
3631 struct lsa_String name;
3635 init_lsa_String(&name, TEST_ALIASNAME);
3636 r.in.domain_handle = domain_handle;
3637 r.in.alias_name = &name;
3638 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3639 r.out.alias_handle = alias_handle;
3642 printf("Testing CreateAlias (%s)\n", r.in.alias_name->string);
3644 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
3646 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
3647 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
3648 printf("Server correctly refused create of '%s'\n", r.in.alias_name->string);
3651 printf("Server should have refused create of '%s', got %s instead\n", r.in.alias_name->string,
3657 if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
3658 if (!test_DeleteAlias_byname(p, tctx, domain_handle, r.in.alias_name->string)) {
3661 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
3664 if (!NT_STATUS_IS_OK(status)) {
3665 printf("CreateAlias failed - %s\n", nt_errstr(status));
3669 if (!test_alias_ops(p, tctx, alias_handle, domain_sid)) {
3676 static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3677 const char *acct_name,
3678 struct policy_handle *domain_handle, char **password)
3686 if (!test_ChangePasswordUser(p, mem_ctx, acct_name, domain_handle, password)) {
3690 if (!test_ChangePasswordUser2(p, mem_ctx, acct_name, password, 0, true)) {
3694 if (!test_OemChangePasswordUser2(p, mem_ctx, acct_name, domain_handle, password)) {
3698 /* test what happens when setting the old password again */
3699 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, *password, 0, true)) {
3704 char simple_pass[9];
3705 char *v = generate_random_str(mem_ctx, 1);
3707 ZERO_STRUCT(simple_pass);
3708 memset(simple_pass, *v, sizeof(simple_pass) - 1);
3710 /* test what happens when picking a simple password */
3711 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, simple_pass, 0, true)) {
3716 /* set samr_SetDomainInfo level 1 with min_length 5 */
3718 struct samr_QueryDomainInfo r;
3719 union samr_DomainInfo *info = NULL;
3720 struct samr_SetDomainInfo s;
3721 uint16_t len_old, len;
3722 uint32_t pwd_prop_old;
3723 int64_t min_pwd_age_old;
3728 r.in.domain_handle = domain_handle;
3732 printf("testing samr_QueryDomainInfo level 1\n");
3733 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
3734 if (!NT_STATUS_IS_OK(status)) {
3738 s.in.domain_handle = domain_handle;
3742 /* remember the old min length, so we can reset it */
3743 len_old = s.in.info->info1.min_password_length;
3744 s.in.info->info1.min_password_length = len;
3745 pwd_prop_old = s.in.info->info1.password_properties;
3746 /* turn off password complexity checks for this test */
3747 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
3749 min_pwd_age_old = s.in.info->info1.min_password_age;
3750 s.in.info->info1.min_password_age = 0;
3752 printf("testing samr_SetDomainInfo level 1\n");
3753 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
3754 if (!NT_STATUS_IS_OK(status)) {
3758 printf("calling test_ChangePasswordUser3 with too short password\n");
3760 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, len - 1, password, NULL, 0, true)) {
3764 s.in.info->info1.min_password_length = len_old;
3765 s.in.info->info1.password_properties = pwd_prop_old;
3766 s.in.info->info1.min_password_age = min_pwd_age_old;
3768 printf("testing samr_SetDomainInfo level 1\n");
3769 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
3770 if (!NT_STATUS_IS_OK(status)) {
3778 struct samr_OpenUser r;
3779 struct samr_QueryUserInfo q;
3780 union samr_UserInfo *info;
3781 struct samr_LookupNames n;
3782 struct policy_handle user_handle;
3783 struct samr_Ids rids, types;
3785 n.in.domain_handle = domain_handle;
3787 n.in.names = talloc_array(mem_ctx, struct lsa_String, 1);
3788 n.in.names[0].string = acct_name;
3790 n.out.types = &types;
3792 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
3793 if (!NT_STATUS_IS_OK(status)) {
3794 printf("LookupNames failed - %s\n", nt_errstr(status));
3798 r.in.domain_handle = domain_handle;
3799 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3800 r.in.rid = n.out.rids->ids[0];
3801 r.out.user_handle = &user_handle;
3803 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3804 if (!NT_STATUS_IS_OK(status)) {
3805 printf("OpenUser(%u) failed - %s\n", n.out.rids->ids[0], nt_errstr(status));
3809 q.in.user_handle = &user_handle;
3813 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
3814 if (!NT_STATUS_IS_OK(status)) {
3815 printf("QueryUserInfo failed - %s\n", nt_errstr(status));
3819 printf("calling test_ChangePasswordUser3 with too early password change\n");
3821 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL,
3822 info->info5.last_password_change, true)) {
3827 /* we change passwords twice - this has the effect of verifying
3828 they were changed correctly for the final call */
3829 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, true)) {
3833 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, true)) {
3840 static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
3841 struct policy_handle *domain_handle,
3842 struct policy_handle *user_handle_out,
3843 struct dom_sid *domain_sid,
3844 enum torture_samr_choice which_ops,
3845 struct cli_credentials *machine_credentials)
3848 TALLOC_CTX *user_ctx;
3851 struct samr_CreateUser r;
3852 struct samr_QueryUserInfo q;
3853 union samr_UserInfo *info;
3854 struct samr_DeleteUser d;
3857 /* This call creates a 'normal' account - check that it really does */
3858 const uint32_t acct_flags = ACB_NORMAL;
3859 struct lsa_String name;
3862 struct policy_handle user_handle;
3863 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
3864 init_lsa_String(&name, TEST_ACCOUNT_NAME);
3866 r.in.domain_handle = domain_handle;
3867 r.in.account_name = &name;
3868 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3869 r.out.user_handle = &user_handle;
3872 printf("Testing CreateUser(%s)\n", r.in.account_name->string);
3874 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
3876 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
3877 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
3878 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
3881 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
3887 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
3888 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
3889 talloc_free(user_ctx);
3892 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
3894 if (!NT_STATUS_IS_OK(status)) {
3895 talloc_free(user_ctx);
3896 printf("CreateUser failed - %s\n", nt_errstr(status));
3899 q.in.user_handle = &user_handle;
3903 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
3904 if (!NT_STATUS_IS_OK(status)) {
3905 printf("QueryUserInfo level %u failed - %s\n",
3906 q.in.level, nt_errstr(status));
3909 if ((info->info16.acct_flags & acct_flags) != acct_flags) {
3910 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
3911 info->info16.acct_flags,
3917 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
3918 acct_flags, name.string, which_ops,
3919 machine_credentials)) {
3923 if (user_handle_out) {
3924 *user_handle_out = user_handle;
3926 printf("Testing DeleteUser (createuser test)\n");
3928 d.in.user_handle = &user_handle;
3929 d.out.user_handle = &user_handle;
3931 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
3932 if (!NT_STATUS_IS_OK(status)) {
3933 printf("DeleteUser failed - %s\n", nt_errstr(status));
3940 talloc_free(user_ctx);
3946 static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
3947 struct policy_handle *domain_handle,
3948 struct dom_sid *domain_sid,
3949 enum torture_samr_choice which_ops,
3950 struct cli_credentials *machine_credentials)
3953 struct samr_CreateUser2 r;
3954 struct samr_QueryUserInfo q;
3955 union samr_UserInfo *info;
3956 struct samr_DeleteUser d;
3957 struct policy_handle user_handle;
3959 struct lsa_String name;
3964 uint32_t acct_flags;
3965 const char *account_name;
3967 } account_types[] = {
3968 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
3969 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
3970 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
3971 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
3972 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
3973 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
3974 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
3975 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
3976 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
3977 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
3978 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
3979 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
3980 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
3981 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
3982 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
3985 for (i = 0; account_types[i].account_name; i++) {
3986 TALLOC_CTX *user_ctx;
3987 uint32_t acct_flags = account_types[i].acct_flags;
3988 uint32_t access_granted;
3989 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
3990 init_lsa_String(&name, account_types[i].account_name);
3992 r.in.domain_handle = domain_handle;
3993 r.in.account_name = &name;
3994 r.in.acct_flags = acct_flags;
3995 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3996 r.out.user_handle = &user_handle;
3997 r.out.access_granted = &access_granted;
4000 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
4002 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
4004 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
4005 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
4006 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
4009 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
4016 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
4017 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
4018 talloc_free(user_ctx);
4022 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
4025 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
4026 printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
4027 nt_errstr(status), nt_errstr(account_types[i].nt_status));
4031 if (NT_STATUS_IS_OK(status)) {
4032 q.in.user_handle = &user_handle;
4036 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
4037 if (!NT_STATUS_IS_OK(status)) {
4038 printf("QueryUserInfo level %u failed - %s\n",
4039 q.in.level, nt_errstr(status));
4042 uint32_t expected_flags = (acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
4043 if (acct_flags == ACB_NORMAL) {
4044 expected_flags |= ACB_PW_EXPIRED;
4046 if ((info->info5.acct_flags) != expected_flags) {
4047 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
4048 info->info5.acct_flags,
4052 switch (acct_flags) {
4054 if (info->info5.primary_gid != DOMAIN_RID_DCS) {
4055 printf("QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n",
4056 DOMAIN_RID_DCS, info->info5.primary_gid);
4061 if (info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
4062 printf("QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
4063 DOMAIN_RID_DOMAIN_MEMBERS, info->info5.primary_gid);
4068 if (info->info5.primary_gid != DOMAIN_RID_USERS) {
4069 printf("QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n",
4070 DOMAIN_RID_USERS, info->info5.primary_gid);
4077 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
4078 acct_flags, name.string, which_ops,
4079 machine_credentials)) {
4083 printf("Testing DeleteUser (createuser2 test)\n");
4085 d.in.user_handle = &user_handle;
4086 d.out.user_handle = &user_handle;
4088 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
4089 if (!NT_STATUS_IS_OK(status)) {
4090 printf("DeleteUser failed - %s\n", nt_errstr(status));
4094 talloc_free(user_ctx);
4100 static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4101 struct policy_handle *handle)
4104 struct samr_QueryAliasInfo r;
4105 union samr_AliasInfo *info;
4106 uint16_t levels[] = {1, 2, 3};
4110 for (i=0;i<ARRAY_SIZE(levels);i++) {
4111 printf("Testing QueryAliasInfo level %u\n", levels[i]);
4113 r.in.alias_handle = handle;
4114 r.in.level = levels[i];
4117 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
4118 if (!NT_STATUS_IS_OK(status)) {
4119 printf("QueryAliasInfo level %u failed - %s\n",
4120 levels[i], nt_errstr(status));
4128 static bool test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4129 struct policy_handle *handle)
4132 struct samr_QueryGroupInfo r;
4133 union samr_GroupInfo *info;
4134 uint16_t levels[] = {1, 2, 3, 4, 5};
4138 for (i=0;i<ARRAY_SIZE(levels);i++) {
4139 printf("Testing QueryGroupInfo level %u\n", levels[i]);
4141 r.in.group_handle = handle;
4142 r.in.level = levels[i];
4145 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
4146 if (!NT_STATUS_IS_OK(status)) {
4147 printf("QueryGroupInfo level %u failed - %s\n",
4148 levels[i], nt_errstr(status));
4156 static bool test_QueryGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4157 struct policy_handle *handle)
4160 struct samr_QueryGroupMember r;
4161 struct samr_RidTypeArray *rids = NULL;
4164 printf("Testing QueryGroupMember\n");
4166 r.in.group_handle = handle;
4169 status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &r);
4170 if (!NT_STATUS_IS_OK(status)) {
4171 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
4179 static bool test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4180 struct policy_handle *handle)
4183 struct samr_QueryGroupInfo r;
4184 union samr_GroupInfo *info;
4185 struct samr_SetGroupInfo s;
4186 uint16_t levels[] = {1, 2, 3, 4};
4187 uint16_t set_ok[] = {0, 1, 1, 1};
4191 for (i=0;i<ARRAY_SIZE(levels);i++) {
4192 printf("Testing QueryGroupInfo level %u\n", levels[i]);
4194 r.in.group_handle = handle;
4195 r.in.level = levels[i];
4198 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
4199 if (!NT_STATUS_IS_OK(status)) {
4200 printf("QueryGroupInfo level %u failed - %s\n",
4201 levels[i], nt_errstr(status));
4205 printf("Testing SetGroupInfo level %u\n", levels[i]);
4207 s.in.group_handle = handle;
4208 s.in.level = levels[i];
4209 s.in.info = *r.out.info;
4212 /* disabled this, as it changes the name only from the point of view of samr,
4213 but leaves the name from the point of view of w2k3 internals (and ldap). This means
4214 the name is still reserved, so creating the old name fails, but deleting by the old name
4216 if (s.in.level == 2) {
4217 init_lsa_String(&s.in.info->string, "NewName");
4221 if (s.in.level == 4) {
4222 init_lsa_String(&s.in.info->description, "test description");
4225 status = dcerpc_samr_SetGroupInfo(p, mem_ctx, &s);
4227 if (!NT_STATUS_IS_OK(status)) {
4228 printf("SetGroupInfo level %u failed - %s\n",
4229 r.in.level, nt_errstr(status));
4234 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
4235 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
4236 r.in.level, nt_errstr(status));
4246 static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4247 struct policy_handle *handle)
4250 struct samr_QueryUserInfo r;
4251 union samr_UserInfo *info;
4252 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
4253 11, 12, 13, 14, 16, 17, 20, 21};
4257 for (i=0;i<ARRAY_SIZE(levels);i++) {
4258 printf("Testing QueryUserInfo level %u\n", levels[i]);
4260 r.in.user_handle = handle;
4261 r.in.level = levels[i];
4264 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
4265 if (!NT_STATUS_IS_OK(status)) {
4266 printf("QueryUserInfo level %u failed - %s\n",
4267 levels[i], nt_errstr(status));
4275 static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4276 struct policy_handle *handle)
4279 struct samr_QueryUserInfo2 r;
4280 union samr_UserInfo *info;
4281 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
4282 11, 12, 13, 14, 16, 17, 20, 21};
4286 for (i=0;i<ARRAY_SIZE(levels);i++) {
4287 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
4289 r.in.user_handle = handle;
4290 r.in.level = levels[i];
4293 status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r);
4294 if (!NT_STATUS_IS_OK(status)) {
4295 printf("QueryUserInfo2 level %u failed - %s\n",
4296 levels[i], nt_errstr(status));
4304 static bool test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4305 struct policy_handle *handle, uint32_t rid)
4308 struct samr_OpenUser r;
4309 struct policy_handle user_handle;
4312 printf("Testing OpenUser(%u)\n", rid);
4314 r.in.domain_handle = handle;
4315 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4317 r.out.user_handle = &user_handle;
4319 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
4320 if (!NT_STATUS_IS_OK(status)) {
4321 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
4325 if (!test_QuerySecurity(p, mem_ctx, &user_handle)) {
4329 if (!test_QueryUserInfo(p, mem_ctx, &user_handle)) {
4333 if (!test_QueryUserInfo2(p, mem_ctx, &user_handle)) {
4337 if (!test_GetUserPwInfo(p, mem_ctx, &user_handle)) {
4341 if (!test_GetGroupsForUser(p,mem_ctx, &user_handle)) {
4345 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
4352 static bool test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4353 struct policy_handle *handle, uint32_t rid)
4356 struct samr_OpenGroup r;
4357 struct policy_handle group_handle;
4360 printf("Testing OpenGroup(%u)\n", rid);
4362 r.in.domain_handle = handle;
4363 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4365 r.out.group_handle = &group_handle;
4367 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
4368 if (!NT_STATUS_IS_OK(status)) {
4369 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
4373 if (!test_QuerySecurity(p, mem_ctx, &group_handle)) {
4377 if (!test_QueryGroupInfo(p, mem_ctx, &group_handle)) {
4381 if (!test_QueryGroupMember(p, mem_ctx, &group_handle)) {
4385 if (!test_samr_handle_Close(p, mem_ctx, &group_handle)) {
4392 static bool test_OpenAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
4393 struct policy_handle *handle, uint32_t rid)
4396 struct samr_OpenAlias r;
4397 struct policy_handle alias_handle;
4400 torture_comment(tctx, "Testing OpenAlias(%u)\n", rid);
4402 r.in.domain_handle = handle;
4403 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4405 r.out.alias_handle = &alias_handle;
4407 status = dcerpc_samr_OpenAlias(p, tctx, &r);
4408 if (!NT_STATUS_IS_OK(status)) {
4409 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
4413 if (!test_QuerySecurity(p, tctx, &alias_handle)) {
4417 if (!test_QueryAliasInfo(p, tctx, &alias_handle)) {
4421 if (!test_GetMembersInAlias(p, tctx, &alias_handle)) {
4425 if (!test_samr_handle_Close(p, tctx, &alias_handle)) {
4432 static bool check_mask(struct dcerpc_pipe *p, struct torture_context *tctx,
4433 struct policy_handle *handle, uint32_t rid,
4434 uint32_t acct_flag_mask)
4437 struct samr_OpenUser r;
4438 struct samr_QueryUserInfo q;
4439 union samr_UserInfo *info;
4440 struct policy_handle user_handle;
4443 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
4445 r.in.domain_handle = handle;
4446 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4448 r.out.user_handle = &user_handle;
4450 status = dcerpc_samr_OpenUser(p, tctx, &r);
4451 if (!NT_STATUS_IS_OK(status)) {
4452 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
4456 q.in.user_handle = &user_handle;
4460 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
4461 if (!NT_STATUS_IS_OK(status)) {
4462 printf("QueryUserInfo level 16 failed - %s\n",
4466 if ((acct_flag_mask & info->info16.acct_flags) == 0) {
4467 printf("Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
4468 acct_flag_mask, info->info16.acct_flags, rid);
4473 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
4480 static bool test_EnumDomainUsers(struct dcerpc_pipe *p, struct torture_context *tctx,
4481 struct policy_handle *handle)
4483 NTSTATUS status = STATUS_MORE_ENTRIES;
4484 struct samr_EnumDomainUsers r;
4485 uint32_t mask, resume_handle=0;
4488 struct samr_LookupNames n;
4489 struct samr_LookupRids lr ;
4490 struct lsa_Strings names;
4491 struct samr_Ids rids, types;
4492 struct samr_SamArray *sam = NULL;
4493 uint32_t num_entries = 0;
4495 uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
4496 ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
4497 ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
4500 printf("Testing EnumDomainUsers\n");
4502 for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
4503 r.in.domain_handle = handle;
4504 r.in.resume_handle = &resume_handle;
4505 r.in.acct_flags = mask = masks[mask_idx];
4506 r.in.max_size = (uint32_t)-1;
4507 r.out.resume_handle = &resume_handle;
4508 r.out.num_entries = &num_entries;
4511 status = dcerpc_samr_EnumDomainUsers(p, tctx, &r);
4512 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
4513 !NT_STATUS_IS_OK(status)) {
4514 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
4518 torture_assert(tctx, sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
4520 if (sam->count == 0) {
4524 for (i=0;i<sam->count;i++) {
4526 if (!check_mask(p, tctx, handle, sam->entries[i].idx, mask)) {
4529 } else if (!test_OpenUser(p, tctx, handle, sam->entries[i].idx)) {
4535 printf("Testing LookupNames\n");
4536 n.in.domain_handle = handle;
4537 n.in.num_names = sam->count;
4538 n.in.names = talloc_array(tctx, struct lsa_String, sam->count);
4540 n.out.types = &types;
4541 for (i=0;i<sam->count;i++) {
4542 n.in.names[i].string = sam->entries[i].name.string;
4544 status = dcerpc_samr_LookupNames(p, tctx, &n);
4545 if (!NT_STATUS_IS_OK(status)) {
4546 printf("LookupNames failed - %s\n", nt_errstr(status));
4551 printf("Testing LookupRids\n");
4552 lr.in.domain_handle = handle;
4553 lr.in.num_rids = sam->count;
4554 lr.in.rids = talloc_array(tctx, uint32_t, sam->count);
4555 lr.out.names = &names;
4556 lr.out.types = &types;
4557 for (i=0;i<sam->count;i++) {
4558 lr.in.rids[i] = sam->entries[i].idx;
4560 status = dcerpc_samr_LookupRids(p, tctx, &lr);
4561 torture_assert_ntstatus_ok(tctx, status, "LookupRids");
4567 try blasting the server with a bunch of sync requests
4569 static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, struct torture_context *tctx,
4570 struct policy_handle *handle)
4573 struct samr_EnumDomainUsers r;
4574 uint32_t resume_handle=0;
4576 #define ASYNC_COUNT 100
4577 struct rpc_request *req[ASYNC_COUNT];
4579 if (!torture_setting_bool(tctx, "dangerous", false)) {
4580 torture_skip(tctx, "samr async test disabled - enable dangerous tests to use\n");
4583 torture_comment(tctx, "Testing EnumDomainUsers_async\n");
4585 r.in.domain_handle = handle;
4586 r.in.resume_handle = &resume_handle;
4587 r.in.acct_flags = 0;
4588 r.in.max_size = (uint32_t)-1;
4589 r.out.resume_handle = &resume_handle;
4591 for (i=0;i<ASYNC_COUNT;i++) {
4592 req[i] = dcerpc_samr_EnumDomainUsers_send(p, tctx, &r);
4595 for (i=0;i<ASYNC_COUNT;i++) {
4596 status = dcerpc_ndr_request_recv(req[i]);
4597 if (!NT_STATUS_IS_OK(status)) {
4598 printf("EnumDomainUsers[%d] failed - %s\n",
4599 i, nt_errstr(status));
4604 torture_comment(tctx, "%d async requests OK\n", i);
4609 static bool test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4610 struct policy_handle *handle)
4613 struct samr_EnumDomainGroups r;
4614 uint32_t resume_handle=0;
4615 struct samr_SamArray *sam = NULL;
4616 uint32_t num_entries = 0;
4620 printf("Testing EnumDomainGroups\n");
4622 r.in.domain_handle = handle;
4623 r.in.resume_handle = &resume_handle;
4624 r.in.max_size = (uint32_t)-1;
4625 r.out.resume_handle = &resume_handle;
4626 r.out.num_entries = &num_entries;
4629 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
4630 if (!NT_STATUS_IS_OK(status)) {
4631 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
4639 for (i=0;i<sam->count;i++) {
4640 if (!test_OpenGroup(p, mem_ctx, handle, sam->entries[i].idx)) {
4648 static bool test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4649 struct policy_handle *handle)
4652 struct samr_EnumDomainAliases r;
4653 uint32_t resume_handle=0;
4654 struct samr_SamArray *sam = NULL;
4655 uint32_t num_entries = 0;
4659 printf("Testing EnumDomainAliases\n");
4661 r.in.domain_handle = handle;
4662 r.in.resume_handle = &resume_handle;
4663 r.in.max_size = (uint32_t)-1;
4665 r.out.num_entries = &num_entries;
4666 r.out.resume_handle = &resume_handle;
4668 status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
4669 if (!NT_STATUS_IS_OK(status)) {
4670 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
4678 for (i=0;i<sam->count;i++) {
4679 if (!test_OpenAlias(p, mem_ctx, handle, sam->entries[i].idx)) {
4687 static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4688 struct policy_handle *handle)
4691 struct samr_GetDisplayEnumerationIndex r;
4693 uint16_t levels[] = {1, 2, 3, 4, 5};
4694 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
4695 struct lsa_String name;
4699 for (i=0;i<ARRAY_SIZE(levels);i++) {
4700 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
4702 init_lsa_String(&name, TEST_ACCOUNT_NAME);
4704 r.in.domain_handle = handle;
4705 r.in.level = levels[i];
4709 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
4712 !NT_STATUS_IS_OK(status) &&
4713 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
4714 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
4715 levels[i], nt_errstr(status));
4719 init_lsa_String(&name, "zzzzzzzz");
4721 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
4723 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
4724 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
4725 levels[i], nt_errstr(status));
4733 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4734 struct policy_handle *handle)
4737 struct samr_GetDisplayEnumerationIndex2 r;
4739 uint16_t levels[] = {1, 2, 3, 4, 5};
4740 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
4741 struct lsa_String name;
4745 for (i=0;i<ARRAY_SIZE(levels);i++) {
4746 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
4748 init_lsa_String(&name, TEST_ACCOUNT_NAME);
4750 r.in.domain_handle = handle;
4751 r.in.level = levels[i];
4755 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
4757 !NT_STATUS_IS_OK(status) &&
4758 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
4759 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
4760 levels[i], nt_errstr(status));
4764 init_lsa_String(&name, "zzzzzzzz");
4766 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
4767 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
4768 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
4769 levels[i], nt_errstr(status));
4777 #define STRING_EQUAL_QUERY(s1, s2, user) \
4778 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
4779 /* odd, but valid */ \
4780 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
4781 printf("%s mismatch for %s: %s != %s (%s)\n", \
4782 #s1, user.string, s1.string, s2.string, __location__); \
4785 #define INT_EQUAL_QUERY(s1, s2, user) \
4787 printf("%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
4788 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
4792 static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4793 struct samr_QueryDisplayInfo *querydisplayinfo,
4794 bool *seen_testuser)
4796 struct samr_OpenUser r;
4797 struct samr_QueryUserInfo q;
4798 union samr_UserInfo *info;
4799 struct policy_handle user_handle;
4802 r.in.domain_handle = querydisplayinfo->in.domain_handle;
4803 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4804 for (i = 0; ; i++) {
4805 switch (querydisplayinfo->in.level) {
4807 if (i >= querydisplayinfo->out.info->info1.count) {
4810 r.in.rid = querydisplayinfo->out.info->info1.entries[i].rid;
4813 if (i >= querydisplayinfo->out.info->info2.count) {
4816 r.in.rid = querydisplayinfo->out.info->info2.entries[i].rid;
4822 /* Not interested in validating just the account name */
4826 r.out.user_handle = &user_handle;
4828 switch (querydisplayinfo->in.level) {
4831 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
4832 if (!NT_STATUS_IS_OK(status)) {
4833 printf("OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(status));
4838 q.in.user_handle = &user_handle;
4841 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
4842 if (!NT_STATUS_IS_OK(status)) {
4843 printf("QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(status));
4847 switch (querydisplayinfo->in.level) {
4849 if (seen_testuser && strcmp(info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
4850 *seen_testuser = true;
4852 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].full_name,
4853 info->info21.full_name, info->info21.account_name);
4854 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].account_name,
4855 info->info21.account_name, info->info21.account_name);
4856 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].description,
4857 info->info21.description, info->info21.account_name);
4858 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].rid,
4859 info->info21.rid, info->info21.account_name);
4860 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].acct_flags,
4861 info->info21.acct_flags, info->info21.account_name);
4865 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].account_name,
4866 info->info21.account_name, info->info21.account_name);
4867 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].description,
4868 info->info21.description, info->info21.account_name);
4869 INT_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].rid,
4870 info->info21.rid, info->info21.account_name);
4871 INT_EQUAL_QUERY((querydisplayinfo->out.info->info2.entries[i].acct_flags & ~ACB_NORMAL),
4872 info->info21.acct_flags, info->info21.account_name);
4874 if (!(querydisplayinfo->out.info->info2.entries[i].acct_flags & ACB_NORMAL)) {
4875 printf("Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
4876 info->info21.account_name.string);
4879 if (!(info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
4880 printf("Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
4881 info->info21.account_name.string,
4882 querydisplayinfo->out.info->info2.entries[i].acct_flags,
4883 info->info21.acct_flags);
4890 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
4897 static bool test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4898 struct policy_handle *handle)
4901 struct samr_QueryDisplayInfo r;
4902 struct samr_QueryDomainInfo dom_info;
4903 union samr_DomainInfo *info = NULL;
4905 uint16_t levels[] = {1, 2, 3, 4, 5};
4907 bool seen_testuser = false;
4908 uint32_t total_size;
4909 uint32_t returned_size;
4910 union samr_DispInfo disp_info;
4913 for (i=0;i<ARRAY_SIZE(levels);i++) {
4914 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
4917 status = STATUS_MORE_ENTRIES;
4918 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
4919 r.in.domain_handle = handle;
4920 r.in.level = levels[i];
4921 r.in.max_entries = 2;
4922 r.in.buf_size = (uint32_t)-1;
4923 r.out.total_size = &total_size;
4924 r.out.returned_size = &returned_size;
4925 r.out.info = &disp_info;
4927 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
4928 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(status)) {
4929 printf("QueryDisplayInfo level %u failed - %s\n",
4930 levels[i], nt_errstr(status));
4933 switch (r.in.level) {
4935 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, &seen_testuser)) {
4938 r.in.start_idx += r.out.info->info1.count;
4941 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, NULL)) {
4944 r.in.start_idx += r.out.info->info2.count;
4947 r.in.start_idx += r.out.info->info3.count;
4950 r.in.start_idx += r.out.info->info4.count;
4953 r.in.start_idx += r.out.info->info5.count;
4957 dom_info.in.domain_handle = handle;
4958 dom_info.in.level = 2;
4959 dom_info.out.info = &info;
4961 /* Check number of users returned is correct */
4962 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &dom_info);
4963 if (!NT_STATUS_IS_OK(status)) {
4964 printf("QueryDomainInfo level %u failed - %s\n",
4965 r.in.level, nt_errstr(status));
4969 switch (r.in.level) {
4972 if (info->general.num_users < r.in.start_idx) {
4973 printf("QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
4974 r.in.start_idx, info->general.num_groups,
4975 info->general.domain_name.string);
4978 if (!seen_testuser) {
4979 struct policy_handle user_handle;
4980 if (NT_STATUS_IS_OK(test_OpenUser_byname(p, mem_ctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
4981 printf("Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
4982 info->general.domain_name.string);
4984 test_samr_handle_Close(p, mem_ctx, &user_handle);
4990 if (info->general.num_groups != r.in.start_idx) {
4991 printf("QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
4992 r.in.start_idx, info->general.num_groups,
4993 info->general.domain_name.string);
5005 static bool test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
5006 struct policy_handle *handle)
5009 struct samr_QueryDisplayInfo2 r;
5011 uint16_t levels[] = {1, 2, 3, 4, 5};
5013 uint32_t total_size;
5014 uint32_t returned_size;
5015 union samr_DispInfo info;
5017 for (i=0;i<ARRAY_SIZE(levels);i++) {
5018 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
5020 r.in.domain_handle = handle;
5021 r.in.level = levels[i];
5023 r.in.max_entries = 1000;
5024 r.in.buf_size = (uint32_t)-1;
5025 r.out.total_size = &total_size;
5026 r.out.returned_size = &returned_size;
5029 status = dcerpc_samr_QueryDisplayInfo2(p, mem_ctx, &r);
5030 if (!NT_STATUS_IS_OK(status)) {
5031 printf("QueryDisplayInfo2 level %u failed - %s\n",
5032 levels[i], nt_errstr(status));
5040 static bool test_QueryDisplayInfo3(struct dcerpc_pipe *p, struct torture_context *tctx,
5041 struct policy_handle *handle)
5044 struct samr_QueryDisplayInfo3 r;
5046 uint16_t levels[] = {1, 2, 3, 4, 5};
5048 uint32_t total_size;
5049 uint32_t returned_size;
5050 union samr_DispInfo info;
5052 for (i=0;i<ARRAY_SIZE(levels);i++) {
5053 torture_comment(tctx, "Testing QueryDisplayInfo3 level %u\n", levels[i]);
5055 r.in.domain_handle = handle;
5056 r.in.level = levels[i];
5058 r.in.max_entries = 1000;
5059 r.in.buf_size = (uint32_t)-1;
5060 r.out.total_size = &total_size;
5061 r.out.returned_size = &returned_size;
5064 status = dcerpc_samr_QueryDisplayInfo3(p, tctx, &r);
5065 if (!NT_STATUS_IS_OK(status)) {
5066 printf("QueryDisplayInfo3 level %u failed - %s\n",
5067 levels[i], nt_errstr(status));
5076 static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
5077 struct policy_handle *handle)
5080 struct samr_QueryDisplayInfo r;
5082 uint32_t total_size;
5083 uint32_t returned_size;
5084 union samr_DispInfo info;
5086 printf("Testing QueryDisplayInfo continuation\n");
5088 r.in.domain_handle = handle;
5091 r.in.max_entries = 1;
5092 r.in.buf_size = (uint32_t)-1;
5093 r.out.total_size = &total_size;
5094 r.out.returned_size = &returned_size;
5098 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
5099 if (NT_STATUS_IS_OK(status) && *r.out.returned_size != 0) {
5100 if (r.out.info->info1.entries[0].idx != r.in.start_idx + 1) {
5101 printf("expected idx %d but got %d\n",
5103 r.out.info->info1.entries[0].idx);
5107 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
5108 !NT_STATUS_IS_OK(status)) {
5109 printf("QueryDisplayInfo level %u failed - %s\n",
5110 r.in.level, nt_errstr(status));
5115 } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
5116 NT_STATUS_IS_OK(status)) &&
5117 *r.out.returned_size != 0);
5122 static bool test_QueryDomainInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
5123 struct policy_handle *handle)
5126 struct samr_QueryDomainInfo r;
5127 union samr_DomainInfo *info = NULL;
5128 struct samr_SetDomainInfo s;
5129 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
5130 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
5133 const char *domain_comment = talloc_asprintf(tctx,
5134 "Tortured by Samba4 RPC-SAMR: %s",
5135 timestring(tctx, time(NULL)));
5137 s.in.domain_handle = handle;
5139 s.in.info = talloc(tctx, union samr_DomainInfo);
5141 s.in.info->oem.oem_information.string = domain_comment;
5142 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
5143 if (!NT_STATUS_IS_OK(status)) {
5144 printf("SetDomainInfo level %u (set comment) failed - %s\n",
5145 r.in.level, nt_errstr(status));
5149 for (i=0;i<ARRAY_SIZE(levels);i++) {
5150 torture_comment(tctx, "Testing QueryDomainInfo level %u\n", levels[i]);
5152 r.in.domain_handle = handle;
5153 r.in.level = levels[i];
5156 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
5157 if (!NT_STATUS_IS_OK(status)) {
5158 printf("QueryDomainInfo level %u failed - %s\n",
5159 r.in.level, nt_errstr(status));
5164 switch (levels[i]) {
5166 if (strcmp(info->general.oem_information.string, domain_comment) != 0) {
5167 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
5168 levels[i], info->general.oem_information.string, domain_comment);
5171 if (!info->general.primary.string) {
5172 printf("QueryDomainInfo level %u returned no PDC name\n",
5175 } else if (info->general.role == SAMR_ROLE_DOMAIN_PDC) {
5176 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), info->general.primary.string) != 0) {
5177 printf("QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
5178 levels[i], info->general.primary.string, dcerpc_server_name(p));
5183 if (strcmp(info->oem.oem_information.string, domain_comment) != 0) {
5184 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
5185 levels[i], info->oem.oem_information.string, domain_comment);
5190 if (!info->info6.primary.string) {
5191 printf("QueryDomainInfo level %u returned no PDC name\n",
5197 if (strcmp(info->general2.general.oem_information.string, domain_comment) != 0) {
5198 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
5199 levels[i], info->general2.general.oem_information.string, domain_comment);
5205 torture_comment(tctx, "Testing SetDomainInfo level %u\n", levels[i]);
5207 s.in.domain_handle = handle;
5208 s.in.level = levels[i];
5211 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
5213 if (!NT_STATUS_IS_OK(status)) {
5214 printf("SetDomainInfo level %u failed - %s\n",
5215 r.in.level, nt_errstr(status));
5220 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
5221 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
5222 r.in.level, nt_errstr(status));
5228 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
5229 if (!NT_STATUS_IS_OK(status)) {
5230 printf("QueryDomainInfo level %u failed - %s\n",
5231 r.in.level, nt_errstr(status));
5241 static bool test_QueryDomainInfo2(struct dcerpc_pipe *p, struct torture_context *tctx,
5242 struct policy_handle *handle)
5245 struct samr_QueryDomainInfo2 r;
5246 union samr_DomainInfo *info = NULL;
5247 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
5251 for (i=0;i<ARRAY_SIZE(levels);i++) {
5252 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
5254 r.in.domain_handle = handle;
5255 r.in.level = levels[i];
5258 status = dcerpc_samr_QueryDomainInfo2(p, tctx, &r);
5259 if (!NT_STATUS_IS_OK(status)) {
5260 printf("QueryDomainInfo2 level %u failed - %s\n",
5261 r.in.level, nt_errstr(status));
5270 /* Test whether querydispinfo level 5 and enumdomgroups return the same
5271 set of group names. */
5272 static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx,
5273 struct policy_handle *handle)
5275 struct samr_EnumDomainGroups q1;
5276 struct samr_QueryDisplayInfo q2;
5278 uint32_t resume_handle=0;
5279 struct samr_SamArray *sam = NULL;
5280 uint32_t num_entries = 0;
5283 uint32_t total_size;
5284 uint32_t returned_size;
5285 union samr_DispInfo info;
5288 const char **names = NULL;
5290 torture_comment(tctx, "Testing coherency of querydispinfo vs enumdomgroups\n");
5292 q1.in.domain_handle = handle;
5293 q1.in.resume_handle = &resume_handle;
5295 q1.out.resume_handle = &resume_handle;
5296 q1.out.num_entries = &num_entries;
5299 status = STATUS_MORE_ENTRIES;
5300 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
5301 status = dcerpc_samr_EnumDomainGroups(p, tctx, &q1);
5303 if (!NT_STATUS_IS_OK(status) &&
5304 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
5307 for (i=0; i<*q1.out.num_entries; i++) {
5308 add_string_to_array(tctx,
5309 sam->entries[i].name.string,
5310 &names, &num_names);
5314 torture_assert_ntstatus_ok(tctx, status, "EnumDomainGroups");
5316 torture_assert(tctx, sam, "EnumDomainGroups failed to return sam");
5318 q2.in.domain_handle = handle;
5320 q2.in.start_idx = 0;
5321 q2.in.max_entries = 5;
5322 q2.in.buf_size = (uint32_t)-1;
5323 q2.out.total_size = &total_size;
5324 q2.out.returned_size = &returned_size;
5325 q2.out.info = &info;
5327 status = STATUS_MORE_ENTRIES;
5328 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
5329 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &q2);
5331 if (!NT_STATUS_IS_OK(status) &&
5332 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
5335 for (i=0; i<q2.out.info->info5.count; i++) {
5337 const char *name = q2.out.info->info5.entries[i].account_name.string;
5339 for (j=0; j<num_names; j++) {
5340 if (names[j] == NULL)
5342 if (strequal(names[j], name)) {
5350 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
5355 q2.in.start_idx += q2.out.info->info5.count;
5358 if (!NT_STATUS_IS_OK(status)) {
5359 printf("QueryDisplayInfo level 5 failed - %s\n",
5364 for (i=0; i<num_names; i++) {
5365 if (names[i] != NULL) {
5366 printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
5375 static bool test_DeleteDomainGroup(struct dcerpc_pipe *p, struct torture_context *tctx,
5376 struct policy_handle *group_handle)
5378 struct samr_DeleteDomainGroup d;
5381 torture_comment(tctx, "Testing DeleteDomainGroup\n");
5383 d.in.group_handle = group_handle;
5384 d.out.group_handle = group_handle;
5386 status = dcerpc_samr_DeleteDomainGroup(p, tctx, &d);
5387 torture_assert_ntstatus_ok(tctx, status, "DeleteDomainGroup");
5392 static bool test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
5393 struct policy_handle *domain_handle)
5395 struct samr_TestPrivateFunctionsDomain r;
5399 torture_comment(tctx, "Testing TestPrivateFunctionsDomain\n");
5401 r.in.domain_handle = domain_handle;
5403 status = dcerpc_samr_TestPrivateFunctionsDomain(p, tctx, &r);
5404 torture_assert_ntstatus_equal(tctx, NT_STATUS_NOT_IMPLEMENTED, status, "TestPrivateFunctionsDomain");
5409 static bool test_RidToSid(struct dcerpc_pipe *p, struct torture_context *tctx,
5410 struct dom_sid *domain_sid,
5411 struct policy_handle *domain_handle)
5413 struct samr_RidToSid r;
5416 struct dom_sid *calc_sid, *out_sid;
5417 int rids[] = { 0, 42, 512, 10200 };
5420 for (i=0;i<ARRAY_SIZE(rids);i++) {
5421 torture_comment(tctx, "Testing RidToSid\n");
5423 calc_sid = dom_sid_dup(tctx, domain_sid);
5424 r.in.domain_handle = domain_handle;
5426 r.out.sid = &out_sid;
5428 status = dcerpc_samr_RidToSid(p, tctx, &r);
5429 if (!NT_STATUS_IS_OK(status)) {
5430 printf("RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
5433 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
5435 if (!dom_sid_equal(calc_sid, out_sid)) {
5436 printf("RidToSid for %d failed - got %s, expected %s\n", rids[i],
5437 dom_sid_string(tctx, out_sid),
5438 dom_sid_string(tctx, calc_sid));
5447 static bool test_GetBootKeyInformation(struct dcerpc_pipe *p, struct torture_context *tctx,
5448 struct policy_handle *domain_handle)
5450 struct samr_GetBootKeyInformation r;
5453 uint32_t unknown = 0;
5455 torture_comment(tctx, "Testing GetBootKeyInformation\n");
5457 r.in.domain_handle = domain_handle;
5458 r.out.unknown = &unknown;
5460 status = dcerpc_samr_GetBootKeyInformation(p, tctx, &r);
5461 if (!NT_STATUS_IS_OK(status)) {
5462 /* w2k3 seems to fail this sometimes and pass it sometimes */
5463 torture_comment(tctx, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
5469 static bool test_AddGroupMember(struct dcerpc_pipe *p, struct torture_context *tctx,
5470 struct policy_handle *domain_handle,
5471 struct policy_handle *group_handle)
5474 struct samr_AddGroupMember r;
5475 struct samr_DeleteGroupMember d;
5476 struct samr_QueryGroupMember q;
5477 struct samr_RidTypeArray *rids = NULL;
5478 struct samr_SetMemberAttributesOfGroup s;
5481 status = test_LookupName(p, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
5482 torture_assert_ntstatus_ok(tctx, status, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME);
5484 r.in.group_handle = group_handle;
5486 r.in.flags = 0; /* ??? */
5488 torture_comment(tctx, "Testing AddGroupMember and DeleteGroupMember\n");
5490 d.in.group_handle = group_handle;
5493 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
5494 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_NOT_IN_GROUP, status, "DeleteGroupMember");
5496 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5497 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
5499 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5500 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_IN_GROUP, status, "AddGroupMember");
5502 if (torture_setting_bool(tctx, "samba4", false)) {
5503 torture_comment(tctx, "skipping SetMemberAttributesOfGroup test against Samba4\n");
5505 /* this one is quite strange. I am using random inputs in the
5506 hope of triggering an error that might give us a clue */
5508 s.in.group_handle = group_handle;
5509 s.in.unknown1 = random();
5510 s.in.unknown2 = random();
5512 status = dcerpc_samr_SetMemberAttributesOfGroup(p, tctx, &s);
5513 torture_assert_ntstatus_ok(tctx, status, "SetMemberAttributesOfGroup");
5516 q.in.group_handle = group_handle;
5519 status = dcerpc_samr_QueryGroupMember(p, tctx, &q);
5520 torture_assert_ntstatus_ok(tctx, status, "QueryGroupMember");
5522 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
5523 torture_assert_ntstatus_ok(tctx, status, "DeleteGroupMember");
5525 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5526 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
5532 static bool test_CreateDomainGroup(struct dcerpc_pipe *p,
5533 struct torture_context *tctx,
5534 struct policy_handle *domain_handle,
5535 struct policy_handle *group_handle,
5536 struct dom_sid *domain_sid)
5539 struct samr_CreateDomainGroup r;
5541 struct lsa_String name;
5544 init_lsa_String(&name, TEST_GROUPNAME);
5546 r.in.domain_handle = domain_handle;
5548 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5549 r.out.group_handle = group_handle;
5552 printf("Testing CreateDomainGroup(%s)\n", r.in.name->string);
5554 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
5556 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5557 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5558 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.name->string);
5561 printf("Server should have refused create of '%s', got %s instead\n", r.in.name->string,
5567 if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS)) {
5568 if (!test_DeleteGroup_byname(p, tctx, domain_handle, r.in.name->string)) {
5569 printf("CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
5573 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
5575 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
5576 if (!test_DeleteUser_byname(p, tctx, domain_handle, r.in.name->string)) {
5578 printf("CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
5582 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
5584 torture_assert_ntstatus_ok(tctx, status, "CreateDomainGroup");
5586 if (!test_AddGroupMember(p, tctx, domain_handle, group_handle)) {
5587 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
5591 if (!test_SetGroupInfo(p, tctx, group_handle)) {
5600 its not totally clear what this does. It seems to accept any sid you like.
5602 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p,
5603 struct torture_context *tctx,
5604 struct policy_handle *domain_handle)
5607 struct samr_RemoveMemberFromForeignDomain r;
5609 r.in.domain_handle = domain_handle;
5610 r.in.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-12-34-56-78");
5612 status = dcerpc_samr_RemoveMemberFromForeignDomain(p, tctx, &r);
5613 torture_assert_ntstatus_ok(tctx, status, "RemoveMemberFromForeignDomain");
5620 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
5621 struct policy_handle *handle);
5623 static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
5624 struct policy_handle *handle, struct dom_sid *sid,
5625 enum torture_samr_choice which_ops,
5626 struct cli_credentials *machine_credentials)
5629 struct samr_OpenDomain r;
5630 struct policy_handle domain_handle;
5631 struct policy_handle alias_handle;
5632 struct policy_handle user_handle;
5633 struct policy_handle group_handle;
5636 ZERO_STRUCT(alias_handle);
5637 ZERO_STRUCT(user_handle);
5638 ZERO_STRUCT(group_handle);
5639 ZERO_STRUCT(domain_handle);
5641 torture_comment(tctx, "Testing OpenDomain of %s\n", dom_sid_string(tctx, sid));
5643 r.in.connect_handle = handle;
5644 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5646 r.out.domain_handle = &domain_handle;
5648 status = dcerpc_samr_OpenDomain(p, tctx, &r);
5649 torture_assert_ntstatus_ok(tctx, status, "OpenDomain");
5651 /* run the domain tests with the main handle closed - this tests
5652 the servers reference counting */
5653 ret &= test_samr_handle_Close(p, tctx, handle);
5655 switch (which_ops) {
5656 case TORTURE_SAMR_USER_ATTRIBUTES:
5657 case TORTURE_SAMR_PASSWORDS:
5658 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops, NULL);
5659 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops, NULL);
5660 /* This test needs 'complex' users to validate */
5661 ret &= test_QueryDisplayInfo(p, tctx, &domain_handle);
5663 printf("Testing PASSWORDS or ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
5666 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
5667 if (!torture_setting_bool(tctx, "samba3", false)) {
5668 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops, machine_credentials);
5670 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops, machine_credentials);
5672 printf("Testing PASSWORDS PWDLASTSET on domain %s failed!\n", dom_sid_string(tctx, sid));
5675 case TORTURE_SAMR_OTHER:
5676 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops, NULL);
5678 printf("Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid));
5680 ret &= test_QuerySecurity(p, tctx, &domain_handle);
5681 ret &= test_RemoveMemberFromForeignDomain(p, tctx, &domain_handle);
5682 ret &= test_CreateAlias(p, tctx, &domain_handle, &alias_handle, sid);
5683 ret &= test_CreateDomainGroup(p, tctx, &domain_handle, &group_handle, sid);
5684 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
5685 ret &= test_QueryDomainInfo2(p, tctx, &domain_handle);
5686 ret &= test_EnumDomainUsers(p, tctx, &domain_handle);
5687 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
5688 ret &= test_EnumDomainGroups(p, tctx, &domain_handle);
5689 ret &= test_EnumDomainAliases(p, tctx, &domain_handle);
5690 ret &= test_QueryDisplayInfo2(p, tctx, &domain_handle);
5691 ret &= test_QueryDisplayInfo3(p, tctx, &domain_handle);
5692 ret &= test_QueryDisplayInfo_continue(p, tctx, &domain_handle);
5694 if (torture_setting_bool(tctx, "samba4", false)) {
5695 torture_comment(tctx, "skipping GetDisplayEnumerationIndex test against Samba4\n");
5697 ret &= test_GetDisplayEnumerationIndex(p, tctx, &domain_handle);
5698 ret &= test_GetDisplayEnumerationIndex2(p, tctx, &domain_handle);
5700 ret &= test_GroupList(p, tctx, &domain_handle);
5701 ret &= test_TestPrivateFunctionsDomain(p, tctx, &domain_handle);
5702 ret &= test_RidToSid(p, tctx, sid, &domain_handle);
5703 ret &= test_GetBootKeyInformation(p, tctx, &domain_handle);
5705 torture_comment(tctx, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx, sid));
5710 if (!policy_handle_empty(&user_handle) &&
5711 !test_DeleteUser(p, tctx, &user_handle)) {
5715 if (!policy_handle_empty(&alias_handle) &&
5716 !test_DeleteAlias(p, tctx, &alias_handle)) {
5720 if (!policy_handle_empty(&group_handle) &&
5721 !test_DeleteDomainGroup(p, tctx, &group_handle)) {
5725 ret &= test_samr_handle_Close(p, tctx, &domain_handle);
5727 /* reconnect the main handle */
5728 ret &= test_Connect(p, tctx, handle);
5731 printf("Testing domain %s failed!\n", dom_sid_string(tctx, sid));
5737 static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
5738 struct policy_handle *handle, const char *domain,
5739 enum torture_samr_choice which_ops,
5740 struct cli_credentials *machine_credentials)
5743 struct samr_LookupDomain r;
5744 struct dom_sid2 *sid = NULL;
5745 struct lsa_String n1;
5746 struct lsa_String n2;
5749 torture_comment(tctx, "Testing LookupDomain(%s)\n", domain);
5751 /* check for correct error codes */
5752 r.in.connect_handle = handle;
5753 r.in.domain_name = &n2;
5757 status = dcerpc_samr_LookupDomain(p, tctx, &r);
5758 torture_assert_ntstatus_equal(tctx, NT_STATUS_INVALID_PARAMETER, status, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
5760 init_lsa_String(&n2, "xxNODOMAINxx");
5762 status = dcerpc_samr_LookupDomain(p, tctx, &r);
5763 torture_assert_ntstatus_equal(tctx, NT_STATUS_NO_SUCH_DOMAIN, status, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
5765 r.in.connect_handle = handle;
5767 init_lsa_String(&n1, domain);
5768 r.in.domain_name = &n1;
5770 status = dcerpc_samr_LookupDomain(p, tctx, &r);
5771 torture_assert_ntstatus_ok(tctx, status, "LookupDomain");
5773 if (!test_GetDomPwInfo(p, tctx, &n1)) {
5777 if (!test_OpenDomain(p, tctx, handle, *r.out.sid, which_ops,
5778 machine_credentials)) {
5786 static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
5787 struct policy_handle *handle, enum torture_samr_choice which_ops,
5788 struct cli_credentials *machine_credentials)
5791 struct samr_EnumDomains r;
5792 uint32_t resume_handle = 0;
5793 uint32_t num_entries = 0;
5794 struct samr_SamArray *sam = NULL;
5798 r.in.connect_handle = handle;
5799 r.in.resume_handle = &resume_handle;
5800 r.in.buf_size = (uint32_t)-1;
5801 r.out.resume_handle = &resume_handle;
5802 r.out.num_entries = &num_entries;
5805 status = dcerpc_samr_EnumDomains(p, tctx, &r);
5806 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
5812 for (i=0;i<sam->count;i++) {
5813 if (!test_LookupDomain(p, tctx, handle,
5814 sam->entries[i].name.string, which_ops,
5815 machine_credentials)) {
5820 status = dcerpc_samr_EnumDomains(p, tctx, &r);
5821 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
5827 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
5828 struct policy_handle *handle)
5831 struct samr_Connect r;
5832 struct samr_Connect2 r2;
5833 struct samr_Connect3 r3;
5834 struct samr_Connect4 r4;
5835 struct samr_Connect5 r5;
5836 union samr_ConnectInfo info;
5837 struct policy_handle h;
5838 uint32_t level_out = 0;
5839 bool ret = true, got_handle = false;
5841 torture_comment(tctx, "testing samr_Connect\n");
5843 r.in.system_name = 0;
5844 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5845 r.out.connect_handle = &h;
5847 status = dcerpc_samr_Connect(p, tctx, &r);
5848 if (!NT_STATUS_IS_OK(status)) {
5849 torture_comment(tctx, "Connect failed - %s\n", nt_errstr(status));
5856 torture_comment(tctx, "testing samr_Connect2\n");
5858 r2.in.system_name = NULL;
5859 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5860 r2.out.connect_handle = &h;
5862 status = dcerpc_samr_Connect2(p, tctx, &r2);
5863 if (!NT_STATUS_IS_OK(status)) {
5864 torture_comment(tctx, "Connect2 failed - %s\n", nt_errstr(status));
5868 test_samr_handle_Close(p, tctx, handle);
5874 torture_comment(tctx, "testing samr_Connect3\n");
5876 r3.in.system_name = NULL;
5878 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5879 r3.out.connect_handle = &h;
5881 status = dcerpc_samr_Connect3(p, tctx, &r3);
5882 if (!NT_STATUS_IS_OK(status)) {
5883 printf("Connect3 failed - %s\n", nt_errstr(status));
5887 test_samr_handle_Close(p, tctx, handle);
5893 torture_comment(tctx, "testing samr_Connect4\n");
5895 r4.in.system_name = "";
5896 r4.in.client_version = 0;
5897 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5898 r4.out.connect_handle = &h;
5900 status = dcerpc_samr_Connect4(p, tctx, &r4);
5901 if (!NT_STATUS_IS_OK(status)) {
5902 printf("Connect4 failed - %s\n", nt_errstr(status));
5906 test_samr_handle_Close(p, tctx, handle);
5912 torture_comment(tctx, "testing samr_Connect5\n");
5914 info.info1.client_version = 0;
5915 info.info1.unknown2 = 0;
5917 r5.in.system_name = "";
5918 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5920 r5.out.level_out = &level_out;
5921 r5.in.info_in = &info;
5922 r5.out.info_out = &info;
5923 r5.out.connect_handle = &h;
5925 status = dcerpc_samr_Connect5(p, tctx, &r5);
5926 if (!NT_STATUS_IS_OK(status)) {
5927 printf("Connect5 failed - %s\n", nt_errstr(status));
5931 test_samr_handle_Close(p, tctx, handle);
5941 bool torture_rpc_samr(struct torture_context *torture)
5944 struct dcerpc_pipe *p;
5946 struct policy_handle handle;
5948 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
5949 if (!NT_STATUS_IS_OK(status)) {
5953 ret &= test_Connect(p, torture, &handle);
5955 ret &= test_QuerySecurity(p, torture, &handle);
5957 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_OTHER, NULL);
5959 ret &= test_SetDsrmPassword(p, torture, &handle);
5961 ret &= test_Shutdown(p, torture, &handle);
5963 ret &= test_samr_handle_Close(p, torture, &handle);
5969 bool torture_rpc_samr_users(struct torture_context *torture)
5972 struct dcerpc_pipe *p;
5974 struct policy_handle handle;
5976 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
5977 if (!NT_STATUS_IS_OK(status)) {
5981 ret &= test_Connect(p, torture, &handle);
5983 ret &= test_QuerySecurity(p, torture, &handle);
5985 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_USER_ATTRIBUTES, NULL);
5987 ret &= test_SetDsrmPassword(p, torture, &handle);
5989 ret &= test_Shutdown(p, torture, &handle);
5991 ret &= test_samr_handle_Close(p, torture, &handle);
5997 bool torture_rpc_samr_passwords(struct torture_context *torture)
6000 struct dcerpc_pipe *p;
6002 struct policy_handle handle;
6004 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6005 if (!NT_STATUS_IS_OK(status)) {
6009 ret &= test_Connect(p, torture, &handle);
6011 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_PASSWORDS, NULL);
6013 ret &= test_samr_handle_Close(p, torture, &handle);
6018 static bool torture_rpc_samr_pwdlastset(struct torture_context *torture,
6019 struct dcerpc_pipe *p2,
6020 struct cli_credentials *machine_credentials)
6023 struct dcerpc_pipe *p;
6025 struct policy_handle handle;
6027 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6028 if (!NT_STATUS_IS_OK(status)) {
6032 ret &= test_Connect(p, torture, &handle);
6034 ret &= test_EnumDomains(p, torture, &handle,
6035 TORTURE_SAMR_PASSWORDS_PWDLASTSET,
6036 machine_credentials);
6038 ret &= test_samr_handle_Close(p, torture, &handle);
6043 struct torture_suite *torture_rpc_samr_passwords_pwdlastset(TALLOC_CTX *mem_ctx)
6045 struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-PASSWORDS-PWDLASTSET");
6046 struct torture_rpc_tcase *tcase;
6048 tcase = torture_suite_add_machine_rpc_iface_tcase(suite, "samr",
6050 TEST_ACCOUNT_NAME_PWD);
6052 torture_rpc_tcase_add_test_creds(tcase, "pwdLastSet",
6053 torture_rpc_samr_pwdlastset);