2 Unix SMB/CIFS implementation.
3 test suite for samr rpc operations
5 Copyright (C) Andrew Tridgell 2003
6 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "torture/torture.h"
24 #include "system/time.h"
25 #include "librpc/gen_ndr/lsa.h"
26 #include "librpc/gen_ndr/ndr_netlogon.h"
27 #include "librpc/gen_ndr/ndr_netlogon_c.h"
28 #include "librpc/gen_ndr/ndr_samr_c.h"
29 #include "../lib/crypto/crypto.h"
30 #include "libcli/auth/libcli_auth.h"
31 #include "libcli/security/security.h"
32 #include "torture/rpc/rpc.h"
33 #include "param/param.h"
37 #define TEST_ACCOUNT_NAME "samrtorturetest"
38 #define TEST_ACCOUNT_NAME_PWD "samrpwdlastset"
39 #define TEST_ALIASNAME "samrtorturetestalias"
40 #define TEST_GROUPNAME "samrtorturetestgroup"
41 #define TEST_MACHINENAME "samrtestmach$"
42 #define TEST_DOMAINNAME "samrtestdom$"
44 enum torture_samr_choice {
45 TORTURE_SAMR_PASSWORDS,
46 TORTURE_SAMR_PASSWORDS_PWDLASTSET,
47 TORTURE_SAMR_USER_ATTRIBUTES,
51 static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
52 struct policy_handle *handle);
54 static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
55 struct policy_handle *handle);
57 static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
58 struct policy_handle *handle);
60 static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
61 const char *acct_name,
62 struct policy_handle *domain_handle, char **password);
64 static void init_lsa_String(struct lsa_String *string, const char *s)
69 static void init_lsa_BinaryString(struct lsa_BinaryString *string, const char *s, uint32_t length)
71 string->length = length;
72 string->size = length;
73 string->array = (uint16_t *)discard_const(s);
76 bool test_samr_handle_Close(struct dcerpc_pipe *p, struct torture_context *tctx,
77 struct policy_handle *handle)
83 r.out.handle = handle;
85 status = dcerpc_samr_Close(p, tctx, &r);
86 torture_assert_ntstatus_ok(tctx, status, "Close");
91 static bool test_Shutdown(struct dcerpc_pipe *p, struct torture_context *tctx,
92 struct policy_handle *handle)
95 struct samr_Shutdown r;
97 if (!torture_setting_bool(tctx, "dangerous", false)) {
98 torture_skip(tctx, "samr_Shutdown disabled - enable dangerous tests to use\n");
102 r.in.connect_handle = handle;
104 torture_comment(tctx, "testing samr_Shutdown\n");
106 status = dcerpc_samr_Shutdown(p, tctx, &r);
107 torture_assert_ntstatus_ok(tctx, status, "samr_Shutdown");
112 static bool test_SetDsrmPassword(struct dcerpc_pipe *p, struct torture_context *tctx,
113 struct policy_handle *handle)
116 struct samr_SetDsrmPassword r;
117 struct lsa_String string;
118 struct samr_Password hash;
120 if (!torture_setting_bool(tctx, "dangerous", false)) {
121 torture_skip(tctx, "samr_SetDsrmPassword disabled - enable dangerous tests to use");
124 E_md4hash("TeSTDSRM123", hash.hash);
126 init_lsa_String(&string, "Administrator");
132 torture_comment(tctx, "testing samr_SetDsrmPassword\n");
134 status = dcerpc_samr_SetDsrmPassword(p, tctx, &r);
135 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_SUPPORTED, "samr_SetDsrmPassword");
141 static bool test_QuerySecurity(struct dcerpc_pipe *p,
142 struct torture_context *tctx,
143 struct policy_handle *handle)
146 struct samr_QuerySecurity r;
147 struct samr_SetSecurity s;
148 struct sec_desc_buf *sdbuf = NULL;
150 r.in.handle = handle;
152 r.out.sdbuf = &sdbuf;
154 status = dcerpc_samr_QuerySecurity(p, tctx, &r);
155 torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
157 torture_assert(tctx, sdbuf != NULL, "sdbuf is NULL");
159 s.in.handle = handle;
163 if (torture_setting_bool(tctx, "samba4", false)) {
164 torture_skip(tctx, "skipping SetSecurity test against Samba4\n");
167 status = dcerpc_samr_SetSecurity(p, tctx, &s);
168 torture_assert_ntstatus_ok(tctx, status, "SetSecurity");
170 status = dcerpc_samr_QuerySecurity(p, tctx, &r);
171 torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
177 static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
178 struct policy_handle *handle, uint32_t base_acct_flags,
179 const char *base_account_name)
182 struct samr_SetUserInfo s;
183 struct samr_SetUserInfo2 s2;
184 struct samr_QueryUserInfo q;
185 struct samr_QueryUserInfo q0;
186 union samr_UserInfo u;
187 union samr_UserInfo *info;
189 const char *test_account_name;
191 uint32_t user_extra_flags = 0;
192 if (base_acct_flags == ACB_NORMAL) {
193 /* When created, accounts are expired by default */
194 user_extra_flags = ACB_PW_EXPIRED;
197 s.in.user_handle = handle;
200 s2.in.user_handle = handle;
203 q.in.user_handle = handle;
207 #define TESTCALL(call, r) \
208 status = dcerpc_samr_ ##call(p, tctx, &r); \
209 if (!NT_STATUS_IS_OK(status)) { \
210 torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
211 r.in.level, nt_errstr(status), __location__); \
216 #define STRING_EQUAL(s1, s2, field) \
217 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
218 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
219 #field, s2, __location__); \
224 #define MEM_EQUAL(s1, s2, length, field) \
225 if ((s1 && !s2) || (s2 && !s1) || memcmp(s1, s2, length)) { \
226 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
227 #field, (const char *)s2, __location__); \
232 #define INT_EQUAL(i1, i2, field) \
234 torture_comment(tctx, "Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \
235 #field, (unsigned long long)i2, (unsigned long long)i1, __location__); \
240 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
241 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
243 TESTCALL(QueryUserInfo, q) \
245 s2.in.level = lvl1; \
248 ZERO_STRUCT(u.info21); \
249 u.info21.fields_present = fpval; \
251 init_lsa_String(&u.info ## lvl1.field1, value); \
252 TESTCALL(SetUserInfo, s) \
253 TESTCALL(SetUserInfo2, s2) \
254 init_lsa_String(&u.info ## lvl1.field1, ""); \
255 TESTCALL(QueryUserInfo, q); \
257 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
259 TESTCALL(QueryUserInfo, q) \
261 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
264 #define TEST_USERINFO_BINARYSTRING(lvl1, field1, lvl2, field2, value, fpval) do { \
265 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
267 TESTCALL(QueryUserInfo, q) \
269 s2.in.level = lvl1; \
272 ZERO_STRUCT(u.info21); \
273 u.info21.fields_present = fpval; \
275 init_lsa_BinaryString(&u.info ## lvl1.field1, value, strlen(value)); \
276 TESTCALL(SetUserInfo, s) \
277 TESTCALL(SetUserInfo2, s2) \
278 init_lsa_BinaryString(&u.info ## lvl1.field1, "", 1); \
279 TESTCALL(QueryUserInfo, q); \
281 MEM_EQUAL(u.info ## lvl1.field1.array, value, strlen(value), field1); \
283 TESTCALL(QueryUserInfo, q) \
285 MEM_EQUAL(u.info ## lvl2.field2.array, value, strlen(value), field2); \
288 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
289 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
291 TESTCALL(QueryUserInfo, q) \
293 s2.in.level = lvl1; \
296 uint8_t *bits = u.info21.logon_hours.bits; \
297 ZERO_STRUCT(u.info21); \
298 if (fpval == SAMR_FIELD_LOGON_HOURS) { \
299 u.info21.logon_hours.units_per_week = 168; \
300 u.info21.logon_hours.bits = bits; \
302 u.info21.fields_present = fpval; \
304 u.info ## lvl1.field1 = value; \
305 TESTCALL(SetUserInfo, s) \
306 TESTCALL(SetUserInfo2, s2) \
307 u.info ## lvl1.field1 = 0; \
308 TESTCALL(QueryUserInfo, q); \
310 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
312 TESTCALL(QueryUserInfo, q) \
314 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
317 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
318 TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
322 do { TESTCALL(QueryUserInfo, q0) } while (0);
324 /* Samba 3 cannot store comment fields atm. - gd */
325 if (!torture_setting_bool(tctx, "samba3", false)) {
326 TEST_USERINFO_STRING(2, comment, 1, comment, "xx2-1 comment", 0);
327 TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
328 TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment",
332 test_account_name = talloc_asprintf(tctx, "%sxx7-1", base_account_name);
333 TEST_USERINFO_STRING(7, account_name, 1, account_name, base_account_name, 0);
334 test_account_name = talloc_asprintf(tctx, "%sxx7-3", base_account_name);
335 TEST_USERINFO_STRING(7, account_name, 3, account_name, base_account_name, 0);
336 test_account_name = talloc_asprintf(tctx, "%sxx7-5", base_account_name);
337 TEST_USERINFO_STRING(7, account_name, 5, account_name, base_account_name, 0);
338 test_account_name = talloc_asprintf(tctx, "%sxx7-6", base_account_name);
339 TEST_USERINFO_STRING(7, account_name, 6, account_name, base_account_name, 0);
340 test_account_name = talloc_asprintf(tctx, "%sxx7-7", base_account_name);
341 TEST_USERINFO_STRING(7, account_name, 7, account_name, base_account_name, 0);
342 test_account_name = talloc_asprintf(tctx, "%sxx7-21", base_account_name);
343 TEST_USERINFO_STRING(7, account_name, 21, account_name, base_account_name, 0);
344 test_account_name = base_account_name;
345 TEST_USERINFO_STRING(21, account_name, 21, account_name, base_account_name,
346 SAMR_FIELD_ACCOUNT_NAME);
348 TEST_USERINFO_STRING(6, full_name, 1, full_name, "xx6-1 full_name", 0);
349 TEST_USERINFO_STRING(6, full_name, 3, full_name, "xx6-3 full_name", 0);
350 TEST_USERINFO_STRING(6, full_name, 5, full_name, "xx6-5 full_name", 0);
351 TEST_USERINFO_STRING(6, full_name, 6, full_name, "xx6-6 full_name", 0);
352 TEST_USERINFO_STRING(6, full_name, 8, full_name, "xx6-8 full_name", 0);
353 TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
354 TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
355 TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name",
356 SAMR_FIELD_FULL_NAME);
358 TEST_USERINFO_STRING(6, full_name, 1, full_name, "", 0);
359 TEST_USERINFO_STRING(6, full_name, 3, full_name, "", 0);
360 TEST_USERINFO_STRING(6, full_name, 5, full_name, "", 0);
361 TEST_USERINFO_STRING(6, full_name, 6, full_name, "", 0);
362 TEST_USERINFO_STRING(6, full_name, 8, full_name, "", 0);
363 TEST_USERINFO_STRING(6, full_name, 21, full_name, "", 0);
364 TEST_USERINFO_STRING(8, full_name, 21, full_name, "", 0);
365 TEST_USERINFO_STRING(21, full_name, 21, full_name, "",
366 SAMR_FIELD_FULL_NAME);
368 TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
369 TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
370 TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
371 TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script",
372 SAMR_FIELD_LOGON_SCRIPT);
374 TEST_USERINFO_STRING(12, profile_path, 3, profile_path, "xx12-3 profile_path", 0);
375 TEST_USERINFO_STRING(12, profile_path, 5, profile_path, "xx12-5 profile_path", 0);
376 TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
377 TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path",
378 SAMR_FIELD_PROFILE_PATH);
380 TEST_USERINFO_STRING(10, home_directory, 3, home_directory, "xx10-3 home_directory", 0);
381 TEST_USERINFO_STRING(10, home_directory, 5, home_directory, "xx10-5 home_directory", 0);
382 TEST_USERINFO_STRING(10, home_directory, 21, home_directory, "xx10-21 home_directory", 0);
383 TEST_USERINFO_STRING(21, home_directory, 21, home_directory, "xx21-21 home_directory",
384 SAMR_FIELD_HOME_DIRECTORY);
385 TEST_USERINFO_STRING(21, home_directory, 10, home_directory, "xx21-10 home_directory",
386 SAMR_FIELD_HOME_DIRECTORY);
388 TEST_USERINFO_STRING(10, home_drive, 3, home_drive, "xx10-3 home_drive", 0);
389 TEST_USERINFO_STRING(10, home_drive, 5, home_drive, "xx10-5 home_drive", 0);
390 TEST_USERINFO_STRING(10, home_drive, 21, home_drive, "xx10-21 home_drive", 0);
391 TEST_USERINFO_STRING(21, home_drive, 21, home_drive, "xx21-21 home_drive",
392 SAMR_FIELD_HOME_DRIVE);
393 TEST_USERINFO_STRING(21, home_drive, 10, home_drive, "xx21-10 home_drive",
394 SAMR_FIELD_HOME_DRIVE);
396 TEST_USERINFO_STRING(13, description, 1, description, "xx13-1 description", 0);
397 TEST_USERINFO_STRING(13, description, 5, description, "xx13-5 description", 0);
398 TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
399 TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description",
400 SAMR_FIELD_DESCRIPTION);
402 TEST_USERINFO_STRING(14, workstations, 3, workstations, "14workstation3", 0);
403 TEST_USERINFO_STRING(14, workstations, 5, workstations, "14workstation4", 0);
404 TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
405 TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21",
406 SAMR_FIELD_WORKSTATIONS);
407 TEST_USERINFO_STRING(21, workstations, 3, workstations, "21workstation3",
408 SAMR_FIELD_WORKSTATIONS);
409 TEST_USERINFO_STRING(21, workstations, 5, workstations, "21workstation5",
410 SAMR_FIELD_WORKSTATIONS);
411 TEST_USERINFO_STRING(21, workstations, 14, workstations, "21workstation14",
412 SAMR_FIELD_WORKSTATIONS);
414 TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
415 TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "xx21-21 parameters",
416 SAMR_FIELD_PARAMETERS);
417 TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "xx21-20 parameters",
418 SAMR_FIELD_PARAMETERS);
419 /* also empty user parameters are allowed */
420 TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "", 0);
421 TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "",
422 SAMR_FIELD_PARAMETERS);
423 TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "",
424 SAMR_FIELD_PARAMETERS);
426 /* Samba 3 cannot store country_code and copy_page atm. - gd */
427 if (!torture_setting_bool(tctx, "samba3", false)) {
428 TEST_USERINFO_INT(2, country_code, 2, country_code, __LINE__, 0);
429 TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
430 TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__,
431 SAMR_FIELD_COUNTRY_CODE);
432 TEST_USERINFO_INT(21, country_code, 2, country_code, __LINE__,
433 SAMR_FIELD_COUNTRY_CODE);
435 TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
436 TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__,
437 SAMR_FIELD_CODE_PAGE);
438 TEST_USERINFO_INT(21, code_page, 2, code_page, __LINE__,
439 SAMR_FIELD_CODE_PAGE);
442 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, __LINE__, 0);
443 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, __LINE__, 0);
444 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, __LINE__,
445 SAMR_FIELD_ACCT_EXPIRY);
446 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, __LINE__,
447 SAMR_FIELD_ACCT_EXPIRY);
448 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, __LINE__,
449 SAMR_FIELD_ACCT_EXPIRY);
451 TEST_USERINFO_INT(4, logon_hours.bits[3], 3, logon_hours.bits[3], 1, 0);
452 TEST_USERINFO_INT(4, logon_hours.bits[3], 5, logon_hours.bits[3], 2, 0);
453 TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
454 TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4,
455 SAMR_FIELD_LOGON_HOURS);
457 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
458 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
459 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
461 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
462 (base_acct_flags | ACB_DISABLED),
463 (base_acct_flags | ACB_DISABLED | user_extra_flags),
466 /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
467 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
468 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
469 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
471 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
472 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
473 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
477 /* The 'autolock' flag doesn't stick - check this */
478 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
479 (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK),
480 (base_acct_flags | ACB_DISABLED | user_extra_flags),
483 /* Removing the 'disabled' flag doesn't stick - check this */
484 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
486 (base_acct_flags | ACB_DISABLED | user_extra_flags),
489 /* The 'store plaintext' flag does stick */
490 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
491 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED),
492 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags),
494 /* The 'use DES' flag does stick */
495 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
496 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY),
497 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags),
499 /* The 'don't require kerberos pre-authentication flag does stick */
500 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
501 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH),
502 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags),
504 /* The 'no kerberos PAC required' flag sticks */
505 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
506 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD),
507 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags),
510 TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags,
511 (base_acct_flags | ACB_DISABLED),
512 (base_acct_flags | ACB_DISABLED | user_extra_flags),
513 SAMR_FIELD_ACCT_FLAGS);
516 /* these fail with win2003 - it appears you can't set the primary gid?
517 the set succeeds, but the gid isn't changed. Very weird! */
518 TEST_USERINFO_INT(9, primary_gid, 1, primary_gid, 513);
519 TEST_USERINFO_INT(9, primary_gid, 3, primary_gid, 513);
520 TEST_USERINFO_INT(9, primary_gid, 5, primary_gid, 513);
521 TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
528 generate a random password for password change tests
530 static char *samr_rand_pass_silent(TALLOC_CTX *mem_ctx, int min_len)
532 size_t len = MAX(8, min_len) + (random() % 6);
533 char *s = generate_random_str(mem_ctx, len);
537 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
539 char *s = samr_rand_pass_silent(mem_ctx, min_len);
540 printf("Generated password '%s'\n", s);
546 generate a random password for password change tests
548 static DATA_BLOB samr_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
551 DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
552 generate_random_buffer(password.data, password.length);
554 for (i=0; i < len; i++) {
555 if (((uint16_t *)password.data)[i] == 0) {
556 ((uint16_t *)password.data)[i] = 1;
564 generate a random password for password change tests (fixed length)
566 static char *samr_rand_pass_fixed_len(TALLOC_CTX *mem_ctx, int len)
568 char *s = generate_random_str(mem_ctx, len);
569 printf("Generated password '%s'\n", s);
573 static bool test_SetUserPass(struct dcerpc_pipe *p, struct torture_context *tctx,
574 struct policy_handle *handle, char **password)
577 struct samr_SetUserInfo s;
578 union samr_UserInfo u;
580 DATA_BLOB session_key;
582 struct samr_GetUserPwInfo pwp;
583 struct samr_PwInfo info;
584 int policy_min_pw_len = 0;
585 pwp.in.user_handle = handle;
586 pwp.out.info = &info;
588 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
589 if (NT_STATUS_IS_OK(status)) {
590 policy_min_pw_len = pwp.out.info->min_password_length;
592 newpass = samr_rand_pass(tctx, policy_min_pw_len);
594 s.in.user_handle = handle;
598 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
599 u.info24.password_expired = 0;
601 status = dcerpc_fetch_session_key(p, &session_key);
602 if (!NT_STATUS_IS_OK(status)) {
603 printf("SetUserInfo level %u - no session key - %s\n",
604 s.in.level, nt_errstr(status));
608 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
610 torture_comment(tctx, "Testing SetUserInfo level 24 (set password)\n");
612 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
613 if (!NT_STATUS_IS_OK(status)) {
614 printf("SetUserInfo level %u failed - %s\n",
615 s.in.level, nt_errstr(status));
625 static bool test_SetUserPass_23(struct dcerpc_pipe *p, struct torture_context *tctx,
626 struct policy_handle *handle, uint32_t fields_present,
630 struct samr_SetUserInfo s;
631 union samr_UserInfo u;
633 DATA_BLOB session_key;
635 struct samr_GetUserPwInfo pwp;
636 struct samr_PwInfo info;
637 int policy_min_pw_len = 0;
638 pwp.in.user_handle = handle;
639 pwp.out.info = &info;
641 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
642 if (NT_STATUS_IS_OK(status)) {
643 policy_min_pw_len = pwp.out.info->min_password_length;
645 newpass = samr_rand_pass(tctx, policy_min_pw_len);
647 s.in.user_handle = handle;
653 u.info23.info.fields_present = fields_present;
655 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
657 status = dcerpc_fetch_session_key(p, &session_key);
658 if (!NT_STATUS_IS_OK(status)) {
659 printf("SetUserInfo level %u - no session key - %s\n",
660 s.in.level, nt_errstr(status));
664 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
666 torture_comment(tctx, "Testing SetUserInfo level 23 (set password)\n");
668 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
669 if (!NT_STATUS_IS_OK(status)) {
670 printf("SetUserInfo level %u failed - %s\n",
671 s.in.level, nt_errstr(status));
677 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
679 status = dcerpc_fetch_session_key(p, &session_key);
680 if (!NT_STATUS_IS_OK(status)) {
681 printf("SetUserInfo level %u - no session key - %s\n",
682 s.in.level, nt_errstr(status));
686 /* This should break the key nicely */
687 session_key.length--;
688 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
690 torture_comment(tctx, "Testing SetUserInfo level 23 (set password) with wrong password\n");
692 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
693 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
694 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
695 s.in.level, nt_errstr(status));
703 static bool test_SetUserPassEx(struct dcerpc_pipe *p, struct torture_context *tctx,
704 struct policy_handle *handle, bool makeshort,
708 struct samr_SetUserInfo s;
709 union samr_UserInfo u;
711 DATA_BLOB session_key;
712 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
713 uint8_t confounder[16];
715 struct MD5Context ctx;
716 struct samr_GetUserPwInfo pwp;
717 struct samr_PwInfo info;
718 int policy_min_pw_len = 0;
719 pwp.in.user_handle = handle;
720 pwp.out.info = &info;
722 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
723 if (NT_STATUS_IS_OK(status)) {
724 policy_min_pw_len = pwp.out.info->min_password_length;
726 if (makeshort && policy_min_pw_len) {
727 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len - 1);
729 newpass = samr_rand_pass(tctx, policy_min_pw_len);
732 s.in.user_handle = handle;
736 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
737 u.info26.password_expired = 0;
739 status = dcerpc_fetch_session_key(p, &session_key);
740 if (!NT_STATUS_IS_OK(status)) {
741 printf("SetUserInfo level %u - no session key - %s\n",
742 s.in.level, nt_errstr(status));
746 generate_random_buffer((uint8_t *)confounder, 16);
749 MD5Update(&ctx, confounder, 16);
750 MD5Update(&ctx, session_key.data, session_key.length);
751 MD5Final(confounded_session_key.data, &ctx);
753 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
754 memcpy(&u.info26.password.data[516], confounder, 16);
756 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex)\n");
758 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
759 if (!NT_STATUS_IS_OK(status)) {
760 printf("SetUserInfo level %u failed - %s\n",
761 s.in.level, nt_errstr(status));
767 /* This should break the key nicely */
768 confounded_session_key.data[0]++;
770 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
771 memcpy(&u.info26.password.data[516], confounder, 16);
773 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
775 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
776 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
777 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
778 s.in.level, nt_errstr(status));
787 static bool test_SetUserPass_25(struct dcerpc_pipe *p, struct torture_context *tctx,
788 struct policy_handle *handle, uint32_t fields_present,
792 struct samr_SetUserInfo s;
793 union samr_UserInfo u;
795 DATA_BLOB session_key;
796 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
797 struct MD5Context ctx;
798 uint8_t confounder[16];
800 struct samr_GetUserPwInfo pwp;
801 struct samr_PwInfo info;
802 int policy_min_pw_len = 0;
803 pwp.in.user_handle = handle;
804 pwp.out.info = &info;
806 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
807 if (NT_STATUS_IS_OK(status)) {
808 policy_min_pw_len = pwp.out.info->min_password_length;
810 newpass = samr_rand_pass(tctx, policy_min_pw_len);
812 s.in.user_handle = handle;
818 u.info25.info.fields_present = fields_present;
820 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
822 status = dcerpc_fetch_session_key(p, &session_key);
823 if (!NT_STATUS_IS_OK(status)) {
824 printf("SetUserInfo level %u - no session key - %s\n",
825 s.in.level, nt_errstr(status));
829 generate_random_buffer((uint8_t *)confounder, 16);
832 MD5Update(&ctx, confounder, 16);
833 MD5Update(&ctx, session_key.data, session_key.length);
834 MD5Final(confounded_session_key.data, &ctx);
836 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
837 memcpy(&u.info25.password.data[516], confounder, 16);
839 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex)\n");
841 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
842 if (!NT_STATUS_IS_OK(status)) {
843 printf("SetUserInfo level %u failed - %s\n",
844 s.in.level, nt_errstr(status));
850 /* This should break the key nicely */
851 confounded_session_key.data[0]++;
853 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
854 memcpy(&u.info25.password.data[516], confounder, 16);
856 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
858 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
859 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
860 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
861 s.in.level, nt_errstr(status));
868 static bool test_SetUserPass_18(struct dcerpc_pipe *p, struct torture_context *tctx,
869 struct policy_handle *handle, char **password)
872 struct samr_SetUserInfo s;
873 union samr_UserInfo u;
875 DATA_BLOB session_key;
877 struct samr_GetUserPwInfo pwp;
878 struct samr_PwInfo info;
879 int policy_min_pw_len = 0;
880 uint8_t lm_hash[16], nt_hash[16];
882 pwp.in.user_handle = handle;
883 pwp.out.info = &info;
885 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
886 if (NT_STATUS_IS_OK(status)) {
887 policy_min_pw_len = pwp.out.info->min_password_length;
889 newpass = samr_rand_pass(tctx, policy_min_pw_len);
891 s.in.user_handle = handle;
897 u.info18.nt_pwd_active = true;
898 u.info18.lm_pwd_active = true;
900 E_md4hash(newpass, nt_hash);
901 E_deshash(newpass, lm_hash);
903 status = dcerpc_fetch_session_key(p, &session_key);
904 if (!NT_STATUS_IS_OK(status)) {
905 printf("SetUserInfo level %u - no session key - %s\n",
906 s.in.level, nt_errstr(status));
912 in = data_blob_const(nt_hash, 16);
913 out = data_blob_talloc_zero(tctx, 16);
914 sess_crypt_blob(&out, &in, &session_key, true);
915 memcpy(u.info18.nt_pwd.hash, out.data, out.length);
919 in = data_blob_const(lm_hash, 16);
920 out = data_blob_talloc_zero(tctx, 16);
921 sess_crypt_blob(&out, &in, &session_key, true);
922 memcpy(u.info18.lm_pwd.hash, out.data, out.length);
925 torture_comment(tctx, "Testing SetUserInfo level 18 (set password hash)\n");
927 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
928 if (!NT_STATUS_IS_OK(status)) {
929 printf("SetUserInfo level %u failed - %s\n",
930 s.in.level, nt_errstr(status));
939 static bool test_SetUserPass_21(struct dcerpc_pipe *p, struct torture_context *tctx,
940 struct policy_handle *handle, uint32_t fields_present,
944 struct samr_SetUserInfo s;
945 union samr_UserInfo u;
947 DATA_BLOB session_key;
949 struct samr_GetUserPwInfo pwp;
950 struct samr_PwInfo info;
951 int policy_min_pw_len = 0;
952 uint8_t lm_hash[16], nt_hash[16];
954 pwp.in.user_handle = handle;
955 pwp.out.info = &info;
957 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
958 if (NT_STATUS_IS_OK(status)) {
959 policy_min_pw_len = pwp.out.info->min_password_length;
961 newpass = samr_rand_pass(tctx, policy_min_pw_len);
963 s.in.user_handle = handle;
967 E_md4hash(newpass, nt_hash);
968 E_deshash(newpass, lm_hash);
972 u.info21.fields_present = fields_present;
974 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
975 u.info21.lm_owf_password.length = 16;
976 u.info21.lm_owf_password.size = 16;
977 u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
978 u.info21.lm_password_set = true;
981 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
982 u.info21.nt_owf_password.length = 16;
983 u.info21.nt_owf_password.size = 16;
984 u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
985 u.info21.nt_password_set = true;
988 status = dcerpc_fetch_session_key(p, &session_key);
989 if (!NT_STATUS_IS_OK(status)) {
990 printf("SetUserInfo level %u - no session key - %s\n",
991 s.in.level, nt_errstr(status));
995 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
997 in = data_blob_const(u.info21.lm_owf_password.array,
998 u.info21.lm_owf_password.length);
999 out = data_blob_talloc_zero(tctx, 16);
1000 sess_crypt_blob(&out, &in, &session_key, true);
1001 u.info21.lm_owf_password.array = (uint16_t *)out.data;
1004 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1006 in = data_blob_const(u.info21.nt_owf_password.array,
1007 u.info21.nt_owf_password.length);
1008 out = data_blob_talloc_zero(tctx, 16);
1009 sess_crypt_blob(&out, &in, &session_key, true);
1010 u.info21.nt_owf_password.array = (uint16_t *)out.data;
1013 torture_comment(tctx, "Testing SetUserInfo level 21 (set password hash)\n");
1015 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1016 if (!NT_STATUS_IS_OK(status)) {
1017 printf("SetUserInfo level %u failed - %s\n",
1018 s.in.level, nt_errstr(status));
1021 *password = newpass;
1024 /* try invalid length */
1025 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1027 u.info21.nt_owf_password.length++;
1029 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1031 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1032 printf("SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1033 s.in.level, nt_errstr(status));
1038 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1040 u.info21.lm_owf_password.length++;
1042 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1044 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1045 printf("SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1046 s.in.level, nt_errstr(status));
1054 static bool test_SetUserPass_level_ex(struct dcerpc_pipe *p,
1055 struct torture_context *tctx,
1056 struct policy_handle *handle,
1058 uint32_t fields_present,
1059 char **password, uint8_t password_expired,
1061 bool *matched_expected_error)
1064 NTSTATUS expected_error = NT_STATUS_OK;
1065 struct samr_SetUserInfo s;
1066 struct samr_SetUserInfo2 s2;
1067 union samr_UserInfo u;
1069 DATA_BLOB session_key;
1070 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
1071 struct MD5Context ctx;
1072 uint8_t confounder[16];
1074 struct samr_GetUserPwInfo pwp;
1075 struct samr_PwInfo info;
1076 int policy_min_pw_len = 0;
1077 const char *comment = NULL;
1078 uint8_t lm_hash[16], nt_hash[16];
1080 pwp.in.user_handle = handle;
1081 pwp.out.info = &info;
1083 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1084 if (NT_STATUS_IS_OK(status)) {
1085 policy_min_pw_len = pwp.out.info->min_password_length;
1087 newpass = samr_rand_pass_silent(tctx, policy_min_pw_len);
1090 s2.in.user_handle = handle;
1092 s2.in.level = level;
1094 s.in.user_handle = handle;
1099 if (fields_present & SAMR_FIELD_COMMENT) {
1100 comment = talloc_asprintf(tctx, "comment: %ld\n", time(NULL));
1107 E_md4hash(newpass, nt_hash);
1108 E_deshash(newpass, lm_hash);
1110 u.info18.nt_pwd_active = true;
1111 u.info18.lm_pwd_active = true;
1112 u.info18.password_expired = password_expired;
1114 memcpy(u.info18.lm_pwd.hash, lm_hash, 16);
1115 memcpy(u.info18.nt_pwd.hash, nt_hash, 16);
1119 E_md4hash(newpass, nt_hash);
1120 E_deshash(newpass, lm_hash);
1122 u.info21.fields_present = fields_present;
1123 u.info21.password_expired = password_expired;
1124 u.info21.comment.string = comment;
1126 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1127 u.info21.lm_owf_password.length = 16;
1128 u.info21.lm_owf_password.size = 16;
1129 u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
1130 u.info21.lm_password_set = true;
1133 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1134 u.info21.nt_owf_password.length = 16;
1135 u.info21.nt_owf_password.size = 16;
1136 u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
1137 u.info21.nt_password_set = true;
1142 u.info23.info.fields_present = fields_present;
1143 u.info23.info.password_expired = password_expired;
1144 u.info23.info.comment.string = comment;
1146 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
1150 u.info24.password_expired = password_expired;
1152 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
1156 u.info25.info.fields_present = fields_present;
1157 u.info25.info.password_expired = password_expired;
1158 u.info25.info.comment.string = comment;
1160 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
1164 u.info26.password_expired = password_expired;
1166 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
1171 status = dcerpc_fetch_session_key(p, &session_key);
1172 if (!NT_STATUS_IS_OK(status)) {
1173 printf("SetUserInfo level %u - no session key - %s\n",
1174 s.in.level, nt_errstr(status));
1178 generate_random_buffer((uint8_t *)confounder, 16);
1181 MD5Update(&ctx, confounder, 16);
1182 MD5Update(&ctx, session_key.data, session_key.length);
1183 MD5Final(confounded_session_key.data, &ctx);
1189 in = data_blob_const(u.info18.nt_pwd.hash, 16);
1190 out = data_blob_talloc_zero(tctx, 16);
1191 sess_crypt_blob(&out, &in, &session_key, true);
1192 memcpy(u.info18.nt_pwd.hash, out.data, out.length);
1196 in = data_blob_const(u.info18.lm_pwd.hash, 16);
1197 out = data_blob_talloc_zero(tctx, 16);
1198 sess_crypt_blob(&out, &in, &session_key, true);
1199 memcpy(u.info18.lm_pwd.hash, out.data, out.length);
1204 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1206 in = data_blob_const(u.info21.lm_owf_password.array,
1207 u.info21.lm_owf_password.length);
1208 out = data_blob_talloc_zero(tctx, 16);
1209 sess_crypt_blob(&out, &in, &session_key, true);
1210 u.info21.lm_owf_password.array = (uint16_t *)out.data;
1212 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1214 in = data_blob_const(u.info21.nt_owf_password.array,
1215 u.info21.nt_owf_password.length);
1216 out = data_blob_talloc_zero(tctx, 16);
1217 sess_crypt_blob(&out, &in, &session_key, true);
1218 u.info21.nt_owf_password.array = (uint16_t *)out.data;
1222 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
1225 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
1228 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
1229 memcpy(&u.info25.password.data[516], confounder, 16);
1232 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
1233 memcpy(&u.info26.password.data[516], confounder, 16);
1238 status = dcerpc_samr_SetUserInfo2(p, tctx, &s2);
1240 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1243 if (!NT_STATUS_IS_OK(status)) {
1244 if (fields_present == 0) {
1245 expected_error = NT_STATUS_INVALID_PARAMETER;
1247 if (fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
1248 expected_error = NT_STATUS_ACCESS_DENIED;
1252 if (!NT_STATUS_IS_OK(expected_error)) {
1254 torture_assert_ntstatus_equal(tctx,
1256 expected_error, "SetUserInfo2 failed");
1258 torture_assert_ntstatus_equal(tctx,
1260 expected_error, "SetUserInfo failed");
1262 *matched_expected_error = true;
1266 if (!NT_STATUS_IS_OK(status)) {
1267 printf("SetUserInfo%s level %u failed - %s\n",
1268 use_setinfo2 ? "2":"", level, nt_errstr(status));
1271 *password = newpass;
1277 static bool test_SetAliasInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1278 struct policy_handle *handle)
1281 struct samr_SetAliasInfo r;
1282 struct samr_QueryAliasInfo q;
1283 union samr_AliasInfo *info;
1284 uint16_t levels[] = {2, 3};
1288 /* Ignoring switch level 1, as that includes the number of members for the alias
1289 * and setting this to a wrong value might have negative consequences
1292 for (i=0;i<ARRAY_SIZE(levels);i++) {
1293 torture_comment(tctx, "Testing SetAliasInfo level %u\n", levels[i]);
1295 r.in.alias_handle = handle;
1296 r.in.level = levels[i];
1297 r.in.info = talloc(tctx, union samr_AliasInfo);
1298 switch (r.in.level) {
1299 case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
1300 case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
1301 "Test Description, should test I18N as well"); break;
1302 case ALIASINFOALL: printf("ALIASINFOALL ignored\n"); break;
1305 status = dcerpc_samr_SetAliasInfo(p, tctx, &r);
1306 if (!NT_STATUS_IS_OK(status)) {
1307 printf("SetAliasInfo level %u failed - %s\n",
1308 levels[i], nt_errstr(status));
1312 q.in.alias_handle = handle;
1313 q.in.level = levels[i];
1316 status = dcerpc_samr_QueryAliasInfo(p, tctx, &q);
1317 if (!NT_STATUS_IS_OK(status)) {
1318 printf("QueryAliasInfo level %u failed - %s\n",
1319 levels[i], nt_errstr(status));
1327 static bool test_GetGroupsForUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1328 struct policy_handle *user_handle)
1330 struct samr_GetGroupsForUser r;
1331 struct samr_RidWithAttributeArray *rids = NULL;
1334 torture_comment(tctx, "testing GetGroupsForUser\n");
1336 r.in.user_handle = user_handle;
1339 status = dcerpc_samr_GetGroupsForUser(p, tctx, &r);
1340 torture_assert_ntstatus_ok(tctx, status, "GetGroupsForUser");
1346 static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1347 struct lsa_String *domain_name)
1350 struct samr_GetDomPwInfo r;
1351 struct samr_PwInfo info;
1353 r.in.domain_name = domain_name;
1356 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1358 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1359 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1361 r.in.domain_name->string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1362 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1364 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1365 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1367 r.in.domain_name->string = "\\\\__NONAME__";
1368 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1370 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1371 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1373 r.in.domain_name->string = "\\\\Builtin";
1374 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1376 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1377 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1382 static bool test_GetUserPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1383 struct policy_handle *handle)
1386 struct samr_GetUserPwInfo r;
1387 struct samr_PwInfo info;
1389 torture_comment(tctx, "Testing GetUserPwInfo\n");
1391 r.in.user_handle = handle;
1394 status = dcerpc_samr_GetUserPwInfo(p, tctx, &r);
1395 torture_assert_ntstatus_ok(tctx, status, "GetUserPwInfo");
1400 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, struct torture_context *tctx,
1401 struct policy_handle *domain_handle, const char *name,
1405 struct samr_LookupNames n;
1406 struct lsa_String sname[2];
1407 struct samr_Ids rids, types;
1409 init_lsa_String(&sname[0], name);
1411 n.in.domain_handle = domain_handle;
1415 n.out.types = &types;
1416 status = dcerpc_samr_LookupNames(p, tctx, &n);
1417 if (NT_STATUS_IS_OK(status)) {
1418 *rid = n.out.rids->ids[0];
1423 init_lsa_String(&sname[1], "xxNONAMExx");
1425 status = dcerpc_samr_LookupNames(p, tctx, &n);
1426 if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
1427 printf("LookupNames[2] failed - %s\n", nt_errstr(status));
1428 if (NT_STATUS_IS_OK(status)) {
1429 return NT_STATUS_UNSUCCESSFUL;
1435 status = dcerpc_samr_LookupNames(p, tctx, &n);
1436 if (!NT_STATUS_IS_OK(status)) {
1437 printf("LookupNames[0] failed - %s\n", nt_errstr(status));
1441 init_lsa_String(&sname[0], "xxNONAMExx");
1443 status = dcerpc_samr_LookupNames(p, tctx, &n);
1444 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1445 printf("LookupNames[1 bad name] failed - %s\n", nt_errstr(status));
1446 if (NT_STATUS_IS_OK(status)) {
1447 return NT_STATUS_UNSUCCESSFUL;
1452 init_lsa_String(&sname[0], "xxNONAMExx");
1453 init_lsa_String(&sname[1], "xxNONAME2xx");
1455 status = dcerpc_samr_LookupNames(p, tctx, &n);
1456 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1457 printf("LookupNames[2 bad names] failed - %s\n", nt_errstr(status));
1458 if (NT_STATUS_IS_OK(status)) {
1459 return NT_STATUS_UNSUCCESSFUL;
1464 return NT_STATUS_OK;
1467 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1468 struct policy_handle *domain_handle,
1469 const char *name, struct policy_handle *user_handle)
1472 struct samr_OpenUser r;
1475 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
1476 if (!NT_STATUS_IS_OK(status)) {
1480 r.in.domain_handle = domain_handle;
1481 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1483 r.out.user_handle = user_handle;
1484 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
1485 if (!NT_STATUS_IS_OK(status)) {
1486 printf("OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(status));
1493 static bool test_ChangePasswordNT3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1494 struct policy_handle *handle)
1497 struct samr_ChangePasswordUser r;
1499 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1500 struct policy_handle user_handle;
1501 char *oldpass = "test";
1502 char *newpass = "test2";
1503 uint8_t old_nt_hash[16], new_nt_hash[16];
1504 uint8_t old_lm_hash[16], new_lm_hash[16];
1506 status = test_OpenUser_byname(p, mem_ctx, handle, "testuser", &user_handle);
1507 if (!NT_STATUS_IS_OK(status)) {
1511 printf("Testing ChangePasswordUser for user 'testuser'\n");
1513 printf("old password: %s\n", oldpass);
1514 printf("new password: %s\n", newpass);
1516 E_md4hash(oldpass, old_nt_hash);
1517 E_md4hash(newpass, new_nt_hash);
1518 E_deshash(oldpass, old_lm_hash);
1519 E_deshash(newpass, new_lm_hash);
1521 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1522 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1523 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1524 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1525 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1526 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1528 r.in.handle = &user_handle;
1529 r.in.lm_present = 1;
1530 r.in.old_lm_crypted = &hash1;
1531 r.in.new_lm_crypted = &hash2;
1532 r.in.nt_present = 1;
1533 r.in.old_nt_crypted = &hash3;
1534 r.in.new_nt_crypted = &hash4;
1535 r.in.cross1_present = 1;
1536 r.in.nt_cross = &hash5;
1537 r.in.cross2_present = 1;
1538 r.in.lm_cross = &hash6;
1540 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1541 if (!NT_STATUS_IS_OK(status)) {
1542 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1546 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1554 static bool test_ChangePasswordUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1555 const char *acct_name,
1556 struct policy_handle *handle, char **password)
1559 struct samr_ChangePasswordUser r;
1561 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1562 struct policy_handle user_handle;
1564 uint8_t old_nt_hash[16], new_nt_hash[16];
1565 uint8_t old_lm_hash[16], new_lm_hash[16];
1566 bool changed = true;
1569 struct samr_GetUserPwInfo pwp;
1570 struct samr_PwInfo info;
1571 int policy_min_pw_len = 0;
1573 status = test_OpenUser_byname(p, tctx, handle, acct_name, &user_handle);
1574 if (!NT_STATUS_IS_OK(status)) {
1577 pwp.in.user_handle = &user_handle;
1578 pwp.out.info = &info;
1580 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1581 if (NT_STATUS_IS_OK(status)) {
1582 policy_min_pw_len = pwp.out.info->min_password_length;
1584 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1586 torture_comment(tctx, "Testing ChangePasswordUser\n");
1588 torture_assert(tctx, *password != NULL,
1589 "Failing ChangePasswordUser as old password was NULL. Previous test failed?");
1591 oldpass = *password;
1593 E_md4hash(oldpass, old_nt_hash);
1594 E_md4hash(newpass, new_nt_hash);
1595 E_deshash(oldpass, old_lm_hash);
1596 E_deshash(newpass, new_lm_hash);
1598 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1599 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1600 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1601 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1602 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1603 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1605 r.in.user_handle = &user_handle;
1606 r.in.lm_present = 1;
1607 /* Break the LM hash */
1609 r.in.old_lm_crypted = &hash1;
1610 r.in.new_lm_crypted = &hash2;
1611 r.in.nt_present = 1;
1612 r.in.old_nt_crypted = &hash3;
1613 r.in.new_nt_crypted = &hash4;
1614 r.in.cross1_present = 1;
1615 r.in.nt_cross = &hash5;
1616 r.in.cross2_present = 1;
1617 r.in.lm_cross = &hash6;
1619 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1620 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1621 "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash");
1623 /* Unbreak the LM hash */
1626 r.in.user_handle = &user_handle;
1627 r.in.lm_present = 1;
1628 r.in.old_lm_crypted = &hash1;
1629 r.in.new_lm_crypted = &hash2;
1630 /* Break the NT hash */
1632 r.in.nt_present = 1;
1633 r.in.old_nt_crypted = &hash3;
1634 r.in.new_nt_crypted = &hash4;
1635 r.in.cross1_present = 1;
1636 r.in.nt_cross = &hash5;
1637 r.in.cross2_present = 1;
1638 r.in.lm_cross = &hash6;
1640 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1641 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1642 "expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash");
1644 /* Unbreak the NT hash */
1647 r.in.user_handle = &user_handle;
1648 r.in.lm_present = 1;
1649 r.in.old_lm_crypted = &hash1;
1650 r.in.new_lm_crypted = &hash2;
1651 r.in.nt_present = 1;
1652 r.in.old_nt_crypted = &hash3;
1653 r.in.new_nt_crypted = &hash4;
1654 r.in.cross1_present = 1;
1655 r.in.nt_cross = &hash5;
1656 r.in.cross2_present = 1;
1657 /* Break the LM cross */
1659 r.in.lm_cross = &hash6;
1661 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1662 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1663 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status));
1667 /* Unbreak the LM cross */
1670 r.in.user_handle = &user_handle;
1671 r.in.lm_present = 1;
1672 r.in.old_lm_crypted = &hash1;
1673 r.in.new_lm_crypted = &hash2;
1674 r.in.nt_present = 1;
1675 r.in.old_nt_crypted = &hash3;
1676 r.in.new_nt_crypted = &hash4;
1677 r.in.cross1_present = 1;
1678 /* Break the NT cross */
1680 r.in.nt_cross = &hash5;
1681 r.in.cross2_present = 1;
1682 r.in.lm_cross = &hash6;
1684 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1685 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1686 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status));
1690 /* Unbreak the NT cross */
1694 /* Reset the hashes to not broken values */
1695 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1696 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1697 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1698 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1699 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1700 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1702 r.in.user_handle = &user_handle;
1703 r.in.lm_present = 1;
1704 r.in.old_lm_crypted = &hash1;
1705 r.in.new_lm_crypted = &hash2;
1706 r.in.nt_present = 1;
1707 r.in.old_nt_crypted = &hash3;
1708 r.in.new_nt_crypted = &hash4;
1709 r.in.cross1_present = 1;
1710 r.in.nt_cross = &hash5;
1711 r.in.cross2_present = 0;
1712 r.in.lm_cross = NULL;
1714 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1715 if (NT_STATUS_IS_OK(status)) {
1717 *password = newpass;
1718 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1719 printf("ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(status));
1724 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1726 E_md4hash(oldpass, old_nt_hash);
1727 E_md4hash(newpass, new_nt_hash);
1728 E_deshash(oldpass, old_lm_hash);
1729 E_deshash(newpass, new_lm_hash);
1732 /* Reset the hashes to not broken values */
1733 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1734 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1735 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1736 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1737 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1738 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1740 r.in.user_handle = &user_handle;
1741 r.in.lm_present = 1;
1742 r.in.old_lm_crypted = &hash1;
1743 r.in.new_lm_crypted = &hash2;
1744 r.in.nt_present = 1;
1745 r.in.old_nt_crypted = &hash3;
1746 r.in.new_nt_crypted = &hash4;
1747 r.in.cross1_present = 0;
1748 r.in.nt_cross = NULL;
1749 r.in.cross2_present = 1;
1750 r.in.lm_cross = &hash6;
1752 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1753 if (NT_STATUS_IS_OK(status)) {
1755 *password = newpass;
1756 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1757 printf("ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status));
1762 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1764 E_md4hash(oldpass, old_nt_hash);
1765 E_md4hash(newpass, new_nt_hash);
1766 E_deshash(oldpass, old_lm_hash);
1767 E_deshash(newpass, new_lm_hash);
1770 /* Reset the hashes to not broken values */
1771 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1772 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1773 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1774 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1775 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1776 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1778 r.in.user_handle = &user_handle;
1779 r.in.lm_present = 1;
1780 r.in.old_lm_crypted = &hash1;
1781 r.in.new_lm_crypted = &hash2;
1782 r.in.nt_present = 1;
1783 r.in.old_nt_crypted = &hash3;
1784 r.in.new_nt_crypted = &hash4;
1785 r.in.cross1_present = 1;
1786 r.in.nt_cross = &hash5;
1787 r.in.cross2_present = 1;
1788 r.in.lm_cross = &hash6;
1790 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1791 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1792 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1793 } else if (!NT_STATUS_IS_OK(status)) {
1794 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1798 *password = newpass;
1801 r.in.user_handle = &user_handle;
1802 r.in.lm_present = 1;
1803 r.in.old_lm_crypted = &hash1;
1804 r.in.new_lm_crypted = &hash2;
1805 r.in.nt_present = 1;
1806 r.in.old_nt_crypted = &hash3;
1807 r.in.new_nt_crypted = &hash4;
1808 r.in.cross1_present = 1;
1809 r.in.nt_cross = &hash5;
1810 r.in.cross2_present = 1;
1811 r.in.lm_cross = &hash6;
1814 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1815 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1816 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1817 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1818 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status));
1824 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
1832 static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
1833 const char *acct_name,
1834 struct policy_handle *handle, char **password)
1837 struct samr_OemChangePasswordUser2 r;
1839 struct samr_Password lm_verifier;
1840 struct samr_CryptPassword lm_pass;
1841 struct lsa_AsciiString server, account, account_bad;
1844 uint8_t old_lm_hash[16], new_lm_hash[16];
1846 struct samr_GetDomPwInfo dom_pw_info;
1847 struct samr_PwInfo info;
1848 int policy_min_pw_len = 0;
1850 struct lsa_String domain_name;
1852 domain_name.string = "";
1853 dom_pw_info.in.domain_name = &domain_name;
1854 dom_pw_info.out.info = &info;
1856 torture_comment(tctx, "Testing OemChangePasswordUser2\n");
1858 torture_assert(tctx, *password != NULL,
1859 "Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?");
1861 oldpass = *password;
1863 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
1864 if (NT_STATUS_IS_OK(status)) {
1865 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
1868 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1870 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1871 account.string = acct_name;
1873 E_deshash(oldpass, old_lm_hash);
1874 E_deshash(newpass, new_lm_hash);
1876 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1877 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1878 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1880 r.in.server = &server;
1881 r.in.account = &account;
1882 r.in.password = &lm_pass;
1883 r.in.hash = &lm_verifier;
1885 /* Break the verification */
1886 lm_verifier.hash[0]++;
1888 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1890 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1891 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1892 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1897 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1898 /* Break the old password */
1900 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1901 /* unbreak it for the next operation */
1903 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1905 r.in.server = &server;
1906 r.in.account = &account;
1907 r.in.password = &lm_pass;
1908 r.in.hash = &lm_verifier;
1910 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1912 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1913 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1914 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1919 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1920 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1922 r.in.server = &server;
1923 r.in.account = &account;
1924 r.in.password = &lm_pass;
1927 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1929 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1930 && !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1931 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
1936 /* This shouldn't be a valid name */
1937 account_bad.string = TEST_ACCOUNT_NAME "XX";
1938 r.in.account = &account_bad;
1940 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1942 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1943 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
1948 /* This shouldn't be a valid name */
1949 account_bad.string = TEST_ACCOUNT_NAME "XX";
1950 r.in.account = &account_bad;
1951 r.in.password = &lm_pass;
1952 r.in.hash = &lm_verifier;
1954 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1956 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1957 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1962 /* This shouldn't be a valid name */
1963 account_bad.string = TEST_ACCOUNT_NAME "XX";
1964 r.in.account = &account_bad;
1965 r.in.password = NULL;
1966 r.in.hash = &lm_verifier;
1968 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1970 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1971 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
1976 E_deshash(oldpass, old_lm_hash);
1977 E_deshash(newpass, new_lm_hash);
1979 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1980 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1981 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1983 r.in.server = &server;
1984 r.in.account = &account;
1985 r.in.password = &lm_pass;
1986 r.in.hash = &lm_verifier;
1988 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1989 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1990 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1991 } else if (!NT_STATUS_IS_OK(status)) {
1992 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
1995 *password = newpass;
2002 static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
2003 const char *acct_name,
2005 char *newpass, bool allow_password_restriction)
2008 struct samr_ChangePasswordUser2 r;
2010 struct lsa_String server, account;
2011 struct samr_CryptPassword nt_pass, lm_pass;
2012 struct samr_Password nt_verifier, lm_verifier;
2014 uint8_t old_nt_hash[16], new_nt_hash[16];
2015 uint8_t old_lm_hash[16], new_lm_hash[16];
2017 struct samr_GetDomPwInfo dom_pw_info;
2018 struct samr_PwInfo info;
2020 struct lsa_String domain_name;
2022 domain_name.string = "";
2023 dom_pw_info.in.domain_name = &domain_name;
2024 dom_pw_info.out.info = &info;
2026 torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name);
2028 torture_assert(tctx, *password != NULL,
2029 "Failing ChangePasswordUser2 as old password was NULL. Previous test failed?");
2030 oldpass = *password;
2033 int policy_min_pw_len = 0;
2034 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
2035 if (NT_STATUS_IS_OK(status)) {
2036 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
2039 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2042 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2043 init_lsa_String(&account, acct_name);
2045 E_md4hash(oldpass, old_nt_hash);
2046 E_md4hash(newpass, new_nt_hash);
2048 E_deshash(oldpass, old_lm_hash);
2049 E_deshash(newpass, new_lm_hash);
2051 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
2052 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2053 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2055 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2056 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2057 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2059 r.in.server = &server;
2060 r.in.account = &account;
2061 r.in.nt_password = &nt_pass;
2062 r.in.nt_verifier = &nt_verifier;
2064 r.in.lm_password = &lm_pass;
2065 r.in.lm_verifier = &lm_verifier;
2067 status = dcerpc_samr_ChangePasswordUser2(p, tctx, &r);
2068 if (allow_password_restriction && NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2069 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
2070 } else if (!NT_STATUS_IS_OK(status)) {
2071 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
2074 *password = newpass;
2081 bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tctx,
2082 const char *account_string,
2083 int policy_min_pw_len,
2085 const char *newpass,
2086 NTTIME last_password_change,
2087 bool handle_reject_reason)
2090 struct samr_ChangePasswordUser3 r;
2092 struct lsa_String server, account, account_bad;
2093 struct samr_CryptPassword nt_pass, lm_pass;
2094 struct samr_Password nt_verifier, lm_verifier;
2096 uint8_t old_nt_hash[16], new_nt_hash[16];
2097 uint8_t old_lm_hash[16], new_lm_hash[16];
2099 struct samr_DomInfo1 *dominfo = NULL;
2100 struct samr_ChangeReject *reject = NULL;
2102 torture_comment(tctx, "Testing ChangePasswordUser3\n");
2104 if (newpass == NULL) {
2106 if (policy_min_pw_len == 0) {
2107 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2109 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len);
2111 } while (check_password_quality(newpass) == false);
2113 torture_comment(tctx, "Using password '%s'\n", newpass);
2116 torture_assert(tctx, *password != NULL,
2117 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2119 oldpass = *password;
2120 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2121 init_lsa_String(&account, account_string);
2123 E_md4hash(oldpass, old_nt_hash);
2124 E_md4hash(newpass, new_nt_hash);
2126 E_deshash(oldpass, old_lm_hash);
2127 E_deshash(newpass, new_lm_hash);
2129 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2130 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2131 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2133 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2134 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2135 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2137 /* Break the verification */
2138 nt_verifier.hash[0]++;
2140 r.in.server = &server;
2141 r.in.account = &account;
2142 r.in.nt_password = &nt_pass;
2143 r.in.nt_verifier = &nt_verifier;
2145 r.in.lm_password = &lm_pass;
2146 r.in.lm_verifier = &lm_verifier;
2147 r.in.password3 = NULL;
2148 r.out.dominfo = &dominfo;
2149 r.out.reject = &reject;
2151 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2152 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
2153 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
2154 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
2159 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2160 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2161 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2163 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2164 /* Break the NT hash */
2166 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2167 /* Unbreak it again */
2169 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2171 r.in.server = &server;
2172 r.in.account = &account;
2173 r.in.nt_password = &nt_pass;
2174 r.in.nt_verifier = &nt_verifier;
2176 r.in.lm_password = &lm_pass;
2177 r.in.lm_verifier = &lm_verifier;
2178 r.in.password3 = NULL;
2179 r.out.dominfo = &dominfo;
2180 r.out.reject = &reject;
2182 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2183 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
2184 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
2185 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
2190 /* This shouldn't be a valid name */
2191 init_lsa_String(&account_bad, talloc_asprintf(tctx, "%sXX", account_string));
2193 r.in.account = &account_bad;
2194 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2195 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
2196 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
2201 E_md4hash(oldpass, old_nt_hash);
2202 E_md4hash(newpass, new_nt_hash);
2204 E_deshash(oldpass, old_lm_hash);
2205 E_deshash(newpass, new_lm_hash);
2207 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2208 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2209 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2211 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2212 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2213 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2215 r.in.server = &server;
2216 r.in.account = &account;
2217 r.in.nt_password = &nt_pass;
2218 r.in.nt_verifier = &nt_verifier;
2220 r.in.lm_password = &lm_pass;
2221 r.in.lm_verifier = &lm_verifier;
2222 r.in.password3 = NULL;
2223 r.out.dominfo = &dominfo;
2224 r.out.reject = &reject;
2226 unix_to_nt_time(&t, time(NULL));
2228 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2230 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
2233 && handle_reject_reason
2234 && (!null_nttime(last_password_change) || !dominfo->min_password_age)) {
2235 if (dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
2237 if (reject && (reject->reason != SAMR_REJECT_OTHER)) {
2238 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2239 SAMR_REJECT_OTHER, reject->reason);
2244 /* We tested the order of precendence which is as follows:
2253 if ((dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
2254 (last_password_change + dominfo->min_password_age > t)) {
2256 if (reject->reason != SAMR_REJECT_OTHER) {
2257 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2258 SAMR_REJECT_OTHER, reject->reason);
2262 } else if ((dominfo->min_password_length > 0) &&
2263 (strlen(newpass) < dominfo->min_password_length)) {
2265 if (reject->reason != SAMR_REJECT_TOO_SHORT) {
2266 printf("expected SAMR_REJECT_TOO_SHORT (%d), got %d\n",
2267 SAMR_REJECT_TOO_SHORT, reject->reason);
2271 } else if ((dominfo->password_history_length > 0) &&
2272 strequal(oldpass, newpass)) {
2274 if (reject->reason != SAMR_REJECT_IN_HISTORY) {
2275 printf("expected SAMR_REJECT_IN_HISTORY (%d), got %d\n",
2276 SAMR_REJECT_IN_HISTORY, reject->reason);
2279 } else if (dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
2281 if (reject->reason != SAMR_REJECT_COMPLEXITY) {
2282 printf("expected SAMR_REJECT_COMPLEXITY (%d), got %d\n",
2283 SAMR_REJECT_COMPLEXITY, reject->reason);
2289 if (reject->reason == SAMR_REJECT_TOO_SHORT) {
2290 /* retry with adjusted size */
2291 return test_ChangePasswordUser3(p, tctx, account_string,
2292 dominfo->min_password_length,
2293 password, NULL, 0, false);
2297 } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2298 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2299 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2300 SAMR_REJECT_OTHER, reject->reason);
2303 /* Perhaps the server has a 'min password age' set? */
2306 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3");
2307 *password = talloc_strdup(tctx, newpass);
2313 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_context *tctx,
2314 const char *account_string,
2315 struct policy_handle *handle,
2319 struct samr_ChangePasswordUser3 r;
2320 struct samr_SetUserInfo s;
2321 union samr_UserInfo u;
2322 DATA_BLOB session_key;
2323 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
2324 uint8_t confounder[16];
2325 struct MD5Context ctx;
2328 struct lsa_String server, account;
2329 struct samr_CryptPassword nt_pass;
2330 struct samr_Password nt_verifier;
2331 DATA_BLOB new_random_pass;
2334 uint8_t old_nt_hash[16], new_nt_hash[16];
2336 struct samr_DomInfo1 *dominfo = NULL;
2337 struct samr_ChangeReject *reject = NULL;
2339 new_random_pass = samr_very_rand_pass(tctx, 128);
2341 torture_assert(tctx, *password != NULL,
2342 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2344 oldpass = *password;
2345 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2346 init_lsa_String(&account, account_string);
2348 s.in.user_handle = handle;
2354 u.info25.info.fields_present = SAMR_FIELD_NT_PASSWORD_PRESENT;
2356 set_pw_in_buffer(u.info25.password.data, &new_random_pass);
2358 status = dcerpc_fetch_session_key(p, &session_key);
2359 if (!NT_STATUS_IS_OK(status)) {
2360 printf("SetUserInfo level %u - no session key - %s\n",
2361 s.in.level, nt_errstr(status));
2365 generate_random_buffer((uint8_t *)confounder, 16);
2368 MD5Update(&ctx, confounder, 16);
2369 MD5Update(&ctx, session_key.data, session_key.length);
2370 MD5Final(confounded_session_key.data, &ctx);
2372 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
2373 memcpy(&u.info25.password.data[516], confounder, 16);
2375 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
2377 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
2378 if (!NT_STATUS_IS_OK(status)) {
2379 printf("SetUserInfo level %u failed - %s\n",
2380 s.in.level, nt_errstr(status));
2384 torture_comment(tctx, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
2386 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2388 new_random_pass = samr_very_rand_pass(tctx, 128);
2390 mdfour(new_nt_hash, new_random_pass.data, new_random_pass.length);
2392 set_pw_in_buffer(nt_pass.data, &new_random_pass);
2393 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2394 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2396 r.in.server = &server;
2397 r.in.account = &account;
2398 r.in.nt_password = &nt_pass;
2399 r.in.nt_verifier = &nt_verifier;
2401 r.in.lm_password = NULL;
2402 r.in.lm_verifier = NULL;
2403 r.in.password3 = NULL;
2404 r.out.dominfo = &dominfo;
2405 r.out.reject = &reject;
2407 unix_to_nt_time(&t, time(NULL));
2409 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2411 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2412 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2413 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2414 SAMR_REJECT_OTHER, reject->reason);
2417 /* Perhaps the server has a 'min password age' set? */
2419 } else if (!NT_STATUS_IS_OK(status)) {
2420 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
2424 newpass = samr_rand_pass(tctx, 128);
2426 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2428 E_md4hash(newpass, new_nt_hash);
2430 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2431 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2432 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2434 r.in.server = &server;
2435 r.in.account = &account;
2436 r.in.nt_password = &nt_pass;
2437 r.in.nt_verifier = &nt_verifier;
2439 r.in.lm_password = NULL;
2440 r.in.lm_verifier = NULL;
2441 r.in.password3 = NULL;
2442 r.out.dominfo = &dominfo;
2443 r.out.reject = &reject;
2445 unix_to_nt_time(&t, time(NULL));
2447 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2449 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2450 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2451 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2452 SAMR_REJECT_OTHER, reject->reason);
2455 /* Perhaps the server has a 'min password age' set? */
2458 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3 (on second random password)");
2459 *password = talloc_strdup(tctx, newpass);
2466 static bool test_GetMembersInAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2467 struct policy_handle *alias_handle)
2469 struct samr_GetMembersInAlias r;
2470 struct lsa_SidArray sids;
2473 torture_comment(tctx, "Testing GetMembersInAlias\n");
2475 r.in.alias_handle = alias_handle;
2478 status = dcerpc_samr_GetMembersInAlias(p, tctx, &r);
2479 torture_assert_ntstatus_ok(tctx, status, "GetMembersInAlias");
2484 static bool test_AddMemberToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2485 struct policy_handle *alias_handle,
2486 const struct dom_sid *domain_sid)
2488 struct samr_AddAliasMember r;
2489 struct samr_DeleteAliasMember d;
2491 struct dom_sid *sid;
2493 sid = dom_sid_add_rid(tctx, domain_sid, 512);
2495 torture_comment(tctx, "testing AddAliasMember\n");
2496 r.in.alias_handle = alias_handle;
2499 status = dcerpc_samr_AddAliasMember(p, tctx, &r);
2500 torture_assert_ntstatus_ok(tctx, status, "AddAliasMember");
2502 d.in.alias_handle = alias_handle;
2505 status = dcerpc_samr_DeleteAliasMember(p, tctx, &d);
2506 torture_assert_ntstatus_ok(tctx, status, "DelAliasMember");
2511 static bool test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2512 struct policy_handle *alias_handle)
2514 struct samr_AddMultipleMembersToAlias a;
2515 struct samr_RemoveMultipleMembersFromAlias r;
2517 struct lsa_SidArray sids;
2519 torture_comment(tctx, "testing AddMultipleMembersToAlias\n");
2520 a.in.alias_handle = alias_handle;
2524 sids.sids = talloc_array(tctx, struct lsa_SidPtr, 3);
2526 sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2527 sids.sids[1].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-2");
2528 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-3");
2530 status = dcerpc_samr_AddMultipleMembersToAlias(p, tctx, &a);
2531 torture_assert_ntstatus_ok(tctx, status, "AddMultipleMembersToAlias");
2534 torture_comment(tctx, "testing RemoveMultipleMembersFromAlias\n");
2535 r.in.alias_handle = alias_handle;
2538 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2539 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2541 /* strange! removing twice doesn't give any error */
2542 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2543 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2545 /* but removing an alias that isn't there does */
2546 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-4");
2548 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2549 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, "RemoveMultipleMembersFromAlias");
2554 static bool test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2555 struct policy_handle *user_handle)
2557 struct samr_TestPrivateFunctionsUser r;
2560 torture_comment(tctx, "Testing TestPrivateFunctionsUser\n");
2562 r.in.user_handle = user_handle;
2564 status = dcerpc_samr_TestPrivateFunctionsUser(p, tctx, &r);
2565 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsUser");
2570 static bool test_QueryUserInfo_pwdlastset(struct dcerpc_pipe *p,
2571 struct torture_context *tctx,
2572 struct policy_handle *handle,
2577 uint16_t levels[] = { /* 3, */ 5, 21 };
2579 NTTIME pwdlastset3 = 0;
2580 NTTIME pwdlastset5 = 0;
2581 NTTIME pwdlastset21 = 0;
2583 torture_comment(tctx, "Testing QueryUserInfo%s level 5 and 21 call ",
2584 use_info2 ? "2":"");
2586 for (i=0; i<ARRAY_SIZE(levels); i++) {
2588 struct samr_QueryUserInfo r;
2589 struct samr_QueryUserInfo2 r2;
2590 union samr_UserInfo *info;
2593 r2.in.user_handle = handle;
2594 r2.in.level = levels[i];
2595 r2.out.info = &info;
2596 status = dcerpc_samr_QueryUserInfo2(p, tctx, &r2);
2599 r.in.user_handle = handle;
2600 r.in.level = levels[i];
2602 status = dcerpc_samr_QueryUserInfo(p, tctx, &r);
2605 if (!NT_STATUS_IS_OK(status) &&
2606 !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
2607 printf("QueryUserInfo%s level %u failed - %s\n",
2608 use_info2 ? "2":"", levels[i], nt_errstr(status));
2612 switch (levels[i]) {
2614 pwdlastset3 = info->info3.last_password_change;
2617 pwdlastset5 = info->info5.last_password_change;
2620 pwdlastset21 = info->info21.last_password_change;
2626 /* torture_assert_int_equal(tctx, pwdlastset3, pwdlastset5,
2627 "pwdlastset mixup"); */
2628 torture_assert_int_equal(tctx, pwdlastset5, pwdlastset21,
2629 "pwdlastset mixup");
2631 *pwdlastset = pwdlastset21;
2633 torture_comment(tctx, "(pwdlastset: %lld)\n", *pwdlastset);
2638 static bool test_SamLogon_Creds(struct dcerpc_pipe *p, struct torture_context *tctx,
2639 struct cli_credentials *machine_credentials,
2640 struct cli_credentials *test_credentials,
2641 struct netlogon_creds_CredentialState *creds,
2642 NTSTATUS expected_result)
2645 struct netr_LogonSamLogon r;
2646 struct netr_Authenticator auth, auth2;
2647 union netr_LogonLevel logon;
2648 union netr_Validation validation;
2649 uint8_t authoritative;
2650 struct netr_NetworkInfo ninfo;
2651 DATA_BLOB names_blob, chal, lm_resp, nt_resp;
2652 int flags = CLI_CRED_NTLM_AUTH;
2654 if (lp_client_lanman_auth(tctx->lp_ctx)) {
2655 flags |= CLI_CRED_LANMAN_AUTH;
2658 if (lp_client_ntlmv2_auth(tctx->lp_ctx)) {
2659 flags |= CLI_CRED_NTLMv2_AUTH;
2662 cli_credentials_get_ntlm_username_domain(test_credentials, tctx,
2663 &ninfo.identity_info.account_name.string,
2664 &ninfo.identity_info.domain_name.string);
2666 generate_random_buffer(ninfo.challenge,
2667 sizeof(ninfo.challenge));
2668 chal = data_blob_const(ninfo.challenge,
2669 sizeof(ninfo.challenge));
2671 names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(machine_credentials),
2672 cli_credentials_get_domain(machine_credentials));
2674 status = cli_credentials_get_ntlm_response(test_credentials, tctx,
2680 torture_assert_ntstatus_ok(tctx, status, "cli_credentials_get_ntlm_response failed");
2682 ninfo.lm.data = lm_resp.data;
2683 ninfo.lm.length = lm_resp.length;
2685 ninfo.nt.data = nt_resp.data;
2686 ninfo.nt.length = nt_resp.length;
2688 ninfo.identity_info.parameter_control =
2689 MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT |
2690 MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;
2691 ninfo.identity_info.logon_id_low = 0;
2692 ninfo.identity_info.logon_id_high = 0;
2693 ninfo.identity_info.workstation.string = cli_credentials_get_workstation(machine_credentials);
2695 logon.network = &ninfo;
2697 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2698 r.in.computer_name = cli_credentials_get_workstation(machine_credentials);
2699 r.in.credential = &auth;
2700 r.in.return_authenticator = &auth2;
2701 r.in.logon_level = 2;
2702 r.in.logon = &logon;
2703 r.out.validation = &validation;
2704 r.out.authoritative = &authoritative;
2706 d_printf("Testing LogonSamLogon with name %s\n", ninfo.identity_info.account_name.string);
2709 netlogon_creds_client_authenticator(creds, &auth);
2711 r.in.validation_level = 2;
2713 status = dcerpc_netr_LogonSamLogon(p, tctx, &r);
2714 if (!NT_STATUS_IS_OK(status)) {
2715 torture_assert_ntstatus_equal(tctx, status, expected_result, "LogonSamLogon failed");
2718 torture_assert_ntstatus_ok(tctx, status, "LogonSamLogon failed");
2721 torture_assert(tctx, netlogon_creds_client_check(creds, &r.out.return_authenticator->cred),
2722 "Credential chaining failed");
2727 static bool test_SamLogon(struct torture_context *tctx,
2728 struct dcerpc_pipe *p,
2729 struct cli_credentials *machine_credentials,
2730 struct cli_credentials *test_credentials,
2731 NTSTATUS expected_result)
2733 struct netlogon_creds_CredentialState *creds;
2735 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
2739 return test_SamLogon_Creds(p, tctx, machine_credentials, test_credentials,
2740 creds, expected_result);
2743 static bool test_SamLogon_with_creds(struct torture_context *tctx,
2744 struct dcerpc_pipe *p,
2745 struct cli_credentials *machine_creds,
2746 const char *acct_name,
2748 NTSTATUS expected_samlogon_result)
2751 struct cli_credentials *test_credentials;
2753 test_credentials = cli_credentials_init(tctx);
2755 cli_credentials_set_workstation(test_credentials,
2756 TEST_ACCOUNT_NAME_PWD, CRED_SPECIFIED);
2757 cli_credentials_set_domain(test_credentials,
2758 lp_workgroup(tctx->lp_ctx), CRED_SPECIFIED);
2759 cli_credentials_set_username(test_credentials,
2760 acct_name, CRED_SPECIFIED);
2761 cli_credentials_set_password(test_credentials,
2762 password, CRED_SPECIFIED);
2763 cli_credentials_set_secure_channel_type(test_credentials, SEC_CHAN_BDC);
2765 printf("testing samlogon as %s@%s password: %s\n",
2766 acct_name, TEST_ACCOUNT_NAME_PWD, password);
2768 if (!test_SamLogon(tctx, p, machine_creds, test_credentials,
2769 expected_samlogon_result)) {
2770 torture_warning(tctx, "new password did not work\n");
2777 static bool test_SetPassword_level(struct dcerpc_pipe *p,
2778 struct dcerpc_pipe *np,
2779 struct torture_context *tctx,
2780 struct policy_handle *handle,
2782 uint32_t fields_present,
2783 uint8_t password_expired,
2784 bool *matched_expected_error,
2786 const char *acct_name,
2788 struct cli_credentials *machine_creds,
2789 bool use_queryinfo2,
2791 NTSTATUS expected_samlogon_result)
2793 const char *fields = NULL;
2800 fields = talloc_asprintf(tctx, "(fields_present: 0x%08x)",
2807 torture_comment(tctx, "Testing SetUserInfo%s level %d call "
2808 "(password_expired: %d) %s\n",
2809 use_setinfo2 ? "2":"", level, password_expired,
2810 fields ? fields : "");
2812 if (!test_SetUserPass_level_ex(p, tctx, handle, level,
2817 matched_expected_error)) {
2821 if (!test_QueryUserInfo_pwdlastset(p, tctx, handle,
2827 if (*matched_expected_error == true) {
2831 if (!test_SamLogon_with_creds(tctx, np,
2835 expected_samlogon_result)) {
2842 static bool test_SetPassword_pwdlastset(struct dcerpc_pipe *p,
2843 struct torture_context *tctx,
2844 uint32_t acct_flags,
2845 const char *acct_name,
2846 struct policy_handle *handle,
2848 struct cli_credentials *machine_credentials)
2850 int s = 0, q = 0, f = 0, l = 0, z = 0;
2853 bool set_levels[] = { false, true };
2854 bool query_levels[] = { false, true };
2855 uint32_t levels[] = { 18, 21, 23, 24, 25, 26 };
2856 uint32_t nonzeros[] = { 1, 24 };
2857 uint32_t fields_present[] = {
2859 SAMR_FIELD_EXPIRED_FLAG,
2860 SAMR_FIELD_LAST_PWD_CHANGE,
2861 SAMR_FIELD_EXPIRED_FLAG | SAMR_FIELD_LAST_PWD_CHANGE,
2863 SAMR_FIELD_NT_PASSWORD_PRESENT,
2864 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
2865 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
2866 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
2867 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
2868 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
2869 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE | SAMR_FIELD_EXPIRED_FLAG
2872 struct dcerpc_pipe *np = NULL;
2874 if (torture_setting_bool(tctx, "samba3", false)) {
2876 printf("Samba3 has second granularity, setting delay to: %d\n",
2880 status = torture_rpc_connection(tctx, &np, &ndr_table_netlogon);
2881 if (!NT_STATUS_IS_OK(status)) {
2885 /* set to 1 to enable testing for all possible opcode
2886 (SetUserInfo, SetUserInfo2, QueryUserInfo, QueryUserInfo2)
2889 #define TEST_SET_LEVELS 1
2890 #define TEST_QUERY_LEVELS 1
2892 for (l=0; l<ARRAY_SIZE(levels); l++) {
2893 for (z=0; z<ARRAY_SIZE(nonzeros); z++) {
2894 for (f=0; f<ARRAY_SIZE(fields_present); f++) {
2895 #ifdef TEST_SET_LEVELS
2896 for (s=0; s<ARRAY_SIZE(set_levels); s++) {
2898 #ifdef TEST_QUERY_LEVELS
2899 for (q=0; q<ARRAY_SIZE(query_levels); q++) {
2901 NTTIME pwdlastset_old = 0;
2902 NTTIME pwdlastset_new = 0;
2903 bool matched_expected_error = false;
2904 NTSTATUS expected_samlogon_result = NT_STATUS_ACCOUNT_DISABLED;
2906 torture_comment(tctx, "------------------------------\n"
2907 "Testing pwdLastSet attribute for flags: 0x%08x "
2908 "(s: %d (l: %d), q: %d)\n",
2909 acct_flags, s, levels[l], q);
2911 switch (levels[l]) {
2915 if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
2916 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT))) {
2917 expected_samlogon_result = NT_STATUS_WRONG_PASSWORD;
2925 /* set a password and force password change (pwdlastset 0) by
2926 * setting the password expired flag to a non-0 value */
2928 if (!test_SetPassword_level(p, np, tctx, handle,
2932 &matched_expected_error,
2936 machine_credentials,
2939 expected_samlogon_result)) {
2943 if (matched_expected_error == true) {
2944 /* skipping on expected failure */
2948 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
2949 * set without the SAMR_FIELD_EXPIRED_FLAG */
2951 switch (levels[l]) {
2955 if ((pwdlastset_new != 0) &&
2956 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
2957 torture_comment(tctx, "not considering a non-0 "
2958 "pwdLastSet as a an error as the "
2959 "SAMR_FIELD_EXPIRED_FLAG has not "
2964 if (pwdlastset_new != 0) {
2965 torture_warning(tctx, "pwdLastSet test failed: "
2966 "expected pwdLastSet 0 but got %lld\n",
2973 switch (levels[l]) {
2977 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
2978 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
2979 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
2980 (pwdlastset_old >= pwdlastset_new)) {
2981 torture_warning(tctx, "pwdlastset not increasing\n");
2986 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
2987 (pwdlastset_old >= pwdlastset_new)) {
2988 torture_warning(tctx, "pwdlastset not increasing\n");
2998 /* set a password, pwdlastset needs to get updated (increased
2999 * value), password_expired value used here is 0 */
3001 if (!test_SetPassword_level(p, np, tctx, handle,
3005 &matched_expected_error,
3009 machine_credentials,
3012 expected_samlogon_result)) {
3016 /* when a password has been changed, pwdlastset must not be 0 afterwards
3017 * and must be larger then the old value */
3019 switch (levels[l]) {
3024 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3025 * password has been changed, old and new pwdlastset
3026 * need to be the same value */
3028 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3029 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3030 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3032 torture_assert_int_equal(tctx, pwdlastset_old,
3033 pwdlastset_new, "pwdlastset must be equal");
3037 if (pwdlastset_old >= pwdlastset_new) {
3038 torture_warning(tctx, "pwdLastSet test failed: "
3039 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
3040 pwdlastset_old, pwdlastset_new);
3043 if (pwdlastset_new == 0) {
3044 torture_warning(tctx, "pwdLastSet test failed: "
3045 "expected non-0 pwdlastset, got: %lld\n",
3051 switch (levels[l]) {
3055 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3056 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3057 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3058 (pwdlastset_old >= pwdlastset_new)) {
3059 torture_warning(tctx, "pwdlastset not increasing\n");
3064 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3065 (pwdlastset_old >= pwdlastset_new)) {
3066 torture_warning(tctx, "pwdlastset not increasing\n");
3072 pwdlastset_old = pwdlastset_new;
3078 /* set a password, pwdlastset needs to get updated (increased
3079 * value), password_expired value used here is 0 */
3081 if (!test_SetPassword_level(p, np, tctx, handle,
3085 &matched_expected_error,
3089 machine_credentials,
3092 expected_samlogon_result)) {
3096 /* when a password has been changed, pwdlastset must not be 0 afterwards
3097 * and must be larger then the old value */
3099 switch (levels[l]) {
3104 /* if no password has been changed, old and new pwdlastset
3105 * need to be the same value */
3107 if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3108 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3110 torture_assert_int_equal(tctx, pwdlastset_old,
3111 pwdlastset_new, "pwdlastset must be equal");
3115 if (pwdlastset_old >= pwdlastset_new) {
3116 torture_warning(tctx, "pwdLastSet test failed: "
3117 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
3118 pwdlastset_old, pwdlastset_new);
3121 if (pwdlastset_new == 0) {
3122 torture_warning(tctx, "pwdLastSet test failed: "
3123 "expected non-0 pwdlastset, got: %lld\n",
3131 /* set a password and force password change (pwdlastset 0) by
3132 * setting the password expired flag to a non-0 value */
3134 if (!test_SetPassword_level(p, np, tctx, handle,
3138 &matched_expected_error,
3142 machine_credentials,
3145 expected_samlogon_result)) {
3149 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3150 * set without the SAMR_FIELD_EXPIRED_FLAG */
3152 switch (levels[l]) {
3156 if ((pwdlastset_new != 0) &&
3157 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
3158 torture_comment(tctx, "not considering a non-0 "
3159 "pwdLastSet as a an error as the "
3160 "SAMR_FIELD_EXPIRED_FLAG has not "
3165 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3166 * password has been changed, old and new pwdlastset
3167 * need to be the same value */
3169 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3170 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3171 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3173 torture_assert_int_equal(tctx, pwdlastset_old,
3174 pwdlastset_new, "pwdlastset must be equal");
3179 if (pwdlastset_old == pwdlastset_new) {
3180 torture_warning(tctx, "pwdLastSet test failed: "
3181 "expected last pwdlastset (%lld) != new pwdlastset (%lld)\n",
3182 pwdlastset_old, pwdlastset_new);
3186 if (pwdlastset_new != 0) {
3187 torture_warning(tctx, "pwdLastSet test failed: "
3188 "expected pwdLastSet 0, got %lld\n",
3195 switch (levels[l]) {
3199 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3200 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3201 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3202 (pwdlastset_old >= pwdlastset_new)) {
3203 torture_warning(tctx, "pwdlastset not increasing\n");
3208 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3209 (pwdlastset_old >= pwdlastset_new)) {
3210 torture_warning(tctx, "pwdlastset not increasing\n");
3216 /* if the level we are testing does not have a fields_present
3217 * field, skip all fields present tests by setting f to to
3219 switch (levels[l]) {
3223 f = ARRAY_SIZE(fields_present);
3227 #ifdef TEST_QUERY_LEVELS
3230 #ifdef TEST_SET_LEVELS
3233 } /* fields present */
3237 #undef TEST_SET_LEVELS
3238 #undef TEST_QUERY_LEVELS
3243 static bool test_user_ops(struct dcerpc_pipe *p,
3244 struct torture_context *tctx,
3245 struct policy_handle *user_handle,
3246 struct policy_handle *domain_handle,
3247 uint32_t base_acct_flags,
3248 const char *base_acct_name, enum torture_samr_choice which_ops,
3249 struct cli_credentials *machine_credentials)
3251 char *password = NULL;
3252 struct samr_QueryUserInfo q;
3253 union samr_UserInfo *info;
3259 const uint32_t password_fields[] = {
3260 SAMR_FIELD_NT_PASSWORD_PRESENT,
3261 SAMR_FIELD_LM_PASSWORD_PRESENT,
3262 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
3266 status = test_LookupName(p, tctx, domain_handle, base_acct_name, &rid);
3267 if (!NT_STATUS_IS_OK(status)) {
3271 switch (which_ops) {
3272 case TORTURE_SAMR_USER_ATTRIBUTES:
3273 if (!test_QuerySecurity(p, tctx, user_handle)) {
3277 if (!test_QueryUserInfo(p, tctx, user_handle)) {
3281 if (!test_QueryUserInfo2(p, tctx, user_handle)) {
3285 if (!test_SetUserInfo(p, tctx, user_handle, base_acct_flags,
3290 if (!test_GetUserPwInfo(p, tctx, user_handle)) {
3294 if (!test_TestPrivateFunctionsUser(p, tctx, user_handle)) {
3298 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
3302 case TORTURE_SAMR_PASSWORDS:
3303 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
3304 char simple_pass[9];
3305 char *v = generate_random_str(tctx, 1);
3307 ZERO_STRUCT(simple_pass);
3308 memset(simple_pass, *v, sizeof(simple_pass) - 1);
3310 printf("Testing machine account password policy rules\n");
3312 /* Workstation trust accounts don't seem to need to honour password quality policy */
3313 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
3317 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
3321 /* reset again, to allow another 'user' password change */
3322 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
3326 /* Try a 'short' password */
3327 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
3331 /* Try a compleatly random password */
3332 if (!test_ChangePasswordRandomBytes(p, tctx, base_acct_name, user_handle, &password)) {
3337 for (i = 0; password_fields[i]; i++) {
3338 if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
3342 /* check it was set right */
3343 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3348 for (i = 0; password_fields[i]; i++) {
3349 if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
3353 /* check it was set right */
3354 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3359 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
3363 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
3367 if (torture_setting_bool(tctx, "samba4", false)) {
3368 printf("skipping Set Password level 18 and 21 against Samba4\n");
3371 if (!test_SetUserPass_18(p, tctx, user_handle, &password)) {
3375 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3379 for (i = 0; password_fields[i]; i++) {
3381 if (password_fields[i] == SAMR_FIELD_LM_PASSWORD_PRESENT) {
3382 /* we need to skip as that would break
3383 * the ChangePasswordUser3 verify */
3387 if (!test_SetUserPass_21(p, tctx, user_handle, password_fields[i], &password)) {
3391 /* check it was set right */
3392 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3398 q.in.user_handle = user_handle;
3402 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
3403 if (!NT_STATUS_IS_OK(status)) {
3404 printf("QueryUserInfo level %u failed - %s\n",
3405 q.in.level, nt_errstr(status));
3408 uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
3409 if ((info->info5.acct_flags) != expected_flags) {
3410 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
3411 info->info5.acct_flags,
3414 if (!torture_setting_bool(tctx, "samba3", false)) {
3418 if (info->info5.rid != rid) {
3419 printf("QuerUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
3420 info->info5.rid, rid);
3427 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
3429 /* test last password change timestamp behaviour */
3430 if (!test_SetPassword_pwdlastset(p, tctx, base_acct_flags,
3432 user_handle, &password,
3433 machine_credentials)) {
3438 torture_comment(tctx, "pwdLastSet test succeeded\n");
3440 torture_warning(tctx, "pwdLastSet test failed\n");
3445 case TORTURE_SAMR_OTHER:
3446 /* We just need the account to exist */
3452 static bool test_alias_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
3453 struct policy_handle *alias_handle,
3454 const struct dom_sid *domain_sid)
3458 if (!test_QuerySecurity(p, tctx, alias_handle)) {
3462 if (!test_QueryAliasInfo(p, tctx, alias_handle)) {
3466 if (!test_SetAliasInfo(p, tctx, alias_handle)) {
3470 if (!test_AddMemberToAlias(p, tctx, alias_handle, domain_sid)) {
3474 if (torture_setting_bool(tctx, "samba4", false)) {
3475 printf("skipping MultipleMembers Alias tests against Samba4\n");
3479 if (!test_AddMultipleMembersToAlias(p, tctx, alias_handle)) {
3487 static bool test_DeleteUser(struct dcerpc_pipe *p, struct torture_context *tctx,
3488 struct policy_handle *user_handle)
3490 struct samr_DeleteUser d;
3492 torture_comment(tctx, "Testing DeleteUser\n");
3494 d.in.user_handle = user_handle;
3495 d.out.user_handle = user_handle;
3497 status = dcerpc_samr_DeleteUser(p, tctx, &d);
3498 torture_assert_ntstatus_ok(tctx, status, "DeleteUser");
3503 bool test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3504 struct policy_handle *handle, const char *name)
3507 struct samr_DeleteUser d;
3508 struct policy_handle user_handle;
3511 status = test_LookupName(p, mem_ctx, handle, name, &rid);
3512 if (!NT_STATUS_IS_OK(status)) {
3516 status = test_OpenUser_byname(p, mem_ctx, handle, name, &user_handle);
3517 if (!NT_STATUS_IS_OK(status)) {
3521 d.in.user_handle = &user_handle;
3522 d.out.user_handle = &user_handle;
3523 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
3524 if (!NT_STATUS_IS_OK(status)) {
3531 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
3536 static bool test_DeleteGroup_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3537 struct policy_handle *handle, const char *name)
3540 struct samr_OpenGroup r;
3541 struct samr_DeleteDomainGroup d;
3542 struct policy_handle group_handle;
3545 status = test_LookupName(p, mem_ctx, handle, name, &rid);
3546 if (!NT_STATUS_IS_OK(status)) {
3550 r.in.domain_handle = handle;
3551 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3553 r.out.group_handle = &group_handle;
3554 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
3555 if (!NT_STATUS_IS_OK(status)) {
3559 d.in.group_handle = &group_handle;
3560 d.out.group_handle = &group_handle;
3561 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
3562 if (!NT_STATUS_IS_OK(status)) {
3569 printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
3574 static bool test_DeleteAlias_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3575 struct policy_handle *domain_handle, const char *name)
3578 struct samr_OpenAlias r;
3579 struct samr_DeleteDomAlias d;
3580 struct policy_handle alias_handle;
3583 printf("testing DeleteAlias_byname\n");
3585 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
3586 if (!NT_STATUS_IS_OK(status)) {
3590 r.in.domain_handle = domain_handle;
3591 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3593 r.out.alias_handle = &alias_handle;
3594 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
3595 if (!NT_STATUS_IS_OK(status)) {
3599 d.in.alias_handle = &alias_handle;
3600 d.out.alias_handle = &alias_handle;
3601 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
3602 if (!NT_STATUS_IS_OK(status)) {
3609 printf("DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
3613 static bool test_DeleteAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3614 struct policy_handle *alias_handle)
3616 struct samr_DeleteDomAlias d;
3619 printf("Testing DeleteAlias\n");
3621 d.in.alias_handle = alias_handle;
3622 d.out.alias_handle = alias_handle;
3624 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
3625 if (!NT_STATUS_IS_OK(status)) {
3626 printf("DeleteAlias failed - %s\n", nt_errstr(status));
3633 static bool test_CreateAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
3634 struct policy_handle *domain_handle,
3635 struct policy_handle *alias_handle,
3636 const struct dom_sid *domain_sid)
3639 struct samr_CreateDomAlias r;
3640 struct lsa_String name;
3644 init_lsa_String(&name, TEST_ALIASNAME);
3645 r.in.domain_handle = domain_handle;
3646 r.in.alias_name = &name;
3647 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3648 r.out.alias_handle = alias_handle;
3651 printf("Testing CreateAlias (%s)\n", r.in.alias_name->string);
3653 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
3655 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
3656 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
3657 printf("Server correctly refused create of '%s'\n", r.in.alias_name->string);
3660 printf("Server should have refused create of '%s', got %s instead\n", r.in.alias_name->string,
3666 if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
3667 if (!test_DeleteAlias_byname(p, tctx, domain_handle, r.in.alias_name->string)) {
3670 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
3673 if (!NT_STATUS_IS_OK(status)) {
3674 printf("CreateAlias failed - %s\n", nt_errstr(status));
3678 if (!test_alias_ops(p, tctx, alias_handle, domain_sid)) {
3685 static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3686 const char *acct_name,
3687 struct policy_handle *domain_handle, char **password)
3695 if (!test_ChangePasswordUser(p, mem_ctx, acct_name, domain_handle, password)) {
3699 if (!test_ChangePasswordUser2(p, mem_ctx, acct_name, password, 0, true)) {
3703 if (!test_OemChangePasswordUser2(p, mem_ctx, acct_name, domain_handle, password)) {
3707 /* test what happens when setting the old password again */
3708 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, *password, 0, true)) {
3713 char simple_pass[9];
3714 char *v = generate_random_str(mem_ctx, 1);
3716 ZERO_STRUCT(simple_pass);
3717 memset(simple_pass, *v, sizeof(simple_pass) - 1);
3719 /* test what happens when picking a simple password */
3720 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, simple_pass, 0, true)) {
3725 /* set samr_SetDomainInfo level 1 with min_length 5 */
3727 struct samr_QueryDomainInfo r;
3728 union samr_DomainInfo *info = NULL;
3729 struct samr_SetDomainInfo s;
3730 uint16_t len_old, len;
3731 uint32_t pwd_prop_old;
3732 int64_t min_pwd_age_old;
3737 r.in.domain_handle = domain_handle;
3741 printf("testing samr_QueryDomainInfo level 1\n");
3742 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
3743 if (!NT_STATUS_IS_OK(status)) {
3747 s.in.domain_handle = domain_handle;
3751 /* remember the old min length, so we can reset it */
3752 len_old = s.in.info->info1.min_password_length;
3753 s.in.info->info1.min_password_length = len;
3754 pwd_prop_old = s.in.info->info1.password_properties;
3755 /* turn off password complexity checks for this test */
3756 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
3758 min_pwd_age_old = s.in.info->info1.min_password_age;
3759 s.in.info->info1.min_password_age = 0;
3761 printf("testing samr_SetDomainInfo level 1\n");
3762 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
3763 if (!NT_STATUS_IS_OK(status)) {
3767 printf("calling test_ChangePasswordUser3 with too short password\n");
3769 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, len - 1, password, NULL, 0, true)) {
3773 s.in.info->info1.min_password_length = len_old;
3774 s.in.info->info1.password_properties = pwd_prop_old;
3775 s.in.info->info1.min_password_age = min_pwd_age_old;
3777 printf("testing samr_SetDomainInfo level 1\n");
3778 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
3779 if (!NT_STATUS_IS_OK(status)) {
3787 struct samr_OpenUser r;
3788 struct samr_QueryUserInfo q;
3789 union samr_UserInfo *info;
3790 struct samr_LookupNames n;
3791 struct policy_handle user_handle;
3792 struct samr_Ids rids, types;
3794 n.in.domain_handle = domain_handle;
3796 n.in.names = talloc_array(mem_ctx, struct lsa_String, 1);
3797 n.in.names[0].string = acct_name;
3799 n.out.types = &types;
3801 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
3802 if (!NT_STATUS_IS_OK(status)) {
3803 printf("LookupNames failed - %s\n", nt_errstr(status));
3807 r.in.domain_handle = domain_handle;
3808 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3809 r.in.rid = n.out.rids->ids[0];
3810 r.out.user_handle = &user_handle;
3812 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3813 if (!NT_STATUS_IS_OK(status)) {
3814 printf("OpenUser(%u) failed - %s\n", n.out.rids->ids[0], nt_errstr(status));
3818 q.in.user_handle = &user_handle;
3822 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
3823 if (!NT_STATUS_IS_OK(status)) {
3824 printf("QueryUserInfo failed - %s\n", nt_errstr(status));
3828 printf("calling test_ChangePasswordUser3 with too early password change\n");
3830 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL,
3831 info->info5.last_password_change, true)) {
3836 /* we change passwords twice - this has the effect of verifying
3837 they were changed correctly for the final call */
3838 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, true)) {
3842 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, true)) {
3849 static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
3850 struct policy_handle *domain_handle,
3851 struct policy_handle *user_handle_out,
3852 struct dom_sid *domain_sid,
3853 enum torture_samr_choice which_ops,
3854 struct cli_credentials *machine_credentials)
3857 TALLOC_CTX *user_ctx;
3860 struct samr_CreateUser r;
3861 struct samr_QueryUserInfo q;
3862 union samr_UserInfo *info;
3863 struct samr_DeleteUser d;
3866 /* This call creates a 'normal' account - check that it really does */
3867 const uint32_t acct_flags = ACB_NORMAL;
3868 struct lsa_String name;
3871 struct policy_handle user_handle;
3872 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
3873 init_lsa_String(&name, TEST_ACCOUNT_NAME);
3875 r.in.domain_handle = domain_handle;
3876 r.in.account_name = &name;
3877 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3878 r.out.user_handle = &user_handle;
3881 printf("Testing CreateUser(%s)\n", r.in.account_name->string);
3883 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
3885 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
3886 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
3887 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
3890 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
3896 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
3897 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
3898 talloc_free(user_ctx);
3901 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
3903 if (!NT_STATUS_IS_OK(status)) {
3904 talloc_free(user_ctx);
3905 printf("CreateUser failed - %s\n", nt_errstr(status));
3908 q.in.user_handle = &user_handle;
3912 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
3913 if (!NT_STATUS_IS_OK(status)) {
3914 printf("QueryUserInfo level %u failed - %s\n",
3915 q.in.level, nt_errstr(status));
3918 if ((info->info16.acct_flags & acct_flags) != acct_flags) {
3919 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
3920 info->info16.acct_flags,
3926 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
3927 acct_flags, name.string, which_ops,
3928 machine_credentials)) {
3932 if (user_handle_out) {
3933 *user_handle_out = user_handle;
3935 printf("Testing DeleteUser (createuser test)\n");
3937 d.in.user_handle = &user_handle;
3938 d.out.user_handle = &user_handle;
3940 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
3941 if (!NT_STATUS_IS_OK(status)) {
3942 printf("DeleteUser failed - %s\n", nt_errstr(status));
3949 talloc_free(user_ctx);
3955 static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
3956 struct policy_handle *domain_handle,
3957 struct dom_sid *domain_sid,
3958 enum torture_samr_choice which_ops,
3959 struct cli_credentials *machine_credentials)
3962 struct samr_CreateUser2 r;
3963 struct samr_QueryUserInfo q;
3964 union samr_UserInfo *info;
3965 struct samr_DeleteUser d;
3966 struct policy_handle user_handle;
3968 struct lsa_String name;
3973 uint32_t acct_flags;
3974 const char *account_name;
3976 } account_types[] = {
3977 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
3978 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
3979 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
3980 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
3981 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
3982 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
3983 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
3984 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
3985 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
3986 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
3987 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
3988 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
3989 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
3990 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
3991 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
3994 for (i = 0; account_types[i].account_name; i++) {
3995 TALLOC_CTX *user_ctx;
3996 uint32_t acct_flags = account_types[i].acct_flags;
3997 uint32_t access_granted;
3998 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
3999 init_lsa_String(&name, account_types[i].account_name);
4001 r.in.domain_handle = domain_handle;
4002 r.in.account_name = &name;
4003 r.in.acct_flags = acct_flags;
4004 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4005 r.out.user_handle = &user_handle;
4006 r.out.access_granted = &access_granted;
4009 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
4011 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
4013 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
4014 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
4015 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
4018 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
4025 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
4026 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
4027 talloc_free(user_ctx);
4031 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
4034 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
4035 printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
4036 nt_errstr(status), nt_errstr(account_types[i].nt_status));
4040 if (NT_STATUS_IS_OK(status)) {
4041 q.in.user_handle = &user_handle;
4045 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
4046 if (!NT_STATUS_IS_OK(status)) {
4047 printf("QueryUserInfo level %u failed - %s\n",
4048 q.in.level, nt_errstr(status));
4051 uint32_t expected_flags = (acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
4052 if (acct_flags == ACB_NORMAL) {
4053 expected_flags |= ACB_PW_EXPIRED;
4055 if ((info->info5.acct_flags) != expected_flags) {
4056 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
4057 info->info5.acct_flags,
4061 switch (acct_flags) {
4063 if (info->info5.primary_gid != DOMAIN_RID_DCS) {
4064 printf("QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n",
4065 DOMAIN_RID_DCS, info->info5.primary_gid);
4070 if (info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
4071 printf("QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
4072 DOMAIN_RID_DOMAIN_MEMBERS, info->info5.primary_gid);
4077 if (info->info5.primary_gid != DOMAIN_RID_USERS) {
4078 printf("QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n",
4079 DOMAIN_RID_USERS, info->info5.primary_gid);
4086 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
4087 acct_flags, name.string, which_ops,
4088 machine_credentials)) {
4092 printf("Testing DeleteUser (createuser2 test)\n");
4094 d.in.user_handle = &user_handle;
4095 d.out.user_handle = &user_handle;
4097 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
4098 if (!NT_STATUS_IS_OK(status)) {
4099 printf("DeleteUser failed - %s\n", nt_errstr(status));
4103 talloc_free(user_ctx);
4109 static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4110 struct policy_handle *handle)
4113 struct samr_QueryAliasInfo r;
4114 union samr_AliasInfo *info;
4115 uint16_t levels[] = {1, 2, 3};
4119 for (i=0;i<ARRAY_SIZE(levels);i++) {
4120 printf("Testing QueryAliasInfo level %u\n", levels[i]);
4122 r.in.alias_handle = handle;
4123 r.in.level = levels[i];
4126 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
4127 if (!NT_STATUS_IS_OK(status)) {
4128 printf("QueryAliasInfo level %u failed - %s\n",
4129 levels[i], nt_errstr(status));
4137 static bool test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4138 struct policy_handle *handle)
4141 struct samr_QueryGroupInfo r;
4142 union samr_GroupInfo *info;
4143 uint16_t levels[] = {1, 2, 3, 4, 5};
4147 for (i=0;i<ARRAY_SIZE(levels);i++) {
4148 printf("Testing QueryGroupInfo level %u\n", levels[i]);
4150 r.in.group_handle = handle;
4151 r.in.level = levels[i];
4154 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
4155 if (!NT_STATUS_IS_OK(status)) {
4156 printf("QueryGroupInfo level %u failed - %s\n",
4157 levels[i], nt_errstr(status));
4165 static bool test_QueryGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4166 struct policy_handle *handle)
4169 struct samr_QueryGroupMember r;
4170 struct samr_RidTypeArray *rids = NULL;
4173 printf("Testing QueryGroupMember\n");
4175 r.in.group_handle = handle;
4178 status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &r);
4179 if (!NT_STATUS_IS_OK(status)) {
4180 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
4188 static bool test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4189 struct policy_handle *handle)
4192 struct samr_QueryGroupInfo r;
4193 union samr_GroupInfo *info;
4194 struct samr_SetGroupInfo s;
4195 uint16_t levels[] = {1, 2, 3, 4};
4196 uint16_t set_ok[] = {0, 1, 1, 1};
4200 for (i=0;i<ARRAY_SIZE(levels);i++) {
4201 printf("Testing QueryGroupInfo level %u\n", levels[i]);
4203 r.in.group_handle = handle;
4204 r.in.level = levels[i];
4207 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
4208 if (!NT_STATUS_IS_OK(status)) {
4209 printf("QueryGroupInfo level %u failed - %s\n",
4210 levels[i], nt_errstr(status));
4214 printf("Testing SetGroupInfo level %u\n", levels[i]);
4216 s.in.group_handle = handle;
4217 s.in.level = levels[i];
4218 s.in.info = *r.out.info;
4221 /* disabled this, as it changes the name only from the point of view of samr,
4222 but leaves the name from the point of view of w2k3 internals (and ldap). This means
4223 the name is still reserved, so creating the old name fails, but deleting by the old name
4225 if (s.in.level == 2) {
4226 init_lsa_String(&s.in.info->string, "NewName");
4230 if (s.in.level == 4) {
4231 init_lsa_String(&s.in.info->description, "test description");
4234 status = dcerpc_samr_SetGroupInfo(p, mem_ctx, &s);
4236 if (!NT_STATUS_IS_OK(status)) {
4237 printf("SetGroupInfo level %u failed - %s\n",
4238 r.in.level, nt_errstr(status));
4243 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
4244 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
4245 r.in.level, nt_errstr(status));
4255 static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4256 struct policy_handle *handle)
4259 struct samr_QueryUserInfo r;
4260 union samr_UserInfo *info;
4261 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
4262 11, 12, 13, 14, 16, 17, 20, 21};
4266 for (i=0;i<ARRAY_SIZE(levels);i++) {
4267 printf("Testing QueryUserInfo level %u\n", levels[i]);
4269 r.in.user_handle = handle;
4270 r.in.level = levels[i];
4273 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
4274 if (!NT_STATUS_IS_OK(status)) {
4275 printf("QueryUserInfo level %u failed - %s\n",
4276 levels[i], nt_errstr(status));
4284 static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4285 struct policy_handle *handle)
4288 struct samr_QueryUserInfo2 r;
4289 union samr_UserInfo *info;
4290 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
4291 11, 12, 13, 14, 16, 17, 20, 21};
4295 for (i=0;i<ARRAY_SIZE(levels);i++) {
4296 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
4298 r.in.user_handle = handle;
4299 r.in.level = levels[i];
4302 status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r);
4303 if (!NT_STATUS_IS_OK(status)) {
4304 printf("QueryUserInfo2 level %u failed - %s\n",
4305 levels[i], nt_errstr(status));
4313 static bool test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4314 struct policy_handle *handle, uint32_t rid)
4317 struct samr_OpenUser r;
4318 struct policy_handle user_handle;
4321 printf("Testing OpenUser(%u)\n", rid);
4323 r.in.domain_handle = handle;
4324 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4326 r.out.user_handle = &user_handle;
4328 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
4329 if (!NT_STATUS_IS_OK(status)) {
4330 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
4334 if (!test_QuerySecurity(p, mem_ctx, &user_handle)) {
4338 if (!test_QueryUserInfo(p, mem_ctx, &user_handle)) {
4342 if (!test_QueryUserInfo2(p, mem_ctx, &user_handle)) {
4346 if (!test_GetUserPwInfo(p, mem_ctx, &user_handle)) {
4350 if (!test_GetGroupsForUser(p,mem_ctx, &user_handle)) {
4354 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
4361 static bool test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4362 struct policy_handle *handle, uint32_t rid)
4365 struct samr_OpenGroup r;
4366 struct policy_handle group_handle;
4369 printf("Testing OpenGroup(%u)\n", rid);
4371 r.in.domain_handle = handle;
4372 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4374 r.out.group_handle = &group_handle;
4376 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
4377 if (!NT_STATUS_IS_OK(status)) {
4378 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
4382 if (!test_QuerySecurity(p, mem_ctx, &group_handle)) {
4386 if (!test_QueryGroupInfo(p, mem_ctx, &group_handle)) {
4390 if (!test_QueryGroupMember(p, mem_ctx, &group_handle)) {
4394 if (!test_samr_handle_Close(p, mem_ctx, &group_handle)) {
4401 static bool test_OpenAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
4402 struct policy_handle *handle, uint32_t rid)
4405 struct samr_OpenAlias r;
4406 struct policy_handle alias_handle;
4409 torture_comment(tctx, "Testing OpenAlias(%u)\n", rid);
4411 r.in.domain_handle = handle;
4412 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4414 r.out.alias_handle = &alias_handle;
4416 status = dcerpc_samr_OpenAlias(p, tctx, &r);
4417 if (!NT_STATUS_IS_OK(status)) {
4418 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
4422 if (!test_QuerySecurity(p, tctx, &alias_handle)) {
4426 if (!test_QueryAliasInfo(p, tctx, &alias_handle)) {
4430 if (!test_GetMembersInAlias(p, tctx, &alias_handle)) {
4434 if (!test_samr_handle_Close(p, tctx, &alias_handle)) {
4441 static bool check_mask(struct dcerpc_pipe *p, struct torture_context *tctx,
4442 struct policy_handle *handle, uint32_t rid,
4443 uint32_t acct_flag_mask)
4446 struct samr_OpenUser r;
4447 struct samr_QueryUserInfo q;
4448 union samr_UserInfo *info;
4449 struct policy_handle user_handle;
4452 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
4454 r.in.domain_handle = handle;
4455 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4457 r.out.user_handle = &user_handle;
4459 status = dcerpc_samr_OpenUser(p, tctx, &r);
4460 if (!NT_STATUS_IS_OK(status)) {
4461 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
4465 q.in.user_handle = &user_handle;
4469 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
4470 if (!NT_STATUS_IS_OK(status)) {
4471 printf("QueryUserInfo level 16 failed - %s\n",
4475 if ((acct_flag_mask & info->info16.acct_flags) == 0) {
4476 printf("Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
4477 acct_flag_mask, info->info16.acct_flags, rid);
4482 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
4489 static bool test_EnumDomainUsers(struct dcerpc_pipe *p, struct torture_context *tctx,
4490 struct policy_handle *handle)
4492 NTSTATUS status = STATUS_MORE_ENTRIES;
4493 struct samr_EnumDomainUsers r;
4494 uint32_t mask, resume_handle=0;
4497 struct samr_LookupNames n;
4498 struct samr_LookupRids lr ;
4499 struct lsa_Strings names;
4500 struct samr_Ids rids, types;
4501 struct samr_SamArray *sam = NULL;
4502 uint32_t num_entries = 0;
4504 uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
4505 ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
4506 ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
4509 printf("Testing EnumDomainUsers\n");
4511 for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
4512 r.in.domain_handle = handle;
4513 r.in.resume_handle = &resume_handle;
4514 r.in.acct_flags = mask = masks[mask_idx];
4515 r.in.max_size = (uint32_t)-1;
4516 r.out.resume_handle = &resume_handle;
4517 r.out.num_entries = &num_entries;
4520 status = dcerpc_samr_EnumDomainUsers(p, tctx, &r);
4521 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
4522 !NT_STATUS_IS_OK(status)) {
4523 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
4527 torture_assert(tctx, sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
4529 if (sam->count == 0) {
4533 for (i=0;i<sam->count;i++) {
4535 if (!check_mask(p, tctx, handle, sam->entries[i].idx, mask)) {
4538 } else if (!test_OpenUser(p, tctx, handle, sam->entries[i].idx)) {
4544 printf("Testing LookupNames\n");
4545 n.in.domain_handle = handle;
4546 n.in.num_names = sam->count;
4547 n.in.names = talloc_array(tctx, struct lsa_String, sam->count);
4549 n.out.types = &types;
4550 for (i=0;i<sam->count;i++) {
4551 n.in.names[i].string = sam->entries[i].name.string;
4553 status = dcerpc_samr_LookupNames(p, tctx, &n);
4554 if (!NT_STATUS_IS_OK(status)) {
4555 printf("LookupNames failed - %s\n", nt_errstr(status));
4560 printf("Testing LookupRids\n");
4561 lr.in.domain_handle = handle;
4562 lr.in.num_rids = sam->count;
4563 lr.in.rids = talloc_array(tctx, uint32_t, sam->count);
4564 lr.out.names = &names;
4565 lr.out.types = &types;
4566 for (i=0;i<sam->count;i++) {
4567 lr.in.rids[i] = sam->entries[i].idx;
4569 status = dcerpc_samr_LookupRids(p, tctx, &lr);
4570 torture_assert_ntstatus_ok(tctx, status, "LookupRids");
4576 try blasting the server with a bunch of sync requests
4578 static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, struct torture_context *tctx,
4579 struct policy_handle *handle)
4582 struct samr_EnumDomainUsers r;
4583 uint32_t resume_handle=0;
4585 #define ASYNC_COUNT 100
4586 struct rpc_request *req[ASYNC_COUNT];
4588 if (!torture_setting_bool(tctx, "dangerous", false)) {
4589 torture_skip(tctx, "samr async test disabled - enable dangerous tests to use\n");
4592 torture_comment(tctx, "Testing EnumDomainUsers_async\n");
4594 r.in.domain_handle = handle;
4595 r.in.resume_handle = &resume_handle;
4596 r.in.acct_flags = 0;
4597 r.in.max_size = (uint32_t)-1;
4598 r.out.resume_handle = &resume_handle;
4600 for (i=0;i<ASYNC_COUNT;i++) {
4601 req[i] = dcerpc_samr_EnumDomainUsers_send(p, tctx, &r);
4604 for (i=0;i<ASYNC_COUNT;i++) {
4605 status = dcerpc_ndr_request_recv(req[i]);
4606 if (!NT_STATUS_IS_OK(status)) {
4607 printf("EnumDomainUsers[%d] failed - %s\n",
4608 i, nt_errstr(status));
4613 torture_comment(tctx, "%d async requests OK\n", i);
4618 static bool test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4619 struct policy_handle *handle)
4622 struct samr_EnumDomainGroups r;
4623 uint32_t resume_handle=0;
4624 struct samr_SamArray *sam = NULL;
4625 uint32_t num_entries = 0;
4629 printf("Testing EnumDomainGroups\n");
4631 r.in.domain_handle = handle;
4632 r.in.resume_handle = &resume_handle;
4633 r.in.max_size = (uint32_t)-1;
4634 r.out.resume_handle = &resume_handle;
4635 r.out.num_entries = &num_entries;
4638 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
4639 if (!NT_STATUS_IS_OK(status)) {
4640 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
4648 for (i=0;i<sam->count;i++) {
4649 if (!test_OpenGroup(p, mem_ctx, handle, sam->entries[i].idx)) {
4657 static bool test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4658 struct policy_handle *handle)
4661 struct samr_EnumDomainAliases r;
4662 uint32_t resume_handle=0;
4663 struct samr_SamArray *sam = NULL;
4664 uint32_t num_entries = 0;
4668 printf("Testing EnumDomainAliases\n");
4670 r.in.domain_handle = handle;
4671 r.in.resume_handle = &resume_handle;
4672 r.in.max_size = (uint32_t)-1;
4674 r.out.num_entries = &num_entries;
4675 r.out.resume_handle = &resume_handle;
4677 status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
4678 if (!NT_STATUS_IS_OK(status)) {
4679 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
4687 for (i=0;i<sam->count;i++) {
4688 if (!test_OpenAlias(p, mem_ctx, handle, sam->entries[i].idx)) {
4696 static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4697 struct policy_handle *handle)
4700 struct samr_GetDisplayEnumerationIndex r;
4702 uint16_t levels[] = {1, 2, 3, 4, 5};
4703 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
4704 struct lsa_String name;
4708 for (i=0;i<ARRAY_SIZE(levels);i++) {
4709 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
4711 init_lsa_String(&name, TEST_ACCOUNT_NAME);
4713 r.in.domain_handle = handle;
4714 r.in.level = levels[i];
4718 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
4721 !NT_STATUS_IS_OK(status) &&
4722 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
4723 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
4724 levels[i], nt_errstr(status));
4728 init_lsa_String(&name, "zzzzzzzz");
4730 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
4732 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
4733 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
4734 levels[i], nt_errstr(status));
4742 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4743 struct policy_handle *handle)
4746 struct samr_GetDisplayEnumerationIndex2 r;
4748 uint16_t levels[] = {1, 2, 3, 4, 5};
4749 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
4750 struct lsa_String name;
4754 for (i=0;i<ARRAY_SIZE(levels);i++) {
4755 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
4757 init_lsa_String(&name, TEST_ACCOUNT_NAME);
4759 r.in.domain_handle = handle;
4760 r.in.level = levels[i];
4764 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
4766 !NT_STATUS_IS_OK(status) &&
4767 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
4768 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
4769 levels[i], nt_errstr(status));
4773 init_lsa_String(&name, "zzzzzzzz");
4775 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
4776 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
4777 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
4778 levels[i], nt_errstr(status));
4786 #define STRING_EQUAL_QUERY(s1, s2, user) \
4787 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
4788 /* odd, but valid */ \
4789 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
4790 printf("%s mismatch for %s: %s != %s (%s)\n", \
4791 #s1, user.string, s1.string, s2.string, __location__); \
4794 #define INT_EQUAL_QUERY(s1, s2, user) \
4796 printf("%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
4797 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
4801 static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4802 struct samr_QueryDisplayInfo *querydisplayinfo,
4803 bool *seen_testuser)
4805 struct samr_OpenUser r;
4806 struct samr_QueryUserInfo q;
4807 union samr_UserInfo *info;
4808 struct policy_handle user_handle;
4811 r.in.domain_handle = querydisplayinfo->in.domain_handle;
4812 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4813 for (i = 0; ; i++) {
4814 switch (querydisplayinfo->in.level) {
4816 if (i >= querydisplayinfo->out.info->info1.count) {
4819 r.in.rid = querydisplayinfo->out.info->info1.entries[i].rid;
4822 if (i >= querydisplayinfo->out.info->info2.count) {
4825 r.in.rid = querydisplayinfo->out.info->info2.entries[i].rid;
4831 /* Not interested in validating just the account name */
4835 r.out.user_handle = &user_handle;
4837 switch (querydisplayinfo->in.level) {
4840 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
4841 if (!NT_STATUS_IS_OK(status)) {
4842 printf("OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(status));
4847 q.in.user_handle = &user_handle;
4850 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
4851 if (!NT_STATUS_IS_OK(status)) {
4852 printf("QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(status));
4856 switch (querydisplayinfo->in.level) {
4858 if (seen_testuser && strcmp(info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
4859 *seen_testuser = true;
4861 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].full_name,
4862 info->info21.full_name, info->info21.account_name);
4863 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].account_name,
4864 info->info21.account_name, info->info21.account_name);
4865 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].description,
4866 info->info21.description, info->info21.account_name);
4867 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].rid,
4868 info->info21.rid, info->info21.account_name);
4869 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].acct_flags,
4870 info->info21.acct_flags, info->info21.account_name);
4874 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].account_name,
4875 info->info21.account_name, info->info21.account_name);
4876 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].description,
4877 info->info21.description, info->info21.account_name);
4878 INT_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].rid,
4879 info->info21.rid, info->info21.account_name);
4880 INT_EQUAL_QUERY((querydisplayinfo->out.info->info2.entries[i].acct_flags & ~ACB_NORMAL),
4881 info->info21.acct_flags, info->info21.account_name);
4883 if (!(querydisplayinfo->out.info->info2.entries[i].acct_flags & ACB_NORMAL)) {
4884 printf("Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
4885 info->info21.account_name.string);
4888 if (!(info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
4889 printf("Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
4890 info->info21.account_name.string,
4891 querydisplayinfo->out.info->info2.entries[i].acct_flags,
4892 info->info21.acct_flags);
4899 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
4906 static bool test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4907 struct policy_handle *handle)
4910 struct samr_QueryDisplayInfo r;
4911 struct samr_QueryDomainInfo dom_info;
4912 union samr_DomainInfo *info = NULL;
4914 uint16_t levels[] = {1, 2, 3, 4, 5};
4916 bool seen_testuser = false;
4917 uint32_t total_size;
4918 uint32_t returned_size;
4919 union samr_DispInfo disp_info;
4922 for (i=0;i<ARRAY_SIZE(levels);i++) {
4923 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
4926 status = STATUS_MORE_ENTRIES;
4927 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
4928 r.in.domain_handle = handle;
4929 r.in.level = levels[i];
4930 r.in.max_entries = 2;
4931 r.in.buf_size = (uint32_t)-1;
4932 r.out.total_size = &total_size;
4933 r.out.returned_size = &returned_size;
4934 r.out.info = &disp_info;
4936 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
4937 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(status)) {
4938 printf("QueryDisplayInfo level %u failed - %s\n",
4939 levels[i], nt_errstr(status));
4942 switch (r.in.level) {
4944 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, &seen_testuser)) {
4947 r.in.start_idx += r.out.info->info1.count;
4950 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, NULL)) {
4953 r.in.start_idx += r.out.info->info2.count;
4956 r.in.start_idx += r.out.info->info3.count;
4959 r.in.start_idx += r.out.info->info4.count;
4962 r.in.start_idx += r.out.info->info5.count;
4966 dom_info.in.domain_handle = handle;
4967 dom_info.in.level = 2;
4968 dom_info.out.info = &info;
4970 /* Check number of users returned is correct */
4971 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &dom_info);
4972 if (!NT_STATUS_IS_OK(status)) {
4973 printf("QueryDomainInfo level %u failed - %s\n",
4974 r.in.level, nt_errstr(status));
4978 switch (r.in.level) {
4981 if (info->general.num_users < r.in.start_idx) {
4982 printf("QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
4983 r.in.start_idx, info->general.num_groups,
4984 info->general.domain_name.string);
4987 if (!seen_testuser) {
4988 struct policy_handle user_handle;
4989 if (NT_STATUS_IS_OK(test_OpenUser_byname(p, mem_ctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
4990 printf("Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
4991 info->general.domain_name.string);
4993 test_samr_handle_Close(p, mem_ctx, &user_handle);
4999 if (info->general.num_groups != r.in.start_idx) {
5000 printf("QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
5001 r.in.start_idx, info->general.num_groups,
5002 info->general.domain_name.string);
5014 static bool test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
5015 struct policy_handle *handle)
5018 struct samr_QueryDisplayInfo2 r;
5020 uint16_t levels[] = {1, 2, 3, 4, 5};
5022 uint32_t total_size;
5023 uint32_t returned_size;
5024 union samr_DispInfo info;
5026 for (i=0;i<ARRAY_SIZE(levels);i++) {
5027 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
5029 r.in.domain_handle = handle;
5030 r.in.level = levels[i];
5032 r.in.max_entries = 1000;
5033 r.in.buf_size = (uint32_t)-1;
5034 r.out.total_size = &total_size;
5035 r.out.returned_size = &returned_size;
5038 status = dcerpc_samr_QueryDisplayInfo2(p, mem_ctx, &r);
5039 if (!NT_STATUS_IS_OK(status)) {
5040 printf("QueryDisplayInfo2 level %u failed - %s\n",
5041 levels[i], nt_errstr(status));
5049 static bool test_QueryDisplayInfo3(struct dcerpc_pipe *p, struct torture_context *tctx,
5050 struct policy_handle *handle)
5053 struct samr_QueryDisplayInfo3 r;
5055 uint16_t levels[] = {1, 2, 3, 4, 5};
5057 uint32_t total_size;
5058 uint32_t returned_size;
5059 union samr_DispInfo info;
5061 for (i=0;i<ARRAY_SIZE(levels);i++) {
5062 torture_comment(tctx, "Testing QueryDisplayInfo3 level %u\n", levels[i]);
5064 r.in.domain_handle = handle;
5065 r.in.level = levels[i];
5067 r.in.max_entries = 1000;
5068 r.in.buf_size = (uint32_t)-1;
5069 r.out.total_size = &total_size;
5070 r.out.returned_size = &returned_size;
5073 status = dcerpc_samr_QueryDisplayInfo3(p, tctx, &r);
5074 if (!NT_STATUS_IS_OK(status)) {
5075 printf("QueryDisplayInfo3 level %u failed - %s\n",
5076 levels[i], nt_errstr(status));
5085 static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
5086 struct policy_handle *handle)
5089 struct samr_QueryDisplayInfo r;
5091 uint32_t total_size;
5092 uint32_t returned_size;
5093 union samr_DispInfo info;
5095 printf("Testing QueryDisplayInfo continuation\n");
5097 r.in.domain_handle = handle;
5100 r.in.max_entries = 1;
5101 r.in.buf_size = (uint32_t)-1;
5102 r.out.total_size = &total_size;
5103 r.out.returned_size = &returned_size;
5107 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
5108 if (NT_STATUS_IS_OK(status) && *r.out.returned_size != 0) {
5109 if (r.out.info->info1.entries[0].idx != r.in.start_idx + 1) {
5110 printf("expected idx %d but got %d\n",
5112 r.out.info->info1.entries[0].idx);
5116 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
5117 !NT_STATUS_IS_OK(status)) {
5118 printf("QueryDisplayInfo level %u failed - %s\n",
5119 r.in.level, nt_errstr(status));
5124 } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
5125 NT_STATUS_IS_OK(status)) &&
5126 *r.out.returned_size != 0);
5131 static bool test_QueryDomainInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
5132 struct policy_handle *handle)
5135 struct samr_QueryDomainInfo r;
5136 union samr_DomainInfo *info = NULL;
5137 struct samr_SetDomainInfo s;
5138 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
5139 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
5142 const char *domain_comment = talloc_asprintf(tctx,
5143 "Tortured by Samba4 RPC-SAMR: %s",
5144 timestring(tctx, time(NULL)));
5146 s.in.domain_handle = handle;
5148 s.in.info = talloc(tctx, union samr_DomainInfo);
5150 s.in.info->oem.oem_information.string = domain_comment;
5151 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
5152 if (!NT_STATUS_IS_OK(status)) {
5153 printf("SetDomainInfo level %u (set comment) failed - %s\n",
5154 r.in.level, nt_errstr(status));
5158 for (i=0;i<ARRAY_SIZE(levels);i++) {
5159 torture_comment(tctx, "Testing QueryDomainInfo level %u\n", levels[i]);
5161 r.in.domain_handle = handle;
5162 r.in.level = levels[i];
5165 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
5166 if (!NT_STATUS_IS_OK(status)) {
5167 printf("QueryDomainInfo level %u failed - %s\n",
5168 r.in.level, nt_errstr(status));
5173 switch (levels[i]) {
5175 if (strcmp(info->general.oem_information.string, domain_comment) != 0) {
5176 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
5177 levels[i], info->general.oem_information.string, domain_comment);
5180 if (!info->general.primary.string) {
5181 printf("QueryDomainInfo level %u returned no PDC name\n",
5184 } else if (info->general.role == SAMR_ROLE_DOMAIN_PDC) {
5185 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), info->general.primary.string) != 0) {
5186 printf("QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
5187 levels[i], info->general.primary.string, dcerpc_server_name(p));
5192 if (strcmp(info->oem.oem_information.string, domain_comment) != 0) {
5193 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
5194 levels[i], info->oem.oem_information.string, domain_comment);
5199 if (!info->info6.primary.string) {
5200 printf("QueryDomainInfo level %u returned no PDC name\n",
5206 if (strcmp(info->general2.general.oem_information.string, domain_comment) != 0) {
5207 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
5208 levels[i], info->general2.general.oem_information.string, domain_comment);
5214 torture_comment(tctx, "Testing SetDomainInfo level %u\n", levels[i]);
5216 s.in.domain_handle = handle;
5217 s.in.level = levels[i];
5220 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
5222 if (!NT_STATUS_IS_OK(status)) {
5223 printf("SetDomainInfo level %u failed - %s\n",
5224 r.in.level, nt_errstr(status));
5229 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
5230 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
5231 r.in.level, nt_errstr(status));
5237 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
5238 if (!NT_STATUS_IS_OK(status)) {
5239 printf("QueryDomainInfo level %u failed - %s\n",
5240 r.in.level, nt_errstr(status));
5250 static bool test_QueryDomainInfo2(struct dcerpc_pipe *p, struct torture_context *tctx,
5251 struct policy_handle *handle)
5254 struct samr_QueryDomainInfo2 r;
5255 union samr_DomainInfo *info = NULL;
5256 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
5260 for (i=0;i<ARRAY_SIZE(levels);i++) {
5261 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
5263 r.in.domain_handle = handle;
5264 r.in.level = levels[i];
5267 status = dcerpc_samr_QueryDomainInfo2(p, tctx, &r);
5268 if (!NT_STATUS_IS_OK(status)) {
5269 printf("QueryDomainInfo2 level %u failed - %s\n",
5270 r.in.level, nt_errstr(status));
5279 /* Test whether querydispinfo level 5 and enumdomgroups return the same
5280 set of group names. */
5281 static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx,
5282 struct policy_handle *handle)
5284 struct samr_EnumDomainGroups q1;
5285 struct samr_QueryDisplayInfo q2;
5287 uint32_t resume_handle=0;
5288 struct samr_SamArray *sam = NULL;
5289 uint32_t num_entries = 0;
5292 uint32_t total_size;
5293 uint32_t returned_size;
5294 union samr_DispInfo info;
5297 const char **names = NULL;
5299 torture_comment(tctx, "Testing coherency of querydispinfo vs enumdomgroups\n");
5301 q1.in.domain_handle = handle;
5302 q1.in.resume_handle = &resume_handle;
5304 q1.out.resume_handle = &resume_handle;
5305 q1.out.num_entries = &num_entries;
5308 status = STATUS_MORE_ENTRIES;
5309 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
5310 status = dcerpc_samr_EnumDomainGroups(p, tctx, &q1);
5312 if (!NT_STATUS_IS_OK(status) &&
5313 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
5316 for (i=0; i<*q1.out.num_entries; i++) {
5317 add_string_to_array(tctx,
5318 sam->entries[i].name.string,
5319 &names, &num_names);
5323 torture_assert_ntstatus_ok(tctx, status, "EnumDomainGroups");
5325 torture_assert(tctx, sam, "EnumDomainGroups failed to return sam");
5327 q2.in.domain_handle = handle;
5329 q2.in.start_idx = 0;
5330 q2.in.max_entries = 5;
5331 q2.in.buf_size = (uint32_t)-1;
5332 q2.out.total_size = &total_size;
5333 q2.out.returned_size = &returned_size;
5334 q2.out.info = &info;
5336 status = STATUS_MORE_ENTRIES;
5337 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
5338 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &q2);
5340 if (!NT_STATUS_IS_OK(status) &&
5341 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
5344 for (i=0; i<q2.out.info->info5.count; i++) {
5346 const char *name = q2.out.info->info5.entries[i].account_name.string;
5348 for (j=0; j<num_names; j++) {
5349 if (names[j] == NULL)
5351 if (strequal(names[j], name)) {
5359 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
5364 q2.in.start_idx += q2.out.info->info5.count;
5367 if (!NT_STATUS_IS_OK(status)) {
5368 printf("QueryDisplayInfo level 5 failed - %s\n",
5373 for (i=0; i<num_names; i++) {
5374 if (names[i] != NULL) {
5375 printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
5384 static bool test_DeleteDomainGroup(struct dcerpc_pipe *p, struct torture_context *tctx,
5385 struct policy_handle *group_handle)
5387 struct samr_DeleteDomainGroup d;
5390 torture_comment(tctx, "Testing DeleteDomainGroup\n");
5392 d.in.group_handle = group_handle;
5393 d.out.group_handle = group_handle;
5395 status = dcerpc_samr_DeleteDomainGroup(p, tctx, &d);
5396 torture_assert_ntstatus_ok(tctx, status, "DeleteDomainGroup");
5401 static bool test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
5402 struct policy_handle *domain_handle)
5404 struct samr_TestPrivateFunctionsDomain r;
5408 torture_comment(tctx, "Testing TestPrivateFunctionsDomain\n");
5410 r.in.domain_handle = domain_handle;
5412 status = dcerpc_samr_TestPrivateFunctionsDomain(p, tctx, &r);
5413 torture_assert_ntstatus_equal(tctx, NT_STATUS_NOT_IMPLEMENTED, status, "TestPrivateFunctionsDomain");
5418 static bool test_RidToSid(struct dcerpc_pipe *p, struct torture_context *tctx,
5419 struct dom_sid *domain_sid,
5420 struct policy_handle *domain_handle)
5422 struct samr_RidToSid r;
5425 struct dom_sid *calc_sid, *out_sid;
5426 int rids[] = { 0, 42, 512, 10200 };
5429 for (i=0;i<ARRAY_SIZE(rids);i++) {
5430 torture_comment(tctx, "Testing RidToSid\n");
5432 calc_sid = dom_sid_dup(tctx, domain_sid);
5433 r.in.domain_handle = domain_handle;
5435 r.out.sid = &out_sid;
5437 status = dcerpc_samr_RidToSid(p, tctx, &r);
5438 if (!NT_STATUS_IS_OK(status)) {
5439 printf("RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
5442 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
5444 if (!dom_sid_equal(calc_sid, out_sid)) {
5445 printf("RidToSid for %d failed - got %s, expected %s\n", rids[i],
5446 dom_sid_string(tctx, out_sid),
5447 dom_sid_string(tctx, calc_sid));
5456 static bool test_GetBootKeyInformation(struct dcerpc_pipe *p, struct torture_context *tctx,
5457 struct policy_handle *domain_handle)
5459 struct samr_GetBootKeyInformation r;
5462 uint32_t unknown = 0;
5464 torture_comment(tctx, "Testing GetBootKeyInformation\n");
5466 r.in.domain_handle = domain_handle;
5467 r.out.unknown = &unknown;
5469 status = dcerpc_samr_GetBootKeyInformation(p, tctx, &r);
5470 if (!NT_STATUS_IS_OK(status)) {
5471 /* w2k3 seems to fail this sometimes and pass it sometimes */
5472 torture_comment(tctx, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
5478 static bool test_AddGroupMember(struct dcerpc_pipe *p, struct torture_context *tctx,
5479 struct policy_handle *domain_handle,
5480 struct policy_handle *group_handle)
5483 struct samr_AddGroupMember r;
5484 struct samr_DeleteGroupMember d;
5485 struct samr_QueryGroupMember q;
5486 struct samr_RidTypeArray *rids = NULL;
5487 struct samr_SetMemberAttributesOfGroup s;
5490 status = test_LookupName(p, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
5491 torture_assert_ntstatus_ok(tctx, status, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME);
5493 r.in.group_handle = group_handle;
5495 r.in.flags = 0; /* ??? */
5497 torture_comment(tctx, "Testing AddGroupMember and DeleteGroupMember\n");
5499 d.in.group_handle = group_handle;
5502 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
5503 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_NOT_IN_GROUP, status, "DeleteGroupMember");
5505 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5506 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
5508 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5509 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_IN_GROUP, status, "AddGroupMember");
5511 if (torture_setting_bool(tctx, "samba4", false)) {
5512 torture_comment(tctx, "skipping SetMemberAttributesOfGroup test against Samba4\n");
5514 /* this one is quite strange. I am using random inputs in the
5515 hope of triggering an error that might give us a clue */
5517 s.in.group_handle = group_handle;
5518 s.in.unknown1 = random();
5519 s.in.unknown2 = random();
5521 status = dcerpc_samr_SetMemberAttributesOfGroup(p, tctx, &s);
5522 torture_assert_ntstatus_ok(tctx, status, "SetMemberAttributesOfGroup");
5525 q.in.group_handle = group_handle;
5528 status = dcerpc_samr_QueryGroupMember(p, tctx, &q);
5529 torture_assert_ntstatus_ok(tctx, status, "QueryGroupMember");
5531 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
5532 torture_assert_ntstatus_ok(tctx, status, "DeleteGroupMember");
5534 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5535 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
5541 static bool test_CreateDomainGroup(struct dcerpc_pipe *p,
5542 struct torture_context *tctx,
5543 struct policy_handle *domain_handle,
5544 struct policy_handle *group_handle,
5545 struct dom_sid *domain_sid)
5548 struct samr_CreateDomainGroup r;
5550 struct lsa_String name;
5553 init_lsa_String(&name, TEST_GROUPNAME);
5555 r.in.domain_handle = domain_handle;
5557 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5558 r.out.group_handle = group_handle;
5561 printf("Testing CreateDomainGroup(%s)\n", r.in.name->string);
5563 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
5565 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5566 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5567 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.name->string);
5570 printf("Server should have refused create of '%s', got %s instead\n", r.in.name->string,
5576 if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS)) {
5577 if (!test_DeleteGroup_byname(p, tctx, domain_handle, r.in.name->string)) {
5578 printf("CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
5582 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
5584 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
5585 if (!test_DeleteUser_byname(p, tctx, domain_handle, r.in.name->string)) {
5587 printf("CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
5591 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
5593 torture_assert_ntstatus_ok(tctx, status, "CreateDomainGroup");
5595 if (!test_AddGroupMember(p, tctx, domain_handle, group_handle)) {
5596 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
5600 if (!test_SetGroupInfo(p, tctx, group_handle)) {
5609 its not totally clear what this does. It seems to accept any sid you like.
5611 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p,
5612 struct torture_context *tctx,
5613 struct policy_handle *domain_handle)
5616 struct samr_RemoveMemberFromForeignDomain r;
5618 r.in.domain_handle = domain_handle;
5619 r.in.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-12-34-56-78");
5621 status = dcerpc_samr_RemoveMemberFromForeignDomain(p, tctx, &r);
5622 torture_assert_ntstatus_ok(tctx, status, "RemoveMemberFromForeignDomain");
5629 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
5630 struct policy_handle *handle);
5632 static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
5633 struct policy_handle *handle, struct dom_sid *sid,
5634 enum torture_samr_choice which_ops,
5635 struct cli_credentials *machine_credentials)
5638 struct samr_OpenDomain r;
5639 struct policy_handle domain_handle;
5640 struct policy_handle alias_handle;
5641 struct policy_handle user_handle;
5642 struct policy_handle group_handle;
5645 ZERO_STRUCT(alias_handle);
5646 ZERO_STRUCT(user_handle);
5647 ZERO_STRUCT(group_handle);
5648 ZERO_STRUCT(domain_handle);
5650 torture_comment(tctx, "Testing OpenDomain of %s\n", dom_sid_string(tctx, sid));
5652 r.in.connect_handle = handle;
5653 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5655 r.out.domain_handle = &domain_handle;
5657 status = dcerpc_samr_OpenDomain(p, tctx, &r);
5658 torture_assert_ntstatus_ok(tctx, status, "OpenDomain");
5660 /* run the domain tests with the main handle closed - this tests
5661 the servers reference counting */
5662 ret &= test_samr_handle_Close(p, tctx, handle);
5664 switch (which_ops) {
5665 case TORTURE_SAMR_USER_ATTRIBUTES:
5666 case TORTURE_SAMR_PASSWORDS:
5667 if (!torture_setting_bool(tctx, "samba3", false)) {
5668 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops, NULL);
5670 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops, NULL);
5671 /* This test needs 'complex' users to validate */
5672 ret &= test_QueryDisplayInfo(p, tctx, &domain_handle);
5674 printf("Testing PASSWORDS or ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
5677 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
5678 if (!torture_setting_bool(tctx, "samba3", false)) {
5679 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops, machine_credentials);
5681 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops, machine_credentials);
5683 printf("Testing PASSWORDS PWDLASTSET on domain %s failed!\n", dom_sid_string(tctx, sid));
5686 case TORTURE_SAMR_OTHER:
5687 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops, NULL);
5689 printf("Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid));
5691 ret &= test_QuerySecurity(p, tctx, &domain_handle);
5692 ret &= test_RemoveMemberFromForeignDomain(p, tctx, &domain_handle);
5693 ret &= test_CreateAlias(p, tctx, &domain_handle, &alias_handle, sid);
5694 ret &= test_CreateDomainGroup(p, tctx, &domain_handle, &group_handle, sid);
5695 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
5696 ret &= test_QueryDomainInfo2(p, tctx, &domain_handle);
5697 ret &= test_EnumDomainUsers(p, tctx, &domain_handle);
5698 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
5699 ret &= test_EnumDomainGroups(p, tctx, &domain_handle);
5700 ret &= test_EnumDomainAliases(p, tctx, &domain_handle);
5701 ret &= test_QueryDisplayInfo2(p, tctx, &domain_handle);
5702 ret &= test_QueryDisplayInfo3(p, tctx, &domain_handle);
5703 ret &= test_QueryDisplayInfo_continue(p, tctx, &domain_handle);
5705 if (torture_setting_bool(tctx, "samba4", false)) {
5706 torture_comment(tctx, "skipping GetDisplayEnumerationIndex test against Samba4\n");
5708 ret &= test_GetDisplayEnumerationIndex(p, tctx, &domain_handle);
5709 ret &= test_GetDisplayEnumerationIndex2(p, tctx, &domain_handle);
5711 ret &= test_GroupList(p, tctx, &domain_handle);
5712 ret &= test_TestPrivateFunctionsDomain(p, tctx, &domain_handle);
5713 ret &= test_RidToSid(p, tctx, sid, &domain_handle);
5714 ret &= test_GetBootKeyInformation(p, tctx, &domain_handle);
5716 torture_comment(tctx, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx, sid));
5721 if (!policy_handle_empty(&user_handle) &&
5722 !test_DeleteUser(p, tctx, &user_handle)) {
5726 if (!policy_handle_empty(&alias_handle) &&
5727 !test_DeleteAlias(p, tctx, &alias_handle)) {
5731 if (!policy_handle_empty(&group_handle) &&
5732 !test_DeleteDomainGroup(p, tctx, &group_handle)) {
5736 ret &= test_samr_handle_Close(p, tctx, &domain_handle);
5738 /* reconnect the main handle */
5739 ret &= test_Connect(p, tctx, handle);
5742 printf("Testing domain %s failed!\n", dom_sid_string(tctx, sid));
5748 static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
5749 struct policy_handle *handle, const char *domain,
5750 enum torture_samr_choice which_ops,
5751 struct cli_credentials *machine_credentials)
5754 struct samr_LookupDomain r;
5755 struct dom_sid2 *sid = NULL;
5756 struct lsa_String n1;
5757 struct lsa_String n2;
5760 torture_comment(tctx, "Testing LookupDomain(%s)\n", domain);
5762 /* check for correct error codes */
5763 r.in.connect_handle = handle;
5764 r.in.domain_name = &n2;
5768 status = dcerpc_samr_LookupDomain(p, tctx, &r);
5769 torture_assert_ntstatus_equal(tctx, NT_STATUS_INVALID_PARAMETER, status, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
5771 init_lsa_String(&n2, "xxNODOMAINxx");
5773 status = dcerpc_samr_LookupDomain(p, tctx, &r);
5774 torture_assert_ntstatus_equal(tctx, NT_STATUS_NO_SUCH_DOMAIN, status, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
5776 r.in.connect_handle = handle;
5778 init_lsa_String(&n1, domain);
5779 r.in.domain_name = &n1;
5781 status = dcerpc_samr_LookupDomain(p, tctx, &r);
5782 torture_assert_ntstatus_ok(tctx, status, "LookupDomain");
5784 if (!test_GetDomPwInfo(p, tctx, &n1)) {
5788 if (!test_OpenDomain(p, tctx, handle, *r.out.sid, which_ops,
5789 machine_credentials)) {
5797 static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
5798 struct policy_handle *handle, enum torture_samr_choice which_ops,
5799 struct cli_credentials *machine_credentials)
5802 struct samr_EnumDomains r;
5803 uint32_t resume_handle = 0;
5804 uint32_t num_entries = 0;
5805 struct samr_SamArray *sam = NULL;
5809 r.in.connect_handle = handle;
5810 r.in.resume_handle = &resume_handle;
5811 r.in.buf_size = (uint32_t)-1;
5812 r.out.resume_handle = &resume_handle;
5813 r.out.num_entries = &num_entries;
5816 status = dcerpc_samr_EnumDomains(p, tctx, &r);
5817 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
5823 for (i=0;i<sam->count;i++) {
5824 if (!test_LookupDomain(p, tctx, handle,
5825 sam->entries[i].name.string, which_ops,
5826 machine_credentials)) {
5831 status = dcerpc_samr_EnumDomains(p, tctx, &r);
5832 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
5838 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
5839 struct policy_handle *handle)
5842 struct samr_Connect r;
5843 struct samr_Connect2 r2;
5844 struct samr_Connect3 r3;
5845 struct samr_Connect4 r4;
5846 struct samr_Connect5 r5;
5847 union samr_ConnectInfo info;
5848 struct policy_handle h;
5849 uint32_t level_out = 0;
5850 bool ret = true, got_handle = false;
5852 torture_comment(tctx, "testing samr_Connect\n");
5854 r.in.system_name = 0;
5855 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5856 r.out.connect_handle = &h;
5858 status = dcerpc_samr_Connect(p, tctx, &r);
5859 if (!NT_STATUS_IS_OK(status)) {
5860 torture_comment(tctx, "Connect failed - %s\n", nt_errstr(status));
5867 torture_comment(tctx, "testing samr_Connect2\n");
5869 r2.in.system_name = NULL;
5870 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5871 r2.out.connect_handle = &h;
5873 status = dcerpc_samr_Connect2(p, tctx, &r2);
5874 if (!NT_STATUS_IS_OK(status)) {
5875 torture_comment(tctx, "Connect2 failed - %s\n", nt_errstr(status));
5879 test_samr_handle_Close(p, tctx, handle);
5885 torture_comment(tctx, "testing samr_Connect3\n");
5887 r3.in.system_name = NULL;
5889 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5890 r3.out.connect_handle = &h;
5892 status = dcerpc_samr_Connect3(p, tctx, &r3);
5893 if (!NT_STATUS_IS_OK(status)) {
5894 printf("Connect3 failed - %s\n", nt_errstr(status));
5898 test_samr_handle_Close(p, tctx, handle);
5904 torture_comment(tctx, "testing samr_Connect4\n");
5906 r4.in.system_name = "";
5907 r4.in.client_version = 0;
5908 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5909 r4.out.connect_handle = &h;
5911 status = dcerpc_samr_Connect4(p, tctx, &r4);
5912 if (!NT_STATUS_IS_OK(status)) {
5913 printf("Connect4 failed - %s\n", nt_errstr(status));
5917 test_samr_handle_Close(p, tctx, handle);
5923 torture_comment(tctx, "testing samr_Connect5\n");
5925 info.info1.client_version = 0;
5926 info.info1.unknown2 = 0;
5928 r5.in.system_name = "";
5929 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5931 r5.out.level_out = &level_out;
5932 r5.in.info_in = &info;
5933 r5.out.info_out = &info;
5934 r5.out.connect_handle = &h;
5936 status = dcerpc_samr_Connect5(p, tctx, &r5);
5937 if (!NT_STATUS_IS_OK(status)) {
5938 printf("Connect5 failed - %s\n", nt_errstr(status));
5942 test_samr_handle_Close(p, tctx, handle);
5952 bool torture_rpc_samr(struct torture_context *torture)
5955 struct dcerpc_pipe *p;
5957 struct policy_handle handle;
5959 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
5960 if (!NT_STATUS_IS_OK(status)) {
5964 ret &= test_Connect(p, torture, &handle);
5966 ret &= test_QuerySecurity(p, torture, &handle);
5968 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_OTHER, NULL);
5970 ret &= test_SetDsrmPassword(p, torture, &handle);
5972 ret &= test_Shutdown(p, torture, &handle);
5974 ret &= test_samr_handle_Close(p, torture, &handle);
5980 bool torture_rpc_samr_users(struct torture_context *torture)
5983 struct dcerpc_pipe *p;
5985 struct policy_handle handle;
5987 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
5988 if (!NT_STATUS_IS_OK(status)) {
5992 ret &= test_Connect(p, torture, &handle);
5994 ret &= test_QuerySecurity(p, torture, &handle);
5996 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_USER_ATTRIBUTES, NULL);
5998 ret &= test_SetDsrmPassword(p, torture, &handle);
6000 ret &= test_Shutdown(p, torture, &handle);
6002 ret &= test_samr_handle_Close(p, torture, &handle);
6008 bool torture_rpc_samr_passwords(struct torture_context *torture)
6011 struct dcerpc_pipe *p;
6013 struct policy_handle handle;
6015 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6016 if (!NT_STATUS_IS_OK(status)) {
6020 ret &= test_Connect(p, torture, &handle);
6022 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_PASSWORDS, NULL);
6024 ret &= test_samr_handle_Close(p, torture, &handle);
6029 static bool torture_rpc_samr_pwdlastset(struct torture_context *torture,
6030 struct dcerpc_pipe *p2,
6031 struct cli_credentials *machine_credentials)
6034 struct dcerpc_pipe *p;
6036 struct policy_handle handle;
6038 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6039 if (!NT_STATUS_IS_OK(status)) {
6043 ret &= test_Connect(p, torture, &handle);
6045 ret &= test_EnumDomains(p, torture, &handle,
6046 TORTURE_SAMR_PASSWORDS_PWDLASTSET,
6047 machine_credentials);
6049 ret &= test_samr_handle_Close(p, torture, &handle);
6054 struct torture_suite *torture_rpc_samr_passwords_pwdlastset(TALLOC_CTX *mem_ctx)
6056 struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-PASSWORDS-PWDLASTSET");
6057 struct torture_rpc_tcase *tcase;
6059 tcase = torture_suite_add_machine_rpc_iface_tcase(suite, "samr",
6061 TEST_ACCOUNT_NAME_PWD);
6063 torture_rpc_tcase_add_test_creds(tcase, "pwdLastSet",
6064 torture_rpc_samr_pwdlastset);