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_samr_c.h"
27 #include "../lib/crypto/crypto.h"
28 #include "libcli/auth/libcli_auth.h"
29 #include "libcli/security/security.h"
30 #include "torture/rpc/rpc.h"
32 #define TEST_ACCOUNT_NAME "samrtorturetest"
33 #define TEST_ALIASNAME "samrtorturetestalias"
34 #define TEST_GROUPNAME "samrtorturetestgroup"
35 #define TEST_MACHINENAME "samrtestmach$"
36 #define TEST_DOMAINNAME "samrtestdom$"
38 enum torture_samr_choice {
39 TORTURE_SAMR_PASSWORDS,
40 TORTURE_SAMR_USER_ATTRIBUTES,
44 static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
45 struct policy_handle *handle);
47 static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
48 struct policy_handle *handle);
50 static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
51 struct policy_handle *handle);
53 static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
54 const char *acct_name,
55 struct policy_handle *domain_handle, char **password);
57 static void init_lsa_String(struct lsa_String *string, const char *s)
62 static void init_lsa_BinaryString(struct lsa_BinaryString *string, const char *s, uint32_t length)
64 string->length = length;
65 string->size = length;
66 string->array = (uint16_t *)discard_const(s);
69 bool test_samr_handle_Close(struct dcerpc_pipe *p, struct torture_context *tctx,
70 struct policy_handle *handle)
76 r.out.handle = handle;
78 status = dcerpc_samr_Close(p, tctx, &r);
79 torture_assert_ntstatus_ok(tctx, status, "Close");
84 static bool test_Shutdown(struct dcerpc_pipe *p, struct torture_context *tctx,
85 struct policy_handle *handle)
88 struct samr_Shutdown r;
90 if (!torture_setting_bool(tctx, "dangerous", false)) {
91 torture_skip(tctx, "samr_Shutdown disabled - enable dangerous tests to use\n");
95 r.in.connect_handle = handle;
97 torture_comment(tctx, "testing samr_Shutdown\n");
99 status = dcerpc_samr_Shutdown(p, tctx, &r);
100 torture_assert_ntstatus_ok(tctx, status, "samr_Shutdown");
105 static bool test_SetDsrmPassword(struct dcerpc_pipe *p, struct torture_context *tctx,
106 struct policy_handle *handle)
109 struct samr_SetDsrmPassword r;
110 struct lsa_String string;
111 struct samr_Password hash;
113 if (!torture_setting_bool(tctx, "dangerous", false)) {
114 torture_skip(tctx, "samr_SetDsrmPassword disabled - enable dangerous tests to use");
117 E_md4hash("TeSTDSRM123", hash.hash);
119 init_lsa_String(&string, "Administrator");
125 torture_comment(tctx, "testing samr_SetDsrmPassword\n");
127 status = dcerpc_samr_SetDsrmPassword(p, tctx, &r);
128 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_SUPPORTED, "samr_SetDsrmPassword");
134 static bool test_QuerySecurity(struct dcerpc_pipe *p,
135 struct torture_context *tctx,
136 struct policy_handle *handle)
139 struct samr_QuerySecurity r;
140 struct samr_SetSecurity s;
141 struct sec_desc_buf *sdbuf = NULL;
143 r.in.handle = handle;
145 r.out.sdbuf = &sdbuf;
147 status = dcerpc_samr_QuerySecurity(p, tctx, &r);
148 torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
150 torture_assert(tctx, sdbuf != NULL, "sdbuf is NULL");
152 s.in.handle = handle;
156 if (torture_setting_bool(tctx, "samba4", false)) {
157 torture_skip(tctx, "skipping SetSecurity test against Samba4\n");
160 status = dcerpc_samr_SetSecurity(p, tctx, &s);
161 torture_assert_ntstatus_ok(tctx, status, "SetSecurity");
163 status = dcerpc_samr_QuerySecurity(p, tctx, &r);
164 torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
170 static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
171 struct policy_handle *handle, uint32_t base_acct_flags,
172 const char *base_account_name)
175 struct samr_SetUserInfo s;
176 struct samr_SetUserInfo2 s2;
177 struct samr_QueryUserInfo q;
178 struct samr_QueryUserInfo q0;
179 union samr_UserInfo u;
180 union samr_UserInfo *info;
182 const char *test_account_name;
184 uint32_t user_extra_flags = 0;
185 if (base_acct_flags == ACB_NORMAL) {
186 /* When created, accounts are expired by default */
187 user_extra_flags = ACB_PW_EXPIRED;
190 s.in.user_handle = handle;
193 s2.in.user_handle = handle;
196 q.in.user_handle = handle;
200 #define TESTCALL(call, r) \
201 status = dcerpc_samr_ ##call(p, tctx, &r); \
202 if (!NT_STATUS_IS_OK(status)) { \
203 torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
204 r.in.level, nt_errstr(status), __location__); \
209 #define STRING_EQUAL(s1, s2, field) \
210 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
211 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
212 #field, s2, __location__); \
217 #define MEM_EQUAL(s1, s2, length, field) \
218 if ((s1 && !s2) || (s2 && !s1) || memcmp(s1, s2, length)) { \
219 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
220 #field, (const char *)s2, __location__); \
225 #define INT_EQUAL(i1, i2, field) \
227 torture_comment(tctx, "Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \
228 #field, (unsigned long long)i2, (unsigned long long)i1, __location__); \
233 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
234 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
236 TESTCALL(QueryUserInfo, q) \
238 s2.in.level = lvl1; \
241 ZERO_STRUCT(u.info21); \
242 u.info21.fields_present = fpval; \
244 init_lsa_String(&u.info ## lvl1.field1, value); \
245 TESTCALL(SetUserInfo, s) \
246 TESTCALL(SetUserInfo2, s2) \
247 init_lsa_String(&u.info ## lvl1.field1, ""); \
248 TESTCALL(QueryUserInfo, q); \
250 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
252 TESTCALL(QueryUserInfo, q) \
254 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
257 #define TEST_USERINFO_BINARYSTRING(lvl1, field1, lvl2, field2, value, fpval) do { \
258 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
260 TESTCALL(QueryUserInfo, q) \
262 s2.in.level = lvl1; \
265 ZERO_STRUCT(u.info21); \
266 u.info21.fields_present = fpval; \
268 init_lsa_BinaryString(&u.info ## lvl1.field1, value, strlen(value)); \
269 TESTCALL(SetUserInfo, s) \
270 TESTCALL(SetUserInfo2, s2) \
271 init_lsa_BinaryString(&u.info ## lvl1.field1, "", 1); \
272 TESTCALL(QueryUserInfo, q); \
274 MEM_EQUAL(u.info ## lvl1.field1.array, value, strlen(value), field1); \
276 TESTCALL(QueryUserInfo, q) \
278 MEM_EQUAL(u.info ## lvl2.field2.array, value, strlen(value), field2); \
281 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
282 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
284 TESTCALL(QueryUserInfo, q) \
286 s2.in.level = lvl1; \
289 uint8_t *bits = u.info21.logon_hours.bits; \
290 ZERO_STRUCT(u.info21); \
291 if (fpval == SAMR_FIELD_LOGON_HOURS) { \
292 u.info21.logon_hours.units_per_week = 168; \
293 u.info21.logon_hours.bits = bits; \
295 u.info21.fields_present = fpval; \
297 u.info ## lvl1.field1 = value; \
298 TESTCALL(SetUserInfo, s) \
299 TESTCALL(SetUserInfo2, s2) \
300 u.info ## lvl1.field1 = 0; \
301 TESTCALL(QueryUserInfo, q); \
303 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
305 TESTCALL(QueryUserInfo, q) \
307 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
310 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
311 TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
315 do { TESTCALL(QueryUserInfo, q0) } while (0);
317 TEST_USERINFO_STRING(2, comment, 1, comment, "xx2-1 comment", 0);
318 TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
319 TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment",
322 test_account_name = talloc_asprintf(tctx, "%sxx7-1", base_account_name);
323 TEST_USERINFO_STRING(7, account_name, 1, account_name, base_account_name, 0);
324 test_account_name = talloc_asprintf(tctx, "%sxx7-3", base_account_name);
325 TEST_USERINFO_STRING(7, account_name, 3, account_name, base_account_name, 0);
326 test_account_name = talloc_asprintf(tctx, "%sxx7-5", base_account_name);
327 TEST_USERINFO_STRING(7, account_name, 5, account_name, base_account_name, 0);
328 test_account_name = talloc_asprintf(tctx, "%sxx7-6", base_account_name);
329 TEST_USERINFO_STRING(7, account_name, 6, account_name, base_account_name, 0);
330 test_account_name = talloc_asprintf(tctx, "%sxx7-7", base_account_name);
331 TEST_USERINFO_STRING(7, account_name, 7, account_name, base_account_name, 0);
332 test_account_name = talloc_asprintf(tctx, "%sxx7-21", base_account_name);
333 TEST_USERINFO_STRING(7, account_name, 21, account_name, base_account_name, 0);
334 test_account_name = base_account_name;
335 TEST_USERINFO_STRING(21, account_name, 21, account_name, base_account_name,
336 SAMR_FIELD_ACCOUNT_NAME);
338 TEST_USERINFO_STRING(6, full_name, 1, full_name, "xx6-1 full_name", 0);
339 TEST_USERINFO_STRING(6, full_name, 3, full_name, "xx6-3 full_name", 0);
340 TEST_USERINFO_STRING(6, full_name, 5, full_name, "xx6-5 full_name", 0);
341 TEST_USERINFO_STRING(6, full_name, 6, full_name, "xx6-6 full_name", 0);
342 TEST_USERINFO_STRING(6, full_name, 8, full_name, "xx6-8 full_name", 0);
343 TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
344 TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
345 TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name",
346 SAMR_FIELD_FULL_NAME);
348 TEST_USERINFO_STRING(6, full_name, 1, full_name, "", 0);
349 TEST_USERINFO_STRING(6, full_name, 3, full_name, "", 0);
350 TEST_USERINFO_STRING(6, full_name, 5, full_name, "", 0);
351 TEST_USERINFO_STRING(6, full_name, 6, full_name, "", 0);
352 TEST_USERINFO_STRING(6, full_name, 8, full_name, "", 0);
353 TEST_USERINFO_STRING(6, full_name, 21, full_name, "", 0);
354 TEST_USERINFO_STRING(8, full_name, 21, full_name, "", 0);
355 TEST_USERINFO_STRING(21, full_name, 21, full_name, "",
356 SAMR_FIELD_FULL_NAME);
358 TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
359 TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
360 TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
361 TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script",
362 SAMR_FIELD_LOGON_SCRIPT);
364 TEST_USERINFO_STRING(12, profile_path, 3, profile_path, "xx12-3 profile_path", 0);
365 TEST_USERINFO_STRING(12, profile_path, 5, profile_path, "xx12-5 profile_path", 0);
366 TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
367 TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path",
368 SAMR_FIELD_PROFILE_PATH);
370 TEST_USERINFO_STRING(10, home_directory, 3, home_directory, "xx10-3 home_directory", 0);
371 TEST_USERINFO_STRING(10, home_directory, 5, home_directory, "xx10-5 home_directory", 0);
372 TEST_USERINFO_STRING(10, home_directory, 21, home_directory, "xx10-21 home_directory", 0);
373 TEST_USERINFO_STRING(21, home_directory, 21, home_directory, "xx21-21 home_directory",
374 SAMR_FIELD_HOME_DIRECTORY);
375 TEST_USERINFO_STRING(21, home_directory, 10, home_directory, "xx21-10 home_directory",
376 SAMR_FIELD_HOME_DIRECTORY);
378 TEST_USERINFO_STRING(10, home_drive, 3, home_drive, "xx10-3 home_drive", 0);
379 TEST_USERINFO_STRING(10, home_drive, 5, home_drive, "xx10-5 home_drive", 0);
380 TEST_USERINFO_STRING(10, home_drive, 21, home_drive, "xx10-21 home_drive", 0);
381 TEST_USERINFO_STRING(21, home_drive, 21, home_drive, "xx21-21 home_drive",
382 SAMR_FIELD_HOME_DRIVE);
383 TEST_USERINFO_STRING(21, home_drive, 10, home_drive, "xx21-10 home_drive",
384 SAMR_FIELD_HOME_DRIVE);
386 TEST_USERINFO_STRING(13, description, 1, description, "xx13-1 description", 0);
387 TEST_USERINFO_STRING(13, description, 5, description, "xx13-5 description", 0);
388 TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
389 TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description",
390 SAMR_FIELD_DESCRIPTION);
392 TEST_USERINFO_STRING(14, workstations, 3, workstations, "14workstation3", 0);
393 TEST_USERINFO_STRING(14, workstations, 5, workstations, "14workstation4", 0);
394 TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
395 TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21",
396 SAMR_FIELD_WORKSTATIONS);
397 TEST_USERINFO_STRING(21, workstations, 3, workstations, "21workstation3",
398 SAMR_FIELD_WORKSTATIONS);
399 TEST_USERINFO_STRING(21, workstations, 5, workstations, "21workstation5",
400 SAMR_FIELD_WORKSTATIONS);
401 TEST_USERINFO_STRING(21, workstations, 14, workstations, "21workstation14",
402 SAMR_FIELD_WORKSTATIONS);
404 TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
405 TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "xx21-21 parameters",
406 SAMR_FIELD_PARAMETERS);
407 TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "xx21-20 parameters",
408 SAMR_FIELD_PARAMETERS);
410 TEST_USERINFO_INT(2, country_code, 2, country_code, __LINE__, 0);
411 TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
412 TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__,
413 SAMR_FIELD_COUNTRY_CODE);
414 TEST_USERINFO_INT(21, country_code, 2, country_code, __LINE__,
415 SAMR_FIELD_COUNTRY_CODE);
417 TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
418 TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__,
419 SAMR_FIELD_CODE_PAGE);
420 TEST_USERINFO_INT(21, code_page, 2, code_page, __LINE__,
421 SAMR_FIELD_CODE_PAGE);
423 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, __LINE__, 0);
424 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, __LINE__, 0);
425 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, __LINE__,
426 SAMR_FIELD_ACCT_EXPIRY);
427 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, __LINE__,
428 SAMR_FIELD_ACCT_EXPIRY);
429 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, __LINE__,
430 SAMR_FIELD_ACCT_EXPIRY);
432 TEST_USERINFO_INT(4, logon_hours.bits[3], 3, logon_hours.bits[3], 1, 0);
433 TEST_USERINFO_INT(4, logon_hours.bits[3], 5, logon_hours.bits[3], 2, 0);
434 TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
435 TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4,
436 SAMR_FIELD_LOGON_HOURS);
438 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
439 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
440 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
442 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
443 (base_acct_flags | ACB_DISABLED),
444 (base_acct_flags | ACB_DISABLED | user_extra_flags),
447 /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
448 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
449 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
450 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
452 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
453 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
454 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
458 /* The 'autolock' flag doesn't stick - check this */
459 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
460 (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK),
461 (base_acct_flags | ACB_DISABLED | user_extra_flags),
464 /* Removing the 'disabled' flag doesn't stick - check this */
465 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
467 (base_acct_flags | ACB_DISABLED | user_extra_flags),
470 /* The 'store plaintext' flag does stick */
471 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
472 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED),
473 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags),
475 /* The 'use DES' flag does stick */
476 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
477 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY),
478 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags),
480 /* The 'don't require kerberos pre-authentication flag does stick */
481 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
482 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH),
483 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags),
485 /* The 'no kerberos PAC required' flag sticks */
486 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
487 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD),
488 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags),
491 TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags,
492 (base_acct_flags | ACB_DISABLED),
493 (base_acct_flags | ACB_DISABLED | user_extra_flags),
494 SAMR_FIELD_ACCT_FLAGS);
497 /* these fail with win2003 - it appears you can't set the primary gid?
498 the set succeeds, but the gid isn't changed. Very weird! */
499 TEST_USERINFO_INT(9, primary_gid, 1, primary_gid, 513);
500 TEST_USERINFO_INT(9, primary_gid, 3, primary_gid, 513);
501 TEST_USERINFO_INT(9, primary_gid, 5, primary_gid, 513);
502 TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
509 generate a random password for password change tests
511 static char *samr_rand_pass_silent(TALLOC_CTX *mem_ctx, int min_len)
513 size_t len = MAX(8, min_len) + (random() % 6);
514 char *s = generate_random_str(mem_ctx, len);
518 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
520 char *s = samr_rand_pass_silent(mem_ctx, min_len);
521 printf("Generated password '%s'\n", s);
527 generate a random password for password change tests
529 static DATA_BLOB samr_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
532 DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
533 generate_random_buffer(password.data, password.length);
535 for (i=0; i < len; i++) {
536 if (((uint16_t *)password.data)[i] == 0) {
537 ((uint16_t *)password.data)[i] = 1;
545 generate a random password for password change tests (fixed length)
547 static char *samr_rand_pass_fixed_len(TALLOC_CTX *mem_ctx, int len)
549 char *s = generate_random_str(mem_ctx, len);
550 printf("Generated password '%s'\n", s);
554 static bool test_SetUserPass(struct dcerpc_pipe *p, struct torture_context *tctx,
555 struct policy_handle *handle, char **password)
558 struct samr_SetUserInfo s;
559 union samr_UserInfo u;
561 DATA_BLOB session_key;
563 struct samr_GetUserPwInfo pwp;
564 struct samr_PwInfo info;
565 int policy_min_pw_len = 0;
566 pwp.in.user_handle = handle;
567 pwp.out.info = &info;
569 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
570 if (NT_STATUS_IS_OK(status)) {
571 policy_min_pw_len = pwp.out.info->min_password_length;
573 newpass = samr_rand_pass(tctx, policy_min_pw_len);
575 s.in.user_handle = handle;
579 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
580 u.info24.password_expired = 0;
582 status = dcerpc_fetch_session_key(p, &session_key);
583 if (!NT_STATUS_IS_OK(status)) {
584 printf("SetUserInfo level %u - no session key - %s\n",
585 s.in.level, nt_errstr(status));
589 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
591 torture_comment(tctx, "Testing SetUserInfo level 24 (set password)\n");
593 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
594 if (!NT_STATUS_IS_OK(status)) {
595 printf("SetUserInfo level %u failed - %s\n",
596 s.in.level, nt_errstr(status));
606 static bool test_SetUserPass_23(struct dcerpc_pipe *p, struct torture_context *tctx,
607 struct policy_handle *handle, uint32_t fields_present,
611 struct samr_SetUserInfo s;
612 union samr_UserInfo u;
614 DATA_BLOB session_key;
616 struct samr_GetUserPwInfo pwp;
617 struct samr_PwInfo info;
618 int policy_min_pw_len = 0;
619 pwp.in.user_handle = handle;
620 pwp.out.info = &info;
622 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
623 if (NT_STATUS_IS_OK(status)) {
624 policy_min_pw_len = pwp.out.info->min_password_length;
626 newpass = samr_rand_pass(tctx, policy_min_pw_len);
628 s.in.user_handle = handle;
634 u.info23.info.fields_present = fields_present;
636 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
638 status = dcerpc_fetch_session_key(p, &session_key);
639 if (!NT_STATUS_IS_OK(status)) {
640 printf("SetUserInfo level %u - no session key - %s\n",
641 s.in.level, nt_errstr(status));
645 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
647 torture_comment(tctx, "Testing SetUserInfo level 23 (set password)\n");
649 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
650 if (!NT_STATUS_IS_OK(status)) {
651 printf("SetUserInfo level %u failed - %s\n",
652 s.in.level, nt_errstr(status));
658 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
660 status = dcerpc_fetch_session_key(p, &session_key);
661 if (!NT_STATUS_IS_OK(status)) {
662 printf("SetUserInfo level %u - no session key - %s\n",
663 s.in.level, nt_errstr(status));
667 /* This should break the key nicely */
668 session_key.length--;
669 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
671 torture_comment(tctx, "Testing SetUserInfo level 23 (set password) with wrong password\n");
673 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
674 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
675 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
676 s.in.level, nt_errstr(status));
684 static bool test_SetUserPassEx(struct dcerpc_pipe *p, struct torture_context *tctx,
685 struct policy_handle *handle, bool makeshort,
689 struct samr_SetUserInfo s;
690 union samr_UserInfo u;
692 DATA_BLOB session_key;
693 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
694 uint8_t confounder[16];
696 struct MD5Context ctx;
697 struct samr_GetUserPwInfo pwp;
698 struct samr_PwInfo info;
699 int policy_min_pw_len = 0;
700 pwp.in.user_handle = handle;
701 pwp.out.info = &info;
703 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
704 if (NT_STATUS_IS_OK(status)) {
705 policy_min_pw_len = pwp.out.info->min_password_length;
707 if (makeshort && policy_min_pw_len) {
708 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len - 1);
710 newpass = samr_rand_pass(tctx, policy_min_pw_len);
713 s.in.user_handle = handle;
717 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
718 u.info26.password_expired = 0;
720 status = dcerpc_fetch_session_key(p, &session_key);
721 if (!NT_STATUS_IS_OK(status)) {
722 printf("SetUserInfo level %u - no session key - %s\n",
723 s.in.level, nt_errstr(status));
727 generate_random_buffer((uint8_t *)confounder, 16);
730 MD5Update(&ctx, confounder, 16);
731 MD5Update(&ctx, session_key.data, session_key.length);
732 MD5Final(confounded_session_key.data, &ctx);
734 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
735 memcpy(&u.info26.password.data[516], confounder, 16);
737 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex)\n");
739 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
740 if (!NT_STATUS_IS_OK(status)) {
741 printf("SetUserInfo level %u failed - %s\n",
742 s.in.level, nt_errstr(status));
748 /* This should break the key nicely */
749 confounded_session_key.data[0]++;
751 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
752 memcpy(&u.info26.password.data[516], confounder, 16);
754 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
756 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
757 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
758 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
759 s.in.level, nt_errstr(status));
768 static bool test_SetUserPass_25(struct dcerpc_pipe *p, struct torture_context *tctx,
769 struct policy_handle *handle, uint32_t fields_present,
773 struct samr_SetUserInfo s;
774 union samr_UserInfo u;
776 DATA_BLOB session_key;
777 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
778 struct MD5Context ctx;
779 uint8_t confounder[16];
781 struct samr_GetUserPwInfo pwp;
782 struct samr_PwInfo info;
783 int policy_min_pw_len = 0;
784 pwp.in.user_handle = handle;
785 pwp.out.info = &info;
787 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
788 if (NT_STATUS_IS_OK(status)) {
789 policy_min_pw_len = pwp.out.info->min_password_length;
791 newpass = samr_rand_pass(tctx, policy_min_pw_len);
793 s.in.user_handle = handle;
799 u.info25.info.fields_present = fields_present;
801 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
803 status = dcerpc_fetch_session_key(p, &session_key);
804 if (!NT_STATUS_IS_OK(status)) {
805 printf("SetUserInfo level %u - no session key - %s\n",
806 s.in.level, nt_errstr(status));
810 generate_random_buffer((uint8_t *)confounder, 16);
813 MD5Update(&ctx, confounder, 16);
814 MD5Update(&ctx, session_key.data, session_key.length);
815 MD5Final(confounded_session_key.data, &ctx);
817 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
818 memcpy(&u.info25.password.data[516], confounder, 16);
820 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex)\n");
822 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
823 if (!NT_STATUS_IS_OK(status)) {
824 printf("SetUserInfo level %u failed - %s\n",
825 s.in.level, nt_errstr(status));
831 /* This should break the key nicely */
832 confounded_session_key.data[0]++;
834 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
835 memcpy(&u.info25.password.data[516], confounder, 16);
837 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
839 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
840 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
841 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
842 s.in.level, nt_errstr(status));
849 static bool test_SetUserPass_level_ex(struct dcerpc_pipe *p,
850 struct torture_context *tctx,
851 struct policy_handle *handle,
853 uint32_t fields_present,
854 char **password, uint8_t password_expired,
855 bool use_setinfo2, NTSTATUS expected_error)
858 struct samr_SetUserInfo s;
859 struct samr_SetUserInfo2 s2;
860 union samr_UserInfo u;
862 DATA_BLOB session_key;
863 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
864 struct MD5Context ctx;
865 uint8_t confounder[16];
867 struct samr_GetUserPwInfo pwp;
868 struct samr_PwInfo info;
869 int policy_min_pw_len = 0;
870 pwp.in.user_handle = handle;
871 pwp.out.info = &info;
873 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
874 if (NT_STATUS_IS_OK(status)) {
875 policy_min_pw_len = pwp.out.info->min_password_length;
877 newpass = samr_rand_pass_silent(tctx, policy_min_pw_len);
880 s2.in.user_handle = handle;
884 s.in.user_handle = handle;
893 u.info21.fields_present = fields_present;
894 u.info21.password_expired = password_expired;
898 u.info23.info.fields_present = fields_present;
899 u.info23.info.password_expired = password_expired;
901 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
905 u.info24.password_expired = password_expired;
907 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
911 u.info25.info.fields_present = fields_present;
912 u.info25.info.password_expired = password_expired;
914 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
918 u.info26.password_expired = password_expired;
920 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
925 status = dcerpc_fetch_session_key(p, &session_key);
926 if (!NT_STATUS_IS_OK(status)) {
927 printf("SetUserInfo level %u - no session key - %s\n",
928 s.in.level, nt_errstr(status));
932 generate_random_buffer((uint8_t *)confounder, 16);
935 MD5Update(&ctx, confounder, 16);
936 MD5Update(&ctx, session_key.data, session_key.length);
937 MD5Final(confounded_session_key.data, &ctx);
941 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
944 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
947 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
948 memcpy(&u.info25.password.data[516], confounder, 16);
951 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
952 memcpy(&u.info26.password.data[516], confounder, 16);
957 status = dcerpc_samr_SetUserInfo2(p, tctx, &s2);
959 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
962 if (NT_STATUS_IS_ERR(expected_error)) {
963 torture_assert_ntstatus_equal(tctx, status, expected_error, "");
967 if (!NT_STATUS_IS_OK(status)) {
968 printf("SetUserInfo%s level %u failed - %s\n",
969 use_setinfo2 ? "2":"", level, nt_errstr(status));
980 static bool test_SetAliasInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
981 struct policy_handle *handle)
984 struct samr_SetAliasInfo r;
985 struct samr_QueryAliasInfo q;
986 union samr_AliasInfo *info;
987 uint16_t levels[] = {2, 3};
991 /* Ignoring switch level 1, as that includes the number of members for the alias
992 * and setting this to a wrong value might have negative consequences
995 for (i=0;i<ARRAY_SIZE(levels);i++) {
996 torture_comment(tctx, "Testing SetAliasInfo level %u\n", levels[i]);
998 r.in.alias_handle = handle;
999 r.in.level = levels[i];
1000 r.in.info = talloc(tctx, union samr_AliasInfo);
1001 switch (r.in.level) {
1002 case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
1003 case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
1004 "Test Description, should test I18N as well"); break;
1005 case ALIASINFOALL: printf("ALIASINFOALL ignored\n"); break;
1008 status = dcerpc_samr_SetAliasInfo(p, tctx, &r);
1009 if (!NT_STATUS_IS_OK(status)) {
1010 printf("SetAliasInfo level %u failed - %s\n",
1011 levels[i], nt_errstr(status));
1015 q.in.alias_handle = handle;
1016 q.in.level = levels[i];
1019 status = dcerpc_samr_QueryAliasInfo(p, tctx, &q);
1020 if (!NT_STATUS_IS_OK(status)) {
1021 printf("QueryAliasInfo level %u failed - %s\n",
1022 levels[i], nt_errstr(status));
1030 static bool test_GetGroupsForUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1031 struct policy_handle *user_handle)
1033 struct samr_GetGroupsForUser r;
1034 struct samr_RidWithAttributeArray *rids = NULL;
1037 torture_comment(tctx, "testing GetGroupsForUser\n");
1039 r.in.user_handle = user_handle;
1042 status = dcerpc_samr_GetGroupsForUser(p, tctx, &r);
1043 torture_assert_ntstatus_ok(tctx, status, "GetGroupsForUser");
1049 static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1050 struct lsa_String *domain_name)
1053 struct samr_GetDomPwInfo r;
1054 struct samr_PwInfo info;
1056 r.in.domain_name = domain_name;
1059 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1061 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1062 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1064 r.in.domain_name->string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1065 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1067 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1068 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1070 r.in.domain_name->string = "\\\\__NONAME__";
1071 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1073 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1074 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1076 r.in.domain_name->string = "\\\\Builtin";
1077 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1079 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1080 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1085 static bool test_GetUserPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1086 struct policy_handle *handle)
1089 struct samr_GetUserPwInfo r;
1090 struct samr_PwInfo info;
1092 torture_comment(tctx, "Testing GetUserPwInfo\n");
1094 r.in.user_handle = handle;
1097 status = dcerpc_samr_GetUserPwInfo(p, tctx, &r);
1098 torture_assert_ntstatus_ok(tctx, status, "GetUserPwInfo");
1103 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, struct torture_context *tctx,
1104 struct policy_handle *domain_handle, const char *name,
1108 struct samr_LookupNames n;
1109 struct lsa_String sname[2];
1110 struct samr_Ids rids, types;
1112 init_lsa_String(&sname[0], name);
1114 n.in.domain_handle = domain_handle;
1118 n.out.types = &types;
1119 status = dcerpc_samr_LookupNames(p, tctx, &n);
1120 if (NT_STATUS_IS_OK(status)) {
1121 *rid = n.out.rids->ids[0];
1126 init_lsa_String(&sname[1], "xxNONAMExx");
1128 status = dcerpc_samr_LookupNames(p, tctx, &n);
1129 if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
1130 printf("LookupNames[2] failed - %s\n", nt_errstr(status));
1131 if (NT_STATUS_IS_OK(status)) {
1132 return NT_STATUS_UNSUCCESSFUL;
1138 status = dcerpc_samr_LookupNames(p, tctx, &n);
1139 if (!NT_STATUS_IS_OK(status)) {
1140 printf("LookupNames[0] failed - %s\n", nt_errstr(status));
1144 init_lsa_String(&sname[0], "xxNONAMExx");
1146 status = dcerpc_samr_LookupNames(p, tctx, &n);
1147 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1148 printf("LookupNames[1 bad name] failed - %s\n", nt_errstr(status));
1149 if (NT_STATUS_IS_OK(status)) {
1150 return NT_STATUS_UNSUCCESSFUL;
1155 init_lsa_String(&sname[0], "xxNONAMExx");
1156 init_lsa_String(&sname[1], "xxNONAME2xx");
1158 status = dcerpc_samr_LookupNames(p, tctx, &n);
1159 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1160 printf("LookupNames[2 bad names] failed - %s\n", nt_errstr(status));
1161 if (NT_STATUS_IS_OK(status)) {
1162 return NT_STATUS_UNSUCCESSFUL;
1167 return NT_STATUS_OK;
1170 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1171 struct policy_handle *domain_handle,
1172 const char *name, struct policy_handle *user_handle)
1175 struct samr_OpenUser r;
1178 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
1179 if (!NT_STATUS_IS_OK(status)) {
1183 r.in.domain_handle = domain_handle;
1184 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1186 r.out.user_handle = user_handle;
1187 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
1188 if (!NT_STATUS_IS_OK(status)) {
1189 printf("OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(status));
1196 static bool test_ChangePasswordNT3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1197 struct policy_handle *handle)
1200 struct samr_ChangePasswordUser r;
1202 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1203 struct policy_handle user_handle;
1204 char *oldpass = "test";
1205 char *newpass = "test2";
1206 uint8_t old_nt_hash[16], new_nt_hash[16];
1207 uint8_t old_lm_hash[16], new_lm_hash[16];
1209 status = test_OpenUser_byname(p, mem_ctx, handle, "testuser", &user_handle);
1210 if (!NT_STATUS_IS_OK(status)) {
1214 printf("Testing ChangePasswordUser for user 'testuser'\n");
1216 printf("old password: %s\n", oldpass);
1217 printf("new password: %s\n", newpass);
1219 E_md4hash(oldpass, old_nt_hash);
1220 E_md4hash(newpass, new_nt_hash);
1221 E_deshash(oldpass, old_lm_hash);
1222 E_deshash(newpass, new_lm_hash);
1224 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1225 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1226 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1227 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1228 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1229 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1231 r.in.handle = &user_handle;
1232 r.in.lm_present = 1;
1233 r.in.old_lm_crypted = &hash1;
1234 r.in.new_lm_crypted = &hash2;
1235 r.in.nt_present = 1;
1236 r.in.old_nt_crypted = &hash3;
1237 r.in.new_nt_crypted = &hash4;
1238 r.in.cross1_present = 1;
1239 r.in.nt_cross = &hash5;
1240 r.in.cross2_present = 1;
1241 r.in.lm_cross = &hash6;
1243 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1244 if (!NT_STATUS_IS_OK(status)) {
1245 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1249 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1257 static bool test_ChangePasswordUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1258 const char *acct_name,
1259 struct policy_handle *handle, char **password)
1262 struct samr_ChangePasswordUser r;
1264 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1265 struct policy_handle user_handle;
1267 uint8_t old_nt_hash[16], new_nt_hash[16];
1268 uint8_t old_lm_hash[16], new_lm_hash[16];
1269 bool changed = true;
1272 struct samr_GetUserPwInfo pwp;
1273 struct samr_PwInfo info;
1274 int policy_min_pw_len = 0;
1276 status = test_OpenUser_byname(p, tctx, handle, acct_name, &user_handle);
1277 if (!NT_STATUS_IS_OK(status)) {
1280 pwp.in.user_handle = &user_handle;
1281 pwp.out.info = &info;
1283 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1284 if (NT_STATUS_IS_OK(status)) {
1285 policy_min_pw_len = pwp.out.info->min_password_length;
1287 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1289 torture_comment(tctx, "Testing ChangePasswordUser\n");
1291 torture_assert(tctx, *password != NULL,
1292 "Failing ChangePasswordUser as old password was NULL. Previous test failed?");
1294 oldpass = *password;
1296 E_md4hash(oldpass, old_nt_hash);
1297 E_md4hash(newpass, new_nt_hash);
1298 E_deshash(oldpass, old_lm_hash);
1299 E_deshash(newpass, new_lm_hash);
1301 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1302 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1303 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1304 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1305 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1306 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1308 r.in.user_handle = &user_handle;
1309 r.in.lm_present = 1;
1310 /* Break the LM hash */
1312 r.in.old_lm_crypted = &hash1;
1313 r.in.new_lm_crypted = &hash2;
1314 r.in.nt_present = 1;
1315 r.in.old_nt_crypted = &hash3;
1316 r.in.new_nt_crypted = &hash4;
1317 r.in.cross1_present = 1;
1318 r.in.nt_cross = &hash5;
1319 r.in.cross2_present = 1;
1320 r.in.lm_cross = &hash6;
1322 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1323 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1324 "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash");
1326 /* Unbreak the LM hash */
1329 r.in.user_handle = &user_handle;
1330 r.in.lm_present = 1;
1331 r.in.old_lm_crypted = &hash1;
1332 r.in.new_lm_crypted = &hash2;
1333 /* Break the NT hash */
1335 r.in.nt_present = 1;
1336 r.in.old_nt_crypted = &hash3;
1337 r.in.new_nt_crypted = &hash4;
1338 r.in.cross1_present = 1;
1339 r.in.nt_cross = &hash5;
1340 r.in.cross2_present = 1;
1341 r.in.lm_cross = &hash6;
1343 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1344 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1345 "expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash");
1347 /* Unbreak the NT hash */
1350 r.in.user_handle = &user_handle;
1351 r.in.lm_present = 1;
1352 r.in.old_lm_crypted = &hash1;
1353 r.in.new_lm_crypted = &hash2;
1354 r.in.nt_present = 1;
1355 r.in.old_nt_crypted = &hash3;
1356 r.in.new_nt_crypted = &hash4;
1357 r.in.cross1_present = 1;
1358 r.in.nt_cross = &hash5;
1359 r.in.cross2_present = 1;
1360 /* Break the LM cross */
1362 r.in.lm_cross = &hash6;
1364 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1365 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1366 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status));
1370 /* Unbreak the LM cross */
1373 r.in.user_handle = &user_handle;
1374 r.in.lm_present = 1;
1375 r.in.old_lm_crypted = &hash1;
1376 r.in.new_lm_crypted = &hash2;
1377 r.in.nt_present = 1;
1378 r.in.old_nt_crypted = &hash3;
1379 r.in.new_nt_crypted = &hash4;
1380 r.in.cross1_present = 1;
1381 /* Break the NT cross */
1383 r.in.nt_cross = &hash5;
1384 r.in.cross2_present = 1;
1385 r.in.lm_cross = &hash6;
1387 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1388 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1389 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status));
1393 /* Unbreak the NT cross */
1397 /* Reset the hashes to not broken values */
1398 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1399 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1400 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1401 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1402 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1403 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1405 r.in.user_handle = &user_handle;
1406 r.in.lm_present = 1;
1407 r.in.old_lm_crypted = &hash1;
1408 r.in.new_lm_crypted = &hash2;
1409 r.in.nt_present = 1;
1410 r.in.old_nt_crypted = &hash3;
1411 r.in.new_nt_crypted = &hash4;
1412 r.in.cross1_present = 1;
1413 r.in.nt_cross = &hash5;
1414 r.in.cross2_present = 0;
1415 r.in.lm_cross = NULL;
1417 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1418 if (NT_STATUS_IS_OK(status)) {
1420 *password = newpass;
1421 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1422 printf("ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(status));
1427 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1429 E_md4hash(oldpass, old_nt_hash);
1430 E_md4hash(newpass, new_nt_hash);
1431 E_deshash(oldpass, old_lm_hash);
1432 E_deshash(newpass, new_lm_hash);
1435 /* Reset the hashes to not broken values */
1436 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1437 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1438 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1439 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1440 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1441 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1443 r.in.user_handle = &user_handle;
1444 r.in.lm_present = 1;
1445 r.in.old_lm_crypted = &hash1;
1446 r.in.new_lm_crypted = &hash2;
1447 r.in.nt_present = 1;
1448 r.in.old_nt_crypted = &hash3;
1449 r.in.new_nt_crypted = &hash4;
1450 r.in.cross1_present = 0;
1451 r.in.nt_cross = NULL;
1452 r.in.cross2_present = 1;
1453 r.in.lm_cross = &hash6;
1455 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1456 if (NT_STATUS_IS_OK(status)) {
1458 *password = newpass;
1459 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1460 printf("ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status));
1465 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1467 E_md4hash(oldpass, old_nt_hash);
1468 E_md4hash(newpass, new_nt_hash);
1469 E_deshash(oldpass, old_lm_hash);
1470 E_deshash(newpass, new_lm_hash);
1473 /* Reset the hashes to not broken values */
1474 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1475 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1476 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1477 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1478 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1479 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1481 r.in.user_handle = &user_handle;
1482 r.in.lm_present = 1;
1483 r.in.old_lm_crypted = &hash1;
1484 r.in.new_lm_crypted = &hash2;
1485 r.in.nt_present = 1;
1486 r.in.old_nt_crypted = &hash3;
1487 r.in.new_nt_crypted = &hash4;
1488 r.in.cross1_present = 1;
1489 r.in.nt_cross = &hash5;
1490 r.in.cross2_present = 1;
1491 r.in.lm_cross = &hash6;
1493 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1494 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1495 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1496 } else if (!NT_STATUS_IS_OK(status)) {
1497 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1501 *password = newpass;
1504 r.in.user_handle = &user_handle;
1505 r.in.lm_present = 1;
1506 r.in.old_lm_crypted = &hash1;
1507 r.in.new_lm_crypted = &hash2;
1508 r.in.nt_present = 1;
1509 r.in.old_nt_crypted = &hash3;
1510 r.in.new_nt_crypted = &hash4;
1511 r.in.cross1_present = 1;
1512 r.in.nt_cross = &hash5;
1513 r.in.cross2_present = 1;
1514 r.in.lm_cross = &hash6;
1517 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1518 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1519 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1520 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1521 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status));
1527 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
1535 static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
1536 const char *acct_name,
1537 struct policy_handle *handle, char **password)
1540 struct samr_OemChangePasswordUser2 r;
1542 struct samr_Password lm_verifier;
1543 struct samr_CryptPassword lm_pass;
1544 struct lsa_AsciiString server, account, account_bad;
1547 uint8_t old_lm_hash[16], new_lm_hash[16];
1549 struct samr_GetDomPwInfo dom_pw_info;
1550 struct samr_PwInfo info;
1551 int policy_min_pw_len = 0;
1553 struct lsa_String domain_name;
1555 domain_name.string = "";
1556 dom_pw_info.in.domain_name = &domain_name;
1557 dom_pw_info.out.info = &info;
1559 torture_comment(tctx, "Testing OemChangePasswordUser2\n");
1561 torture_assert(tctx, *password != NULL,
1562 "Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?");
1564 oldpass = *password;
1566 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
1567 if (NT_STATUS_IS_OK(status)) {
1568 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
1571 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1573 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1574 account.string = acct_name;
1576 E_deshash(oldpass, old_lm_hash);
1577 E_deshash(newpass, new_lm_hash);
1579 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1580 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1581 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1583 r.in.server = &server;
1584 r.in.account = &account;
1585 r.in.password = &lm_pass;
1586 r.in.hash = &lm_verifier;
1588 /* Break the verification */
1589 lm_verifier.hash[0]++;
1591 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1593 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1594 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1595 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1600 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1601 /* Break the old password */
1603 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1604 /* unbreak it for the next operation */
1606 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1608 r.in.server = &server;
1609 r.in.account = &account;
1610 r.in.password = &lm_pass;
1611 r.in.hash = &lm_verifier;
1613 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1615 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1616 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1617 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1622 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1623 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1625 r.in.server = &server;
1626 r.in.account = &account;
1627 r.in.password = &lm_pass;
1630 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1632 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1633 && !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1634 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
1639 /* This shouldn't be a valid name */
1640 account_bad.string = TEST_ACCOUNT_NAME "XX";
1641 r.in.account = &account_bad;
1643 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1645 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1646 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
1651 /* This shouldn't be a valid name */
1652 account_bad.string = TEST_ACCOUNT_NAME "XX";
1653 r.in.account = &account_bad;
1654 r.in.password = &lm_pass;
1655 r.in.hash = &lm_verifier;
1657 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1659 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1660 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1665 /* This shouldn't be a valid name */
1666 account_bad.string = TEST_ACCOUNT_NAME "XX";
1667 r.in.account = &account_bad;
1668 r.in.password = NULL;
1669 r.in.hash = &lm_verifier;
1671 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1673 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1674 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
1679 E_deshash(oldpass, old_lm_hash);
1680 E_deshash(newpass, new_lm_hash);
1682 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1683 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1684 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1686 r.in.server = &server;
1687 r.in.account = &account;
1688 r.in.password = &lm_pass;
1689 r.in.hash = &lm_verifier;
1691 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1692 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1693 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1694 } else if (!NT_STATUS_IS_OK(status)) {
1695 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
1698 *password = newpass;
1705 static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
1706 const char *acct_name,
1708 char *newpass, bool allow_password_restriction)
1711 struct samr_ChangePasswordUser2 r;
1713 struct lsa_String server, account;
1714 struct samr_CryptPassword nt_pass, lm_pass;
1715 struct samr_Password nt_verifier, lm_verifier;
1717 uint8_t old_nt_hash[16], new_nt_hash[16];
1718 uint8_t old_lm_hash[16], new_lm_hash[16];
1720 struct samr_GetDomPwInfo dom_pw_info;
1721 struct samr_PwInfo info;
1723 struct lsa_String domain_name;
1725 domain_name.string = "";
1726 dom_pw_info.in.domain_name = &domain_name;
1727 dom_pw_info.out.info = &info;
1729 torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name);
1731 torture_assert(tctx, *password != NULL,
1732 "Failing ChangePasswordUser2 as old password was NULL. Previous test failed?");
1733 oldpass = *password;
1736 int policy_min_pw_len = 0;
1737 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
1738 if (NT_STATUS_IS_OK(status)) {
1739 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
1742 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1745 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1746 init_lsa_String(&account, acct_name);
1748 E_md4hash(oldpass, old_nt_hash);
1749 E_md4hash(newpass, new_nt_hash);
1751 E_deshash(oldpass, old_lm_hash);
1752 E_deshash(newpass, new_lm_hash);
1754 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
1755 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1756 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1758 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1759 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1760 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1762 r.in.server = &server;
1763 r.in.account = &account;
1764 r.in.nt_password = &nt_pass;
1765 r.in.nt_verifier = &nt_verifier;
1767 r.in.lm_password = &lm_pass;
1768 r.in.lm_verifier = &lm_verifier;
1770 status = dcerpc_samr_ChangePasswordUser2(p, tctx, &r);
1771 if (allow_password_restriction && NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1772 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1773 } else if (!NT_STATUS_IS_OK(status)) {
1774 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
1777 *password = newpass;
1784 bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tctx,
1785 const char *account_string,
1786 int policy_min_pw_len,
1788 const char *newpass,
1789 NTTIME last_password_change,
1790 bool handle_reject_reason)
1793 struct samr_ChangePasswordUser3 r;
1795 struct lsa_String server, account, account_bad;
1796 struct samr_CryptPassword nt_pass, lm_pass;
1797 struct samr_Password nt_verifier, lm_verifier;
1799 uint8_t old_nt_hash[16], new_nt_hash[16];
1800 uint8_t old_lm_hash[16], new_lm_hash[16];
1802 struct samr_DomInfo1 *dominfo = NULL;
1803 struct samr_ChangeReject *reject = NULL;
1805 torture_comment(tctx, "Testing ChangePasswordUser3\n");
1807 if (newpass == NULL) {
1809 if (policy_min_pw_len == 0) {
1810 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1812 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len);
1814 } while (check_password_quality(newpass) == false);
1816 torture_comment(tctx, "Using password '%s'\n", newpass);
1819 torture_assert(tctx, *password != NULL,
1820 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
1822 oldpass = *password;
1823 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1824 init_lsa_String(&account, account_string);
1826 E_md4hash(oldpass, old_nt_hash);
1827 E_md4hash(newpass, new_nt_hash);
1829 E_deshash(oldpass, old_lm_hash);
1830 E_deshash(newpass, new_lm_hash);
1832 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1833 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1834 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1836 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1837 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1838 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1840 /* Break the verification */
1841 nt_verifier.hash[0]++;
1843 r.in.server = &server;
1844 r.in.account = &account;
1845 r.in.nt_password = &nt_pass;
1846 r.in.nt_verifier = &nt_verifier;
1848 r.in.lm_password = &lm_pass;
1849 r.in.lm_verifier = &lm_verifier;
1850 r.in.password3 = NULL;
1851 r.out.dominfo = &dominfo;
1852 r.out.reject = &reject;
1854 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1855 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1856 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1857 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1862 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1863 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1864 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1866 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1867 /* Break the NT hash */
1869 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1870 /* Unbreak it again */
1872 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1874 r.in.server = &server;
1875 r.in.account = &account;
1876 r.in.nt_password = &nt_pass;
1877 r.in.nt_verifier = &nt_verifier;
1879 r.in.lm_password = &lm_pass;
1880 r.in.lm_verifier = &lm_verifier;
1881 r.in.password3 = NULL;
1882 r.out.dominfo = &dominfo;
1883 r.out.reject = &reject;
1885 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1886 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1887 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1888 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1893 /* This shouldn't be a valid name */
1894 init_lsa_String(&account_bad, talloc_asprintf(tctx, "%sXX", account_string));
1896 r.in.account = &account_bad;
1897 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1898 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1899 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
1904 E_md4hash(oldpass, old_nt_hash);
1905 E_md4hash(newpass, new_nt_hash);
1907 E_deshash(oldpass, old_lm_hash);
1908 E_deshash(newpass, new_lm_hash);
1910 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1911 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1912 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1914 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1915 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1916 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1918 r.in.server = &server;
1919 r.in.account = &account;
1920 r.in.nt_password = &nt_pass;
1921 r.in.nt_verifier = &nt_verifier;
1923 r.in.lm_password = &lm_pass;
1924 r.in.lm_verifier = &lm_verifier;
1925 r.in.password3 = NULL;
1926 r.out.dominfo = &dominfo;
1927 r.out.reject = &reject;
1929 unix_to_nt_time(&t, time(NULL));
1931 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1933 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1936 && handle_reject_reason
1937 && (!null_nttime(last_password_change) || !dominfo->min_password_age)) {
1938 if (dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
1940 if (reject && (reject->reason != SAMR_REJECT_OTHER)) {
1941 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1942 SAMR_REJECT_OTHER, reject->reason);
1947 /* We tested the order of precendence which is as follows:
1956 if ((dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
1957 (last_password_change + dominfo->min_password_age > t)) {
1959 if (reject->reason != SAMR_REJECT_OTHER) {
1960 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1961 SAMR_REJECT_OTHER, reject->reason);
1965 } else if ((dominfo->min_password_length > 0) &&
1966 (strlen(newpass) < dominfo->min_password_length)) {
1968 if (reject->reason != SAMR_REJECT_TOO_SHORT) {
1969 printf("expected SAMR_REJECT_TOO_SHORT (%d), got %d\n",
1970 SAMR_REJECT_TOO_SHORT, reject->reason);
1974 } else if ((dominfo->password_history_length > 0) &&
1975 strequal(oldpass, newpass)) {
1977 if (reject->reason != SAMR_REJECT_IN_HISTORY) {
1978 printf("expected SAMR_REJECT_IN_HISTORY (%d), got %d\n",
1979 SAMR_REJECT_IN_HISTORY, reject->reason);
1982 } else if (dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
1984 if (reject->reason != SAMR_REJECT_COMPLEXITY) {
1985 printf("expected SAMR_REJECT_COMPLEXITY (%d), got %d\n",
1986 SAMR_REJECT_COMPLEXITY, reject->reason);
1992 if (reject->reason == SAMR_REJECT_TOO_SHORT) {
1993 /* retry with adjusted size */
1994 return test_ChangePasswordUser3(p, tctx, account_string,
1995 dominfo->min_password_length,
1996 password, NULL, 0, false);
2000 } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2001 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2002 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2003 SAMR_REJECT_OTHER, reject->reason);
2006 /* Perhaps the server has a 'min password age' set? */
2009 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3");
2010 *password = talloc_strdup(tctx, newpass);
2016 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_context *tctx,
2017 const char *account_string,
2018 struct policy_handle *handle,
2022 struct samr_ChangePasswordUser3 r;
2023 struct samr_SetUserInfo s;
2024 union samr_UserInfo u;
2025 DATA_BLOB session_key;
2026 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
2027 uint8_t confounder[16];
2028 struct MD5Context ctx;
2031 struct lsa_String server, account;
2032 struct samr_CryptPassword nt_pass;
2033 struct samr_Password nt_verifier;
2034 DATA_BLOB new_random_pass;
2037 uint8_t old_nt_hash[16], new_nt_hash[16];
2039 struct samr_DomInfo1 *dominfo = NULL;
2040 struct samr_ChangeReject *reject = NULL;
2042 new_random_pass = samr_very_rand_pass(tctx, 128);
2044 torture_assert(tctx, *password != NULL,
2045 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2047 oldpass = *password;
2048 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2049 init_lsa_String(&account, account_string);
2051 s.in.user_handle = handle;
2057 u.info25.info.fields_present = SAMR_FIELD_PASSWORD;
2059 set_pw_in_buffer(u.info25.password.data, &new_random_pass);
2061 status = dcerpc_fetch_session_key(p, &session_key);
2062 if (!NT_STATUS_IS_OK(status)) {
2063 printf("SetUserInfo level %u - no session key - %s\n",
2064 s.in.level, nt_errstr(status));
2068 generate_random_buffer((uint8_t *)confounder, 16);
2071 MD5Update(&ctx, confounder, 16);
2072 MD5Update(&ctx, session_key.data, session_key.length);
2073 MD5Final(confounded_session_key.data, &ctx);
2075 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
2076 memcpy(&u.info25.password.data[516], confounder, 16);
2078 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
2080 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
2081 if (!NT_STATUS_IS_OK(status)) {
2082 printf("SetUserInfo level %u failed - %s\n",
2083 s.in.level, nt_errstr(status));
2087 torture_comment(tctx, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
2089 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2091 new_random_pass = samr_very_rand_pass(tctx, 128);
2093 mdfour(new_nt_hash, new_random_pass.data, new_random_pass.length);
2095 set_pw_in_buffer(nt_pass.data, &new_random_pass);
2096 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2097 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2099 r.in.server = &server;
2100 r.in.account = &account;
2101 r.in.nt_password = &nt_pass;
2102 r.in.nt_verifier = &nt_verifier;
2104 r.in.lm_password = NULL;
2105 r.in.lm_verifier = NULL;
2106 r.in.password3 = NULL;
2107 r.out.dominfo = &dominfo;
2108 r.out.reject = &reject;
2110 unix_to_nt_time(&t, time(NULL));
2112 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2114 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2115 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2116 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2117 SAMR_REJECT_OTHER, reject->reason);
2120 /* Perhaps the server has a 'min password age' set? */
2122 } else if (!NT_STATUS_IS_OK(status)) {
2123 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
2127 newpass = samr_rand_pass(tctx, 128);
2129 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2131 E_md4hash(newpass, new_nt_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 r.in.server = &server;
2138 r.in.account = &account;
2139 r.in.nt_password = &nt_pass;
2140 r.in.nt_verifier = &nt_verifier;
2142 r.in.lm_password = NULL;
2143 r.in.lm_verifier = NULL;
2144 r.in.password3 = NULL;
2145 r.out.dominfo = &dominfo;
2146 r.out.reject = &reject;
2148 unix_to_nt_time(&t, time(NULL));
2150 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2152 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2153 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2154 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2155 SAMR_REJECT_OTHER, reject->reason);
2158 /* Perhaps the server has a 'min password age' set? */
2161 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3 (on second random password)");
2162 *password = talloc_strdup(tctx, newpass);
2169 static bool test_GetMembersInAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2170 struct policy_handle *alias_handle)
2172 struct samr_GetMembersInAlias r;
2173 struct lsa_SidArray sids;
2176 torture_comment(tctx, "Testing GetMembersInAlias\n");
2178 r.in.alias_handle = alias_handle;
2181 status = dcerpc_samr_GetMembersInAlias(p, tctx, &r);
2182 torture_assert_ntstatus_ok(tctx, status, "GetMembersInAlias");
2187 static bool test_AddMemberToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2188 struct policy_handle *alias_handle,
2189 const struct dom_sid *domain_sid)
2191 struct samr_AddAliasMember r;
2192 struct samr_DeleteAliasMember d;
2194 struct dom_sid *sid;
2196 sid = dom_sid_add_rid(tctx, domain_sid, 512);
2198 torture_comment(tctx, "testing AddAliasMember\n");
2199 r.in.alias_handle = alias_handle;
2202 status = dcerpc_samr_AddAliasMember(p, tctx, &r);
2203 torture_assert_ntstatus_ok(tctx, status, "AddAliasMember");
2205 d.in.alias_handle = alias_handle;
2208 status = dcerpc_samr_DeleteAliasMember(p, tctx, &d);
2209 torture_assert_ntstatus_ok(tctx, status, "DelAliasMember");
2214 static bool test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2215 struct policy_handle *alias_handle)
2217 struct samr_AddMultipleMembersToAlias a;
2218 struct samr_RemoveMultipleMembersFromAlias r;
2220 struct lsa_SidArray sids;
2222 torture_comment(tctx, "testing AddMultipleMembersToAlias\n");
2223 a.in.alias_handle = alias_handle;
2227 sids.sids = talloc_array(tctx, struct lsa_SidPtr, 3);
2229 sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2230 sids.sids[1].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-2");
2231 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-3");
2233 status = dcerpc_samr_AddMultipleMembersToAlias(p, tctx, &a);
2234 torture_assert_ntstatus_ok(tctx, status, "AddMultipleMembersToAlias");
2237 torture_comment(tctx, "testing RemoveMultipleMembersFromAlias\n");
2238 r.in.alias_handle = alias_handle;
2241 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2242 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2244 /* strange! removing twice doesn't give any error */
2245 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2246 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2248 /* but removing an alias that isn't there does */
2249 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-4");
2251 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2252 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, "RemoveMultipleMembersFromAlias");
2257 static bool test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2258 struct policy_handle *user_handle)
2260 struct samr_TestPrivateFunctionsUser r;
2263 torture_comment(tctx, "Testing TestPrivateFunctionsUser\n");
2265 r.in.user_handle = user_handle;
2267 status = dcerpc_samr_TestPrivateFunctionsUser(p, tctx, &r);
2268 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsUser");
2274 static bool test_user_ops(struct dcerpc_pipe *p,
2275 struct torture_context *tctx,
2276 struct policy_handle *user_handle,
2277 struct policy_handle *domain_handle,
2278 uint32_t base_acct_flags,
2279 const char *base_acct_name, enum torture_samr_choice which_ops)
2281 char *password = NULL;
2282 struct samr_QueryUserInfo q;
2283 union samr_UserInfo *info;
2289 const uint32_t password_fields[] = {
2290 SAMR_FIELD_PASSWORD,
2291 SAMR_FIELD_PASSWORD2,
2292 SAMR_FIELD_PASSWORD | SAMR_FIELD_PASSWORD2,
2296 status = test_LookupName(p, tctx, domain_handle, base_acct_name, &rid);
2297 if (!NT_STATUS_IS_OK(status)) {
2301 switch (which_ops) {
2302 case TORTURE_SAMR_USER_ATTRIBUTES:
2303 if (!test_QuerySecurity(p, tctx, user_handle)) {
2307 if (!test_QueryUserInfo(p, tctx, user_handle)) {
2311 if (!test_QueryUserInfo2(p, tctx, user_handle)) {
2315 if (!test_SetUserInfo(p, tctx, user_handle, base_acct_flags,
2320 if (!test_GetUserPwInfo(p, tctx, user_handle)) {
2324 if (!test_TestPrivateFunctionsUser(p, tctx, user_handle)) {
2328 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
2332 case TORTURE_SAMR_PASSWORDS:
2333 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
2334 char simple_pass[9];
2335 char *v = generate_random_str(tctx, 1);
2337 ZERO_STRUCT(simple_pass);
2338 memset(simple_pass, *v, sizeof(simple_pass) - 1);
2340 printf("Testing machine account password policy rules\n");
2342 /* Workstation trust accounts don't seem to need to honour password quality policy */
2343 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
2347 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
2351 /* reset again, to allow another 'user' password change */
2352 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
2356 /* Try a 'short' password */
2357 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
2361 /* Try a compleatly random password */
2362 if (!test_ChangePasswordRandomBytes(p, tctx, base_acct_name, user_handle, &password)) {
2367 for (i = 0; password_fields[i]; i++) {
2368 if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
2372 /* check it was set right */
2373 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
2378 for (i = 0; password_fields[i]; i++) {
2379 if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
2383 /* check it was set right */
2384 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
2389 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
2393 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
2397 q.in.user_handle = user_handle;
2401 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
2402 if (!NT_STATUS_IS_OK(status)) {
2403 printf("QueryUserInfo level %u failed - %s\n",
2404 q.in.level, nt_errstr(status));
2407 uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
2408 if ((info->info5.acct_flags) != expected_flags) {
2409 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2410 info->info5.acct_flags,
2414 if (info->info5.rid != rid) {
2415 printf("QuerUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
2416 info->info5.rid, rid);
2422 case TORTURE_SAMR_OTHER:
2423 /* We just need the account to exist */
2429 static bool test_alias_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
2430 struct policy_handle *alias_handle,
2431 const struct dom_sid *domain_sid)
2435 if (!test_QuerySecurity(p, tctx, alias_handle)) {
2439 if (!test_QueryAliasInfo(p, tctx, alias_handle)) {
2443 if (!test_SetAliasInfo(p, tctx, alias_handle)) {
2447 if (!test_AddMemberToAlias(p, tctx, alias_handle, domain_sid)) {
2451 if (torture_setting_bool(tctx, "samba4", false)) {
2452 printf("skipping MultipleMembers Alias tests against Samba4\n");
2456 if (!test_AddMultipleMembersToAlias(p, tctx, alias_handle)) {
2464 static bool test_DeleteUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2465 struct policy_handle *user_handle)
2467 struct samr_DeleteUser d;
2469 torture_comment(tctx, "Testing DeleteUser\n");
2471 d.in.user_handle = user_handle;
2472 d.out.user_handle = user_handle;
2474 status = dcerpc_samr_DeleteUser(p, tctx, &d);
2475 torture_assert_ntstatus_ok(tctx, status, "DeleteUser");
2480 bool test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2481 struct policy_handle *handle, const char *name)
2484 struct samr_DeleteUser d;
2485 struct policy_handle user_handle;
2488 status = test_LookupName(p, mem_ctx, handle, name, &rid);
2489 if (!NT_STATUS_IS_OK(status)) {
2493 status = test_OpenUser_byname(p, mem_ctx, handle, name, &user_handle);
2494 if (!NT_STATUS_IS_OK(status)) {
2498 d.in.user_handle = &user_handle;
2499 d.out.user_handle = &user_handle;
2500 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
2501 if (!NT_STATUS_IS_OK(status)) {
2508 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
2513 static bool test_DeleteGroup_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2514 struct policy_handle *handle, const char *name)
2517 struct samr_OpenGroup r;
2518 struct samr_DeleteDomainGroup d;
2519 struct policy_handle group_handle;
2522 status = test_LookupName(p, mem_ctx, handle, name, &rid);
2523 if (!NT_STATUS_IS_OK(status)) {
2527 r.in.domain_handle = handle;
2528 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2530 r.out.group_handle = &group_handle;
2531 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
2532 if (!NT_STATUS_IS_OK(status)) {
2536 d.in.group_handle = &group_handle;
2537 d.out.group_handle = &group_handle;
2538 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
2539 if (!NT_STATUS_IS_OK(status)) {
2546 printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
2551 static bool test_DeleteAlias_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2552 struct policy_handle *domain_handle, const char *name)
2555 struct samr_OpenAlias r;
2556 struct samr_DeleteDomAlias d;
2557 struct policy_handle alias_handle;
2560 printf("testing DeleteAlias_byname\n");
2562 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
2563 if (!NT_STATUS_IS_OK(status)) {
2567 r.in.domain_handle = domain_handle;
2568 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2570 r.out.alias_handle = &alias_handle;
2571 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
2572 if (!NT_STATUS_IS_OK(status)) {
2576 d.in.alias_handle = &alias_handle;
2577 d.out.alias_handle = &alias_handle;
2578 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
2579 if (!NT_STATUS_IS_OK(status)) {
2586 printf("DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
2590 static bool test_DeleteAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2591 struct policy_handle *alias_handle)
2593 struct samr_DeleteDomAlias d;
2596 printf("Testing DeleteAlias\n");
2598 d.in.alias_handle = alias_handle;
2599 d.out.alias_handle = alias_handle;
2601 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
2602 if (!NT_STATUS_IS_OK(status)) {
2603 printf("DeleteAlias failed - %s\n", nt_errstr(status));
2610 static bool test_CreateAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2611 struct policy_handle *domain_handle,
2612 struct policy_handle *alias_handle,
2613 const struct dom_sid *domain_sid)
2616 struct samr_CreateDomAlias r;
2617 struct lsa_String name;
2621 init_lsa_String(&name, TEST_ALIASNAME);
2622 r.in.domain_handle = domain_handle;
2623 r.in.alias_name = &name;
2624 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2625 r.out.alias_handle = alias_handle;
2628 printf("Testing CreateAlias (%s)\n", r.in.alias_name->string);
2630 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
2632 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
2633 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2634 printf("Server correctly refused create of '%s'\n", r.in.alias_name->string);
2637 printf("Server should have refused create of '%s', got %s instead\n", r.in.alias_name->string,
2643 if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
2644 if (!test_DeleteAlias_byname(p, tctx, domain_handle, r.in.alias_name->string)) {
2647 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
2650 if (!NT_STATUS_IS_OK(status)) {
2651 printf("CreateAlias failed - %s\n", nt_errstr(status));
2655 if (!test_alias_ops(p, tctx, alias_handle, domain_sid)) {
2662 static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2663 const char *acct_name,
2664 struct policy_handle *domain_handle, char **password)
2672 if (!test_ChangePasswordUser(p, mem_ctx, acct_name, domain_handle, password)) {
2676 if (!test_ChangePasswordUser2(p, mem_ctx, acct_name, password, 0, true)) {
2680 if (!test_OemChangePasswordUser2(p, mem_ctx, acct_name, domain_handle, password)) {
2684 /* test what happens when setting the old password again */
2685 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, *password, 0, true)) {
2690 char simple_pass[9];
2691 char *v = generate_random_str(mem_ctx, 1);
2693 ZERO_STRUCT(simple_pass);
2694 memset(simple_pass, *v, sizeof(simple_pass) - 1);
2696 /* test what happens when picking a simple password */
2697 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, simple_pass, 0, true)) {
2702 /* set samr_SetDomainInfo level 1 with min_length 5 */
2704 struct samr_QueryDomainInfo r;
2705 union samr_DomainInfo *info = NULL;
2706 struct samr_SetDomainInfo s;
2707 uint16_t len_old, len;
2708 uint32_t pwd_prop_old;
2709 int64_t min_pwd_age_old;
2714 r.in.domain_handle = domain_handle;
2718 printf("testing samr_QueryDomainInfo level 1\n");
2719 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2720 if (!NT_STATUS_IS_OK(status)) {
2724 s.in.domain_handle = domain_handle;
2728 /* remember the old min length, so we can reset it */
2729 len_old = s.in.info->info1.min_password_length;
2730 s.in.info->info1.min_password_length = len;
2731 pwd_prop_old = s.in.info->info1.password_properties;
2732 /* turn off password complexity checks for this test */
2733 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
2735 min_pwd_age_old = s.in.info->info1.min_password_age;
2736 s.in.info->info1.min_password_age = 0;
2738 printf("testing samr_SetDomainInfo level 1\n");
2739 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2740 if (!NT_STATUS_IS_OK(status)) {
2744 printf("calling test_ChangePasswordUser3 with too short password\n");
2746 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, len - 1, password, NULL, 0, true)) {
2750 s.in.info->info1.min_password_length = len_old;
2751 s.in.info->info1.password_properties = pwd_prop_old;
2752 s.in.info->info1.min_password_age = min_pwd_age_old;
2754 printf("testing samr_SetDomainInfo level 1\n");
2755 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2756 if (!NT_STATUS_IS_OK(status)) {
2764 struct samr_OpenUser r;
2765 struct samr_QueryUserInfo q;
2766 union samr_UserInfo *info;
2767 struct samr_LookupNames n;
2768 struct policy_handle user_handle;
2769 struct samr_Ids rids, types;
2771 n.in.domain_handle = domain_handle;
2773 n.in.names = talloc_array(mem_ctx, struct lsa_String, 1);
2774 n.in.names[0].string = acct_name;
2776 n.out.types = &types;
2778 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
2779 if (!NT_STATUS_IS_OK(status)) {
2780 printf("LookupNames failed - %s\n", nt_errstr(status));
2784 r.in.domain_handle = domain_handle;
2785 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2786 r.in.rid = n.out.rids->ids[0];
2787 r.out.user_handle = &user_handle;
2789 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
2790 if (!NT_STATUS_IS_OK(status)) {
2791 printf("OpenUser(%u) failed - %s\n", n.out.rids->ids[0], nt_errstr(status));
2795 q.in.user_handle = &user_handle;
2799 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
2800 if (!NT_STATUS_IS_OK(status)) {
2801 printf("QueryUserInfo failed - %s\n", nt_errstr(status));
2805 printf("calling test_ChangePasswordUser3 with too early password change\n");
2807 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL,
2808 info->info5.last_password_change, true)) {
2813 /* we change passwords twice - this has the effect of verifying
2814 they were changed correctly for the final call */
2815 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, true)) {
2819 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, true)) {
2826 static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2827 struct policy_handle *domain_handle,
2828 struct policy_handle *user_handle_out,
2829 struct dom_sid *domain_sid,
2830 enum torture_samr_choice which_ops)
2833 TALLOC_CTX *user_ctx;
2836 struct samr_CreateUser r;
2837 struct samr_QueryUserInfo q;
2838 union samr_UserInfo *info;
2839 struct samr_DeleteUser d;
2842 /* This call creates a 'normal' account - check that it really does */
2843 const uint32_t acct_flags = ACB_NORMAL;
2844 struct lsa_String name;
2847 struct policy_handle user_handle;
2848 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
2849 init_lsa_String(&name, TEST_ACCOUNT_NAME);
2851 r.in.domain_handle = domain_handle;
2852 r.in.account_name = &name;
2853 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2854 r.out.user_handle = &user_handle;
2857 printf("Testing CreateUser(%s)\n", r.in.account_name->string);
2859 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
2861 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
2862 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
2863 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
2866 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
2872 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
2873 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
2874 talloc_free(user_ctx);
2877 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
2879 if (!NT_STATUS_IS_OK(status)) {
2880 talloc_free(user_ctx);
2881 printf("CreateUser failed - %s\n", nt_errstr(status));
2884 q.in.user_handle = &user_handle;
2888 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
2889 if (!NT_STATUS_IS_OK(status)) {
2890 printf("QueryUserInfo level %u failed - %s\n",
2891 q.in.level, nt_errstr(status));
2894 if ((info->info16.acct_flags & acct_flags) != acct_flags) {
2895 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2896 info->info16.acct_flags,
2902 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
2903 acct_flags, name.string, which_ops)) {
2907 if (user_handle_out) {
2908 *user_handle_out = user_handle;
2910 printf("Testing DeleteUser (createuser test)\n");
2912 d.in.user_handle = &user_handle;
2913 d.out.user_handle = &user_handle;
2915 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
2916 if (!NT_STATUS_IS_OK(status)) {
2917 printf("DeleteUser failed - %s\n", nt_errstr(status));
2924 talloc_free(user_ctx);
2930 static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
2931 struct policy_handle *domain_handle,
2932 struct dom_sid *domain_sid,
2933 enum torture_samr_choice which_ops)
2936 struct samr_CreateUser2 r;
2937 struct samr_QueryUserInfo q;
2938 union samr_UserInfo *info;
2939 struct samr_DeleteUser d;
2940 struct policy_handle user_handle;
2942 struct lsa_String name;
2947 uint32_t acct_flags;
2948 const char *account_name;
2950 } account_types[] = {
2951 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
2952 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2953 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2954 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
2955 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2956 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2957 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
2958 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2959 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2960 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
2961 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
2962 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
2963 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2964 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2965 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
2968 for (i = 0; account_types[i].account_name; i++) {
2969 TALLOC_CTX *user_ctx;
2970 uint32_t acct_flags = account_types[i].acct_flags;
2971 uint32_t access_granted;
2972 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
2973 init_lsa_String(&name, account_types[i].account_name);
2975 r.in.domain_handle = domain_handle;
2976 r.in.account_name = &name;
2977 r.in.acct_flags = acct_flags;
2978 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2979 r.out.user_handle = &user_handle;
2980 r.out.access_granted = &access_granted;
2983 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
2985 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
2987 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
2988 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
2989 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
2992 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
2999 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
3000 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
3001 talloc_free(user_ctx);
3005 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
3008 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
3009 printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
3010 nt_errstr(status), nt_errstr(account_types[i].nt_status));
3014 if (NT_STATUS_IS_OK(status)) {
3015 q.in.user_handle = &user_handle;
3019 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
3020 if (!NT_STATUS_IS_OK(status)) {
3021 printf("QueryUserInfo level %u failed - %s\n",
3022 q.in.level, nt_errstr(status));
3025 uint32_t expected_flags = (acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
3026 if (acct_flags == ACB_NORMAL) {
3027 expected_flags |= ACB_PW_EXPIRED;
3029 if ((info->info5.acct_flags) != expected_flags) {
3030 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
3031 info->info5.acct_flags,
3035 switch (acct_flags) {
3037 if (info->info5.primary_gid != DOMAIN_RID_DCS) {
3038 printf("QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n",
3039 DOMAIN_RID_DCS, info->info5.primary_gid);
3044 if (info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
3045 printf("QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
3046 DOMAIN_RID_DOMAIN_MEMBERS, info->info5.primary_gid);
3051 if (info->info5.primary_gid != DOMAIN_RID_USERS) {
3052 printf("QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n",
3053 DOMAIN_RID_USERS, info->info5.primary_gid);
3060 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
3061 acct_flags, name.string, which_ops)) {
3065 printf("Testing DeleteUser (createuser2 test)\n");
3067 d.in.user_handle = &user_handle;
3068 d.out.user_handle = &user_handle;
3070 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
3071 if (!NT_STATUS_IS_OK(status)) {
3072 printf("DeleteUser failed - %s\n", nt_errstr(status));
3076 talloc_free(user_ctx);
3082 static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3083 struct policy_handle *handle)
3086 struct samr_QueryAliasInfo r;
3087 union samr_AliasInfo *info;
3088 uint16_t levels[] = {1, 2, 3};
3092 for (i=0;i<ARRAY_SIZE(levels);i++) {
3093 printf("Testing QueryAliasInfo level %u\n", levels[i]);
3095 r.in.alias_handle = handle;
3096 r.in.level = levels[i];
3099 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
3100 if (!NT_STATUS_IS_OK(status)) {
3101 printf("QueryAliasInfo level %u failed - %s\n",
3102 levels[i], nt_errstr(status));
3110 static bool test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3111 struct policy_handle *handle)
3114 struct samr_QueryGroupInfo r;
3115 union samr_GroupInfo *info;
3116 uint16_t levels[] = {1, 2, 3, 4, 5};
3120 for (i=0;i<ARRAY_SIZE(levels);i++) {
3121 printf("Testing QueryGroupInfo level %u\n", levels[i]);
3123 r.in.group_handle = handle;
3124 r.in.level = levels[i];
3127 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
3128 if (!NT_STATUS_IS_OK(status)) {
3129 printf("QueryGroupInfo level %u failed - %s\n",
3130 levels[i], nt_errstr(status));
3138 static bool test_QueryGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3139 struct policy_handle *handle)
3142 struct samr_QueryGroupMember r;
3143 struct samr_RidTypeArray *rids = NULL;
3146 printf("Testing QueryGroupMember\n");
3148 r.in.group_handle = handle;
3151 status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &r);
3152 if (!NT_STATUS_IS_OK(status)) {
3153 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
3161 static bool test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3162 struct policy_handle *handle)
3165 struct samr_QueryGroupInfo r;
3166 union samr_GroupInfo *info;
3167 struct samr_SetGroupInfo s;
3168 uint16_t levels[] = {1, 2, 3, 4};
3169 uint16_t set_ok[] = {0, 1, 1, 1};
3173 for (i=0;i<ARRAY_SIZE(levels);i++) {
3174 printf("Testing QueryGroupInfo level %u\n", levels[i]);
3176 r.in.group_handle = handle;
3177 r.in.level = levels[i];
3180 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
3181 if (!NT_STATUS_IS_OK(status)) {
3182 printf("QueryGroupInfo level %u failed - %s\n",
3183 levels[i], nt_errstr(status));
3187 printf("Testing SetGroupInfo level %u\n", levels[i]);
3189 s.in.group_handle = handle;
3190 s.in.level = levels[i];
3191 s.in.info = *r.out.info;
3194 /* disabled this, as it changes the name only from the point of view of samr,
3195 but leaves the name from the point of view of w2k3 internals (and ldap). This means
3196 the name is still reserved, so creating the old name fails, but deleting by the old name
3198 if (s.in.level == 2) {
3199 init_lsa_String(&s.in.info->string, "NewName");
3203 if (s.in.level == 4) {
3204 init_lsa_String(&s.in.info->description, "test description");
3207 status = dcerpc_samr_SetGroupInfo(p, mem_ctx, &s);
3209 if (!NT_STATUS_IS_OK(status)) {
3210 printf("SetGroupInfo level %u failed - %s\n",
3211 r.in.level, nt_errstr(status));
3216 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
3217 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
3218 r.in.level, nt_errstr(status));
3228 static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3229 struct policy_handle *handle)
3232 struct samr_QueryUserInfo r;
3233 union samr_UserInfo *info;
3234 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
3235 11, 12, 13, 14, 16, 17, 20, 21};
3239 for (i=0;i<ARRAY_SIZE(levels);i++) {
3240 printf("Testing QueryUserInfo level %u\n", levels[i]);
3242 r.in.user_handle = handle;
3243 r.in.level = levels[i];
3246 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
3247 if (!NT_STATUS_IS_OK(status)) {
3248 printf("QueryUserInfo level %u failed - %s\n",
3249 levels[i], nt_errstr(status));
3257 static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3258 struct policy_handle *handle)
3261 struct samr_QueryUserInfo2 r;
3262 union samr_UserInfo *info;
3263 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
3264 11, 12, 13, 14, 16, 17, 20, 21};
3268 for (i=0;i<ARRAY_SIZE(levels);i++) {
3269 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
3271 r.in.user_handle = handle;
3272 r.in.level = levels[i];
3275 status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r);
3276 if (!NT_STATUS_IS_OK(status)) {
3277 printf("QueryUserInfo2 level %u failed - %s\n",
3278 levels[i], nt_errstr(status));
3286 static bool test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3287 struct policy_handle *handle, uint32_t rid)
3290 struct samr_OpenUser r;
3291 struct policy_handle user_handle;
3294 printf("Testing OpenUser(%u)\n", rid);
3296 r.in.domain_handle = handle;
3297 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3299 r.out.user_handle = &user_handle;
3301 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3302 if (!NT_STATUS_IS_OK(status)) {
3303 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
3307 if (!test_QuerySecurity(p, mem_ctx, &user_handle)) {
3311 if (!test_QueryUserInfo(p, mem_ctx, &user_handle)) {
3315 if (!test_QueryUserInfo2(p, mem_ctx, &user_handle)) {
3319 if (!test_GetUserPwInfo(p, mem_ctx, &user_handle)) {
3323 if (!test_GetGroupsForUser(p,mem_ctx, &user_handle)) {
3327 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
3334 static bool test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3335 struct policy_handle *handle, uint32_t rid)
3338 struct samr_OpenGroup r;
3339 struct policy_handle group_handle;
3342 printf("Testing OpenGroup(%u)\n", rid);
3344 r.in.domain_handle = handle;
3345 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3347 r.out.group_handle = &group_handle;
3349 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
3350 if (!NT_STATUS_IS_OK(status)) {
3351 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
3355 if (!test_QuerySecurity(p, mem_ctx, &group_handle)) {
3359 if (!test_QueryGroupInfo(p, mem_ctx, &group_handle)) {
3363 if (!test_QueryGroupMember(p, mem_ctx, &group_handle)) {
3367 if (!test_samr_handle_Close(p, mem_ctx, &group_handle)) {
3374 static bool test_OpenAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
3375 struct policy_handle *handle, uint32_t rid)
3378 struct samr_OpenAlias r;
3379 struct policy_handle alias_handle;
3382 torture_comment(tctx, "Testing OpenAlias(%u)\n", rid);
3384 r.in.domain_handle = handle;
3385 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3387 r.out.alias_handle = &alias_handle;
3389 status = dcerpc_samr_OpenAlias(p, tctx, &r);
3390 if (!NT_STATUS_IS_OK(status)) {
3391 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
3395 if (!test_QuerySecurity(p, tctx, &alias_handle)) {
3399 if (!test_QueryAliasInfo(p, tctx, &alias_handle)) {
3403 if (!test_GetMembersInAlias(p, tctx, &alias_handle)) {
3407 if (!test_samr_handle_Close(p, tctx, &alias_handle)) {
3414 static bool check_mask(struct dcerpc_pipe *p, struct torture_context *tctx,
3415 struct policy_handle *handle, uint32_t rid,
3416 uint32_t acct_flag_mask)
3419 struct samr_OpenUser r;
3420 struct samr_QueryUserInfo q;
3421 union samr_UserInfo *info;
3422 struct policy_handle user_handle;
3425 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
3427 r.in.domain_handle = handle;
3428 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3430 r.out.user_handle = &user_handle;
3432 status = dcerpc_samr_OpenUser(p, tctx, &r);
3433 if (!NT_STATUS_IS_OK(status)) {
3434 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
3438 q.in.user_handle = &user_handle;
3442 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
3443 if (!NT_STATUS_IS_OK(status)) {
3444 printf("QueryUserInfo level 16 failed - %s\n",
3448 if ((acct_flag_mask & info->info16.acct_flags) == 0) {
3449 printf("Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
3450 acct_flag_mask, info->info16.acct_flags, rid);
3455 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
3462 static bool test_EnumDomainUsers(struct dcerpc_pipe *p, struct torture_context *tctx,
3463 struct policy_handle *handle)
3465 NTSTATUS status = STATUS_MORE_ENTRIES;
3466 struct samr_EnumDomainUsers r;
3467 uint32_t mask, resume_handle=0;
3470 struct samr_LookupNames n;
3471 struct samr_LookupRids lr ;
3472 struct lsa_Strings names;
3473 struct samr_Ids rids, types;
3474 struct samr_SamArray *sam = NULL;
3475 uint32_t num_entries = 0;
3477 uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
3478 ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
3479 ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
3482 printf("Testing EnumDomainUsers\n");
3484 for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
3485 r.in.domain_handle = handle;
3486 r.in.resume_handle = &resume_handle;
3487 r.in.acct_flags = mask = masks[mask_idx];
3488 r.in.max_size = (uint32_t)-1;
3489 r.out.resume_handle = &resume_handle;
3490 r.out.num_entries = &num_entries;
3493 status = dcerpc_samr_EnumDomainUsers(p, tctx, &r);
3494 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
3495 !NT_STATUS_IS_OK(status)) {
3496 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
3500 torture_assert(tctx, sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
3502 if (sam->count == 0) {
3506 for (i=0;i<sam->count;i++) {
3508 if (!check_mask(p, tctx, handle, sam->entries[i].idx, mask)) {
3511 } else if (!test_OpenUser(p, tctx, handle, sam->entries[i].idx)) {
3517 printf("Testing LookupNames\n");
3518 n.in.domain_handle = handle;
3519 n.in.num_names = sam->count;
3520 n.in.names = talloc_array(tctx, struct lsa_String, sam->count);
3522 n.out.types = &types;
3523 for (i=0;i<sam->count;i++) {
3524 n.in.names[i].string = sam->entries[i].name.string;
3526 status = dcerpc_samr_LookupNames(p, tctx, &n);
3527 if (!NT_STATUS_IS_OK(status)) {
3528 printf("LookupNames failed - %s\n", nt_errstr(status));
3533 printf("Testing LookupRids\n");
3534 lr.in.domain_handle = handle;
3535 lr.in.num_rids = sam->count;
3536 lr.in.rids = talloc_array(tctx, uint32_t, sam->count);
3537 lr.out.names = &names;
3538 lr.out.types = &types;
3539 for (i=0;i<sam->count;i++) {
3540 lr.in.rids[i] = sam->entries[i].idx;
3542 status = dcerpc_samr_LookupRids(p, tctx, &lr);
3543 torture_assert_ntstatus_ok(tctx, status, "LookupRids");
3549 try blasting the server with a bunch of sync requests
3551 static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, struct torture_context *tctx,
3552 struct policy_handle *handle)
3555 struct samr_EnumDomainUsers r;
3556 uint32_t resume_handle=0;
3558 #define ASYNC_COUNT 100
3559 struct rpc_request *req[ASYNC_COUNT];
3561 if (!torture_setting_bool(tctx, "dangerous", false)) {
3562 torture_skip(tctx, "samr async test disabled - enable dangerous tests to use\n");
3565 torture_comment(tctx, "Testing EnumDomainUsers_async\n");
3567 r.in.domain_handle = handle;
3568 r.in.resume_handle = &resume_handle;
3569 r.in.acct_flags = 0;
3570 r.in.max_size = (uint32_t)-1;
3571 r.out.resume_handle = &resume_handle;
3573 for (i=0;i<ASYNC_COUNT;i++) {
3574 req[i] = dcerpc_samr_EnumDomainUsers_send(p, tctx, &r);
3577 for (i=0;i<ASYNC_COUNT;i++) {
3578 status = dcerpc_ndr_request_recv(req[i]);
3579 if (!NT_STATUS_IS_OK(status)) {
3580 printf("EnumDomainUsers[%d] failed - %s\n",
3581 i, nt_errstr(status));
3586 torture_comment(tctx, "%d async requests OK\n", i);
3591 static bool test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3592 struct policy_handle *handle)
3595 struct samr_EnumDomainGroups r;
3596 uint32_t resume_handle=0;
3597 struct samr_SamArray *sam = NULL;
3598 uint32_t num_entries = 0;
3602 printf("Testing EnumDomainGroups\n");
3604 r.in.domain_handle = handle;
3605 r.in.resume_handle = &resume_handle;
3606 r.in.max_size = (uint32_t)-1;
3607 r.out.resume_handle = &resume_handle;
3608 r.out.num_entries = &num_entries;
3611 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
3612 if (!NT_STATUS_IS_OK(status)) {
3613 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
3621 for (i=0;i<sam->count;i++) {
3622 if (!test_OpenGroup(p, mem_ctx, handle, sam->entries[i].idx)) {
3630 static bool test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3631 struct policy_handle *handle)
3634 struct samr_EnumDomainAliases r;
3635 uint32_t resume_handle=0;
3636 struct samr_SamArray *sam = NULL;
3637 uint32_t num_entries = 0;
3641 printf("Testing EnumDomainAliases\n");
3643 r.in.domain_handle = handle;
3644 r.in.resume_handle = &resume_handle;
3645 r.in.max_size = (uint32_t)-1;
3647 r.out.num_entries = &num_entries;
3648 r.out.resume_handle = &resume_handle;
3650 status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
3651 if (!NT_STATUS_IS_OK(status)) {
3652 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
3660 for (i=0;i<sam->count;i++) {
3661 if (!test_OpenAlias(p, mem_ctx, handle, sam->entries[i].idx)) {
3669 static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3670 struct policy_handle *handle)
3673 struct samr_GetDisplayEnumerationIndex r;
3675 uint16_t levels[] = {1, 2, 3, 4, 5};
3676 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
3677 struct lsa_String name;
3681 for (i=0;i<ARRAY_SIZE(levels);i++) {
3682 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
3684 init_lsa_String(&name, TEST_ACCOUNT_NAME);
3686 r.in.domain_handle = handle;
3687 r.in.level = levels[i];
3691 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
3694 !NT_STATUS_IS_OK(status) &&
3695 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3696 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
3697 levels[i], nt_errstr(status));
3701 init_lsa_String(&name, "zzzzzzzz");
3703 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
3705 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3706 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
3707 levels[i], nt_errstr(status));
3715 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3716 struct policy_handle *handle)
3719 struct samr_GetDisplayEnumerationIndex2 r;
3721 uint16_t levels[] = {1, 2, 3, 4, 5};
3722 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
3723 struct lsa_String name;
3727 for (i=0;i<ARRAY_SIZE(levels);i++) {
3728 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
3730 init_lsa_String(&name, TEST_ACCOUNT_NAME);
3732 r.in.domain_handle = handle;
3733 r.in.level = levels[i];
3737 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
3739 !NT_STATUS_IS_OK(status) &&
3740 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3741 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
3742 levels[i], nt_errstr(status));
3746 init_lsa_String(&name, "zzzzzzzz");
3748 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
3749 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3750 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
3751 levels[i], nt_errstr(status));
3759 #define STRING_EQUAL_QUERY(s1, s2, user) \
3760 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
3761 /* odd, but valid */ \
3762 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
3763 printf("%s mismatch for %s: %s != %s (%s)\n", \
3764 #s1, user.string, s1.string, s2.string, __location__); \
3767 #define INT_EQUAL_QUERY(s1, s2, user) \
3769 printf("%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
3770 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
3774 static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3775 struct samr_QueryDisplayInfo *querydisplayinfo,
3776 bool *seen_testuser)
3778 struct samr_OpenUser r;
3779 struct samr_QueryUserInfo q;
3780 union samr_UserInfo *info;
3781 struct policy_handle user_handle;
3784 r.in.domain_handle = querydisplayinfo->in.domain_handle;
3785 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3786 for (i = 0; ; i++) {
3787 switch (querydisplayinfo->in.level) {
3789 if (i >= querydisplayinfo->out.info->info1.count) {
3792 r.in.rid = querydisplayinfo->out.info->info1.entries[i].rid;
3795 if (i >= querydisplayinfo->out.info->info2.count) {
3798 r.in.rid = querydisplayinfo->out.info->info2.entries[i].rid;
3804 /* Not interested in validating just the account name */
3808 r.out.user_handle = &user_handle;
3810 switch (querydisplayinfo->in.level) {
3813 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3814 if (!NT_STATUS_IS_OK(status)) {
3815 printf("OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(status));
3820 q.in.user_handle = &user_handle;
3823 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
3824 if (!NT_STATUS_IS_OK(status)) {
3825 printf("QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(status));
3829 switch (querydisplayinfo->in.level) {
3831 if (seen_testuser && strcmp(info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
3832 *seen_testuser = true;
3834 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].full_name,
3835 info->info21.full_name, info->info21.account_name);
3836 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].account_name,
3837 info->info21.account_name, info->info21.account_name);
3838 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].description,
3839 info->info21.description, info->info21.account_name);
3840 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].rid,
3841 info->info21.rid, info->info21.account_name);
3842 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].acct_flags,
3843 info->info21.acct_flags, info->info21.account_name);
3847 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].account_name,
3848 info->info21.account_name, info->info21.account_name);
3849 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].description,
3850 info->info21.description, info->info21.account_name);
3851 INT_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].rid,
3852 info->info21.rid, info->info21.account_name);
3853 INT_EQUAL_QUERY((querydisplayinfo->out.info->info2.entries[i].acct_flags & ~ACB_NORMAL),
3854 info->info21.acct_flags, info->info21.account_name);
3856 if (!(querydisplayinfo->out.info->info2.entries[i].acct_flags & ACB_NORMAL)) {
3857 printf("Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
3858 info->info21.account_name.string);
3861 if (!(info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
3862 printf("Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
3863 info->info21.account_name.string,
3864 querydisplayinfo->out.info->info2.entries[i].acct_flags,
3865 info->info21.acct_flags);
3872 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
3879 static bool test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3880 struct policy_handle *handle)
3883 struct samr_QueryDisplayInfo r;
3884 struct samr_QueryDomainInfo dom_info;
3885 union samr_DomainInfo *info = NULL;
3887 uint16_t levels[] = {1, 2, 3, 4, 5};
3889 bool seen_testuser = false;
3890 uint32_t total_size;
3891 uint32_t returned_size;
3892 union samr_DispInfo disp_info;
3895 for (i=0;i<ARRAY_SIZE(levels);i++) {
3896 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
3899 status = STATUS_MORE_ENTRIES;
3900 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
3901 r.in.domain_handle = handle;
3902 r.in.level = levels[i];
3903 r.in.max_entries = 2;
3904 r.in.buf_size = (uint32_t)-1;
3905 r.out.total_size = &total_size;
3906 r.out.returned_size = &returned_size;
3907 r.out.info = &disp_info;
3909 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
3910 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(status)) {
3911 printf("QueryDisplayInfo level %u failed - %s\n",
3912 levels[i], nt_errstr(status));
3915 switch (r.in.level) {
3917 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, &seen_testuser)) {
3920 r.in.start_idx += r.out.info->info1.count;
3923 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, NULL)) {
3926 r.in.start_idx += r.out.info->info2.count;
3929 r.in.start_idx += r.out.info->info3.count;
3932 r.in.start_idx += r.out.info->info4.count;
3935 r.in.start_idx += r.out.info->info5.count;
3939 dom_info.in.domain_handle = handle;
3940 dom_info.in.level = 2;
3941 dom_info.out.info = &info;
3943 /* Check number of users returned is correct */
3944 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &dom_info);
3945 if (!NT_STATUS_IS_OK(status)) {
3946 printf("QueryDomainInfo level %u failed - %s\n",
3947 r.in.level, nt_errstr(status));
3951 switch (r.in.level) {
3954 if (info->general.num_users < r.in.start_idx) {
3955 printf("QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
3956 r.in.start_idx, info->general.num_groups,
3957 info->general.domain_name.string);
3960 if (!seen_testuser) {
3961 struct policy_handle user_handle;
3962 if (NT_STATUS_IS_OK(test_OpenUser_byname(p, mem_ctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
3963 printf("Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
3964 info->general.domain_name.string);
3966 test_samr_handle_Close(p, mem_ctx, &user_handle);
3972 if (info->general.num_groups != r.in.start_idx) {
3973 printf("QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
3974 r.in.start_idx, info->general.num_groups,
3975 info->general.domain_name.string);
3987 static bool test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3988 struct policy_handle *handle)
3991 struct samr_QueryDisplayInfo2 r;
3993 uint16_t levels[] = {1, 2, 3, 4, 5};
3995 uint32_t total_size;
3996 uint32_t returned_size;
3997 union samr_DispInfo info;
3999 for (i=0;i<ARRAY_SIZE(levels);i++) {
4000 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
4002 r.in.domain_handle = handle;
4003 r.in.level = levels[i];
4005 r.in.max_entries = 1000;
4006 r.in.buf_size = (uint32_t)-1;
4007 r.out.total_size = &total_size;
4008 r.out.returned_size = &returned_size;
4011 status = dcerpc_samr_QueryDisplayInfo2(p, mem_ctx, &r);
4012 if (!NT_STATUS_IS_OK(status)) {
4013 printf("QueryDisplayInfo2 level %u failed - %s\n",
4014 levels[i], nt_errstr(status));
4022 static bool test_QueryDisplayInfo3(struct dcerpc_pipe *p, struct torture_context *tctx,
4023 struct policy_handle *handle)
4026 struct samr_QueryDisplayInfo3 r;
4028 uint16_t levels[] = {1, 2, 3, 4, 5};
4030 uint32_t total_size;
4031 uint32_t returned_size;
4032 union samr_DispInfo info;
4034 for (i=0;i<ARRAY_SIZE(levels);i++) {
4035 torture_comment(tctx, "Testing QueryDisplayInfo3 level %u\n", levels[i]);
4037 r.in.domain_handle = handle;
4038 r.in.level = levels[i];
4040 r.in.max_entries = 1000;
4041 r.in.buf_size = (uint32_t)-1;
4042 r.out.total_size = &total_size;
4043 r.out.returned_size = &returned_size;
4046 status = dcerpc_samr_QueryDisplayInfo3(p, tctx, &r);
4047 if (!NT_STATUS_IS_OK(status)) {
4048 printf("QueryDisplayInfo3 level %u failed - %s\n",
4049 levels[i], nt_errstr(status));
4058 static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4059 struct policy_handle *handle)
4062 struct samr_QueryDisplayInfo r;
4064 uint32_t total_size;
4065 uint32_t returned_size;
4066 union samr_DispInfo info;
4068 printf("Testing QueryDisplayInfo continuation\n");
4070 r.in.domain_handle = handle;
4073 r.in.max_entries = 1;
4074 r.in.buf_size = (uint32_t)-1;
4075 r.out.total_size = &total_size;
4076 r.out.returned_size = &returned_size;
4080 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
4081 if (NT_STATUS_IS_OK(status) && *r.out.returned_size != 0) {
4082 if (r.out.info->info1.entries[0].idx != r.in.start_idx + 1) {
4083 printf("expected idx %d but got %d\n",
4085 r.out.info->info1.entries[0].idx);
4089 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
4090 !NT_STATUS_IS_OK(status)) {
4091 printf("QueryDisplayInfo level %u failed - %s\n",
4092 r.in.level, nt_errstr(status));
4097 } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
4098 NT_STATUS_IS_OK(status)) &&
4099 *r.out.returned_size != 0);
4104 static bool test_QueryDomainInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
4105 struct policy_handle *handle)
4108 struct samr_QueryDomainInfo r;
4109 union samr_DomainInfo *info = NULL;
4110 struct samr_SetDomainInfo s;
4111 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
4112 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
4115 const char *domain_comment = talloc_asprintf(tctx,
4116 "Tortured by Samba4 RPC-SAMR: %s",
4117 timestring(tctx, time(NULL)));
4119 s.in.domain_handle = handle;
4121 s.in.info = talloc(tctx, union samr_DomainInfo);
4123 s.in.info->oem.oem_information.string = domain_comment;
4124 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
4125 if (!NT_STATUS_IS_OK(status)) {
4126 printf("SetDomainInfo level %u (set comment) failed - %s\n",
4127 r.in.level, nt_errstr(status));
4131 for (i=0;i<ARRAY_SIZE(levels);i++) {
4132 torture_comment(tctx, "Testing QueryDomainInfo level %u\n", levels[i]);
4134 r.in.domain_handle = handle;
4135 r.in.level = levels[i];
4138 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
4139 if (!NT_STATUS_IS_OK(status)) {
4140 printf("QueryDomainInfo level %u failed - %s\n",
4141 r.in.level, nt_errstr(status));
4146 switch (levels[i]) {
4148 if (strcmp(info->general.oem_information.string, domain_comment) != 0) {
4149 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
4150 levels[i], info->general.oem_information.string, domain_comment);
4153 if (!info->general.primary.string) {
4154 printf("QueryDomainInfo level %u returned no PDC name\n",
4157 } else if (info->general.role == SAMR_ROLE_DOMAIN_PDC) {
4158 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), info->general.primary.string) != 0) {
4159 printf("QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
4160 levels[i], info->general.primary.string, dcerpc_server_name(p));
4165 if (strcmp(info->oem.oem_information.string, domain_comment) != 0) {
4166 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
4167 levels[i], info->oem.oem_information.string, domain_comment);
4172 if (!info->info6.primary.string) {
4173 printf("QueryDomainInfo level %u returned no PDC name\n",
4179 if (strcmp(info->general2.general.oem_information.string, domain_comment) != 0) {
4180 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
4181 levels[i], info->general2.general.oem_information.string, domain_comment);
4187 torture_comment(tctx, "Testing SetDomainInfo level %u\n", levels[i]);
4189 s.in.domain_handle = handle;
4190 s.in.level = levels[i];
4193 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
4195 if (!NT_STATUS_IS_OK(status)) {
4196 printf("SetDomainInfo level %u failed - %s\n",
4197 r.in.level, nt_errstr(status));
4202 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
4203 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
4204 r.in.level, nt_errstr(status));
4210 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
4211 if (!NT_STATUS_IS_OK(status)) {
4212 printf("QueryDomainInfo level %u failed - %s\n",
4213 r.in.level, nt_errstr(status));
4223 static bool test_QueryDomainInfo2(struct dcerpc_pipe *p, struct torture_context *tctx,
4224 struct policy_handle *handle)
4227 struct samr_QueryDomainInfo2 r;
4228 union samr_DomainInfo *info = NULL;
4229 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
4233 for (i=0;i<ARRAY_SIZE(levels);i++) {
4234 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
4236 r.in.domain_handle = handle;
4237 r.in.level = levels[i];
4240 status = dcerpc_samr_QueryDomainInfo2(p, tctx, &r);
4241 if (!NT_STATUS_IS_OK(status)) {
4242 printf("QueryDomainInfo2 level %u failed - %s\n",
4243 r.in.level, nt_errstr(status));
4252 /* Test whether querydispinfo level 5 and enumdomgroups return the same
4253 set of group names. */
4254 static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx,
4255 struct policy_handle *handle)
4257 struct samr_EnumDomainGroups q1;
4258 struct samr_QueryDisplayInfo q2;
4260 uint32_t resume_handle=0;
4261 struct samr_SamArray *sam = NULL;
4262 uint32_t num_entries = 0;
4265 uint32_t total_size;
4266 uint32_t returned_size;
4267 union samr_DispInfo info;
4270 const char **names = NULL;
4272 torture_comment(tctx, "Testing coherency of querydispinfo vs enumdomgroups\n");
4274 q1.in.domain_handle = handle;
4275 q1.in.resume_handle = &resume_handle;
4277 q1.out.resume_handle = &resume_handle;
4278 q1.out.num_entries = &num_entries;
4281 status = STATUS_MORE_ENTRIES;
4282 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
4283 status = dcerpc_samr_EnumDomainGroups(p, tctx, &q1);
4285 if (!NT_STATUS_IS_OK(status) &&
4286 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
4289 for (i=0; i<*q1.out.num_entries; i++) {
4290 add_string_to_array(tctx,
4291 sam->entries[i].name.string,
4292 &names, &num_names);
4296 torture_assert_ntstatus_ok(tctx, status, "EnumDomainGroups");
4298 torture_assert(tctx, sam, "EnumDomainGroups failed to return sam");
4300 q2.in.domain_handle = handle;
4302 q2.in.start_idx = 0;
4303 q2.in.max_entries = 5;
4304 q2.in.buf_size = (uint32_t)-1;
4305 q2.out.total_size = &total_size;
4306 q2.out.returned_size = &returned_size;
4307 q2.out.info = &info;
4309 status = STATUS_MORE_ENTRIES;
4310 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
4311 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &q2);
4313 if (!NT_STATUS_IS_OK(status) &&
4314 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
4317 for (i=0; i<q2.out.info->info5.count; i++) {
4319 const char *name = q2.out.info->info5.entries[i].account_name.string;
4321 for (j=0; j<num_names; j++) {
4322 if (names[j] == NULL)
4324 if (strequal(names[j], name)) {
4332 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
4337 q2.in.start_idx += q2.out.info->info5.count;
4340 if (!NT_STATUS_IS_OK(status)) {
4341 printf("QueryDisplayInfo level 5 failed - %s\n",
4346 for (i=0; i<num_names; i++) {
4347 if (names[i] != NULL) {
4348 printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
4357 static bool test_DeleteDomainGroup(struct dcerpc_pipe *p, struct torture_context *tctx,
4358 struct policy_handle *group_handle)
4360 struct samr_DeleteDomainGroup d;
4363 torture_comment(tctx, "Testing DeleteDomainGroup\n");
4365 d.in.group_handle = group_handle;
4366 d.out.group_handle = group_handle;
4368 status = dcerpc_samr_DeleteDomainGroup(p, tctx, &d);
4369 torture_assert_ntstatus_ok(tctx, status, "DeleteDomainGroup");
4374 static bool test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
4375 struct policy_handle *domain_handle)
4377 struct samr_TestPrivateFunctionsDomain r;
4381 torture_comment(tctx, "Testing TestPrivateFunctionsDomain\n");
4383 r.in.domain_handle = domain_handle;
4385 status = dcerpc_samr_TestPrivateFunctionsDomain(p, tctx, &r);
4386 torture_assert_ntstatus_equal(tctx, NT_STATUS_NOT_IMPLEMENTED, status, "TestPrivateFunctionsDomain");
4391 static bool test_RidToSid(struct dcerpc_pipe *p, struct torture_context *tctx,
4392 struct dom_sid *domain_sid,
4393 struct policy_handle *domain_handle)
4395 struct samr_RidToSid r;
4398 struct dom_sid *calc_sid, *out_sid;
4399 int rids[] = { 0, 42, 512, 10200 };
4402 for (i=0;i<ARRAY_SIZE(rids);i++) {
4403 torture_comment(tctx, "Testing RidToSid\n");
4405 calc_sid = dom_sid_dup(tctx, domain_sid);
4406 r.in.domain_handle = domain_handle;
4408 r.out.sid = &out_sid;
4410 status = dcerpc_samr_RidToSid(p, tctx, &r);
4411 if (!NT_STATUS_IS_OK(status)) {
4412 printf("RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
4415 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
4417 if (!dom_sid_equal(calc_sid, out_sid)) {
4418 printf("RidToSid for %d failed - got %s, expected %s\n", rids[i],
4419 dom_sid_string(tctx, out_sid),
4420 dom_sid_string(tctx, calc_sid));
4429 static bool test_GetBootKeyInformation(struct dcerpc_pipe *p, struct torture_context *tctx,
4430 struct policy_handle *domain_handle)
4432 struct samr_GetBootKeyInformation r;
4435 uint32_t unknown = 0;
4437 torture_comment(tctx, "Testing GetBootKeyInformation\n");
4439 r.in.domain_handle = domain_handle;
4440 r.out.unknown = &unknown;
4442 status = dcerpc_samr_GetBootKeyInformation(p, tctx, &r);
4443 if (!NT_STATUS_IS_OK(status)) {
4444 /* w2k3 seems to fail this sometimes and pass it sometimes */
4445 torture_comment(tctx, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
4451 static bool test_AddGroupMember(struct dcerpc_pipe *p, struct torture_context *tctx,
4452 struct policy_handle *domain_handle,
4453 struct policy_handle *group_handle)
4456 struct samr_AddGroupMember r;
4457 struct samr_DeleteGroupMember d;
4458 struct samr_QueryGroupMember q;
4459 struct samr_RidTypeArray *rids = NULL;
4460 struct samr_SetMemberAttributesOfGroup s;
4463 status = test_LookupName(p, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
4464 torture_assert_ntstatus_ok(tctx, status, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME);
4466 r.in.group_handle = group_handle;
4468 r.in.flags = 0; /* ??? */
4470 torture_comment(tctx, "Testing AddGroupMember and DeleteGroupMember\n");
4472 d.in.group_handle = group_handle;
4475 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
4476 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_NOT_IN_GROUP, status, "DeleteGroupMember");
4478 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4479 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
4481 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4482 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_IN_GROUP, status, "AddGroupMember");
4484 if (torture_setting_bool(tctx, "samba4", false)) {
4485 torture_comment(tctx, "skipping SetMemberAttributesOfGroup test against Samba4\n");
4487 /* this one is quite strange. I am using random inputs in the
4488 hope of triggering an error that might give us a clue */
4490 s.in.group_handle = group_handle;
4491 s.in.unknown1 = random();
4492 s.in.unknown2 = random();
4494 status = dcerpc_samr_SetMemberAttributesOfGroup(p, tctx, &s);
4495 torture_assert_ntstatus_ok(tctx, status, "SetMemberAttributesOfGroup");
4498 q.in.group_handle = group_handle;
4501 status = dcerpc_samr_QueryGroupMember(p, tctx, &q);
4502 torture_assert_ntstatus_ok(tctx, status, "QueryGroupMember");
4504 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
4505 torture_assert_ntstatus_ok(tctx, status, "DeleteGroupMember");
4507 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4508 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
4514 static bool test_CreateDomainGroup(struct dcerpc_pipe *p,
4515 struct torture_context *tctx,
4516 struct policy_handle *domain_handle,
4517 struct policy_handle *group_handle,
4518 struct dom_sid *domain_sid)
4521 struct samr_CreateDomainGroup r;
4523 struct lsa_String name;
4526 init_lsa_String(&name, TEST_GROUPNAME);
4528 r.in.domain_handle = domain_handle;
4530 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4531 r.out.group_handle = group_handle;
4534 printf("Testing CreateDomainGroup(%s)\n", r.in.name->string);
4536 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
4538 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
4539 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
4540 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.name->string);
4543 printf("Server should have refused create of '%s', got %s instead\n", r.in.name->string,
4549 if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS)) {
4550 if (!test_DeleteGroup_byname(p, tctx, domain_handle, r.in.name->string)) {
4551 printf("CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
4555 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
4557 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
4558 if (!test_DeleteUser_byname(p, tctx, domain_handle, r.in.name->string)) {
4560 printf("CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
4564 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
4566 torture_assert_ntstatus_ok(tctx, status, "CreateDomainGroup");
4568 if (!test_AddGroupMember(p, tctx, domain_handle, group_handle)) {
4569 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
4573 if (!test_SetGroupInfo(p, tctx, group_handle)) {
4582 its not totally clear what this does. It seems to accept any sid you like.
4584 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p,
4585 struct torture_context *tctx,
4586 struct policy_handle *domain_handle)
4589 struct samr_RemoveMemberFromForeignDomain r;
4591 r.in.domain_handle = domain_handle;
4592 r.in.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-12-34-56-78");
4594 status = dcerpc_samr_RemoveMemberFromForeignDomain(p, tctx, &r);
4595 torture_assert_ntstatus_ok(tctx, status, "RemoveMemberFromForeignDomain");
4602 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
4603 struct policy_handle *handle);
4605 static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
4606 struct policy_handle *handle, struct dom_sid *sid,
4607 enum torture_samr_choice which_ops)
4610 struct samr_OpenDomain r;
4611 struct policy_handle domain_handle;
4612 struct policy_handle alias_handle;
4613 struct policy_handle user_handle;
4614 struct policy_handle group_handle;
4617 ZERO_STRUCT(alias_handle);
4618 ZERO_STRUCT(user_handle);
4619 ZERO_STRUCT(group_handle);
4620 ZERO_STRUCT(domain_handle);
4622 torture_comment(tctx, "Testing OpenDomain of %s\n", dom_sid_string(tctx, sid));
4624 r.in.connect_handle = handle;
4625 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4627 r.out.domain_handle = &domain_handle;
4629 status = dcerpc_samr_OpenDomain(p, tctx, &r);
4630 torture_assert_ntstatus_ok(tctx, status, "OpenDomain");
4632 /* run the domain tests with the main handle closed - this tests
4633 the servers reference counting */
4634 ret &= test_samr_handle_Close(p, tctx, handle);
4636 switch (which_ops) {
4637 case TORTURE_SAMR_USER_ATTRIBUTES:
4638 case TORTURE_SAMR_PASSWORDS:
4639 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops);
4640 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops);
4641 /* This test needs 'complex' users to validate */
4642 ret &= test_QueryDisplayInfo(p, tctx, &domain_handle);
4644 printf("Testing PASSWORDS or ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
4647 case TORTURE_SAMR_OTHER:
4648 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops);
4650 printf("Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid));
4652 ret &= test_QuerySecurity(p, tctx, &domain_handle);
4653 ret &= test_RemoveMemberFromForeignDomain(p, tctx, &domain_handle);
4654 ret &= test_CreateAlias(p, tctx, &domain_handle, &alias_handle, sid);
4655 ret &= test_CreateDomainGroup(p, tctx, &domain_handle, &group_handle, sid);
4656 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
4657 ret &= test_QueryDomainInfo2(p, tctx, &domain_handle);
4658 ret &= test_EnumDomainUsers(p, tctx, &domain_handle);
4659 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
4660 ret &= test_EnumDomainGroups(p, tctx, &domain_handle);
4661 ret &= test_EnumDomainAliases(p, tctx, &domain_handle);
4662 ret &= test_QueryDisplayInfo2(p, tctx, &domain_handle);
4663 ret &= test_QueryDisplayInfo3(p, tctx, &domain_handle);
4664 ret &= test_QueryDisplayInfo_continue(p, tctx, &domain_handle);
4666 if (torture_setting_bool(tctx, "samba4", false)) {
4667 torture_comment(tctx, "skipping GetDisplayEnumerationIndex test against Samba4\n");
4669 ret &= test_GetDisplayEnumerationIndex(p, tctx, &domain_handle);
4670 ret &= test_GetDisplayEnumerationIndex2(p, tctx, &domain_handle);
4672 ret &= test_GroupList(p, tctx, &domain_handle);
4673 ret &= test_TestPrivateFunctionsDomain(p, tctx, &domain_handle);
4674 ret &= test_RidToSid(p, tctx, sid, &domain_handle);
4675 ret &= test_GetBootKeyInformation(p, tctx, &domain_handle);
4677 torture_comment(tctx, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx, sid));
4682 if (!policy_handle_empty(&user_handle) &&
4683 !test_DeleteUser(p, tctx, &user_handle)) {
4687 if (!policy_handle_empty(&alias_handle) &&
4688 !test_DeleteAlias(p, tctx, &alias_handle)) {
4692 if (!policy_handle_empty(&group_handle) &&
4693 !test_DeleteDomainGroup(p, tctx, &group_handle)) {
4697 ret &= test_samr_handle_Close(p, tctx, &domain_handle);
4699 /* reconnect the main handle */
4700 ret &= test_Connect(p, tctx, handle);
4703 printf("Testing domain %s failed!\n", dom_sid_string(tctx, sid));
4709 static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
4710 struct policy_handle *handle, const char *domain,
4711 enum torture_samr_choice which_ops)
4714 struct samr_LookupDomain r;
4715 struct dom_sid2 *sid = NULL;
4716 struct lsa_String n1;
4717 struct lsa_String n2;
4720 torture_comment(tctx, "Testing LookupDomain(%s)\n", domain);
4722 /* check for correct error codes */
4723 r.in.connect_handle = handle;
4724 r.in.domain_name = &n2;
4728 status = dcerpc_samr_LookupDomain(p, tctx, &r);
4729 torture_assert_ntstatus_equal(tctx, NT_STATUS_INVALID_PARAMETER, status, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
4731 init_lsa_String(&n2, "xxNODOMAINxx");
4733 status = dcerpc_samr_LookupDomain(p, tctx, &r);
4734 torture_assert_ntstatus_equal(tctx, NT_STATUS_NO_SUCH_DOMAIN, status, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
4736 r.in.connect_handle = handle;
4738 init_lsa_String(&n1, domain);
4739 r.in.domain_name = &n1;
4741 status = dcerpc_samr_LookupDomain(p, tctx, &r);
4742 torture_assert_ntstatus_ok(tctx, status, "LookupDomain");
4744 if (!test_GetDomPwInfo(p, tctx, &n1)) {
4748 if (!test_OpenDomain(p, tctx, handle, *r.out.sid, which_ops)) {
4756 static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
4757 struct policy_handle *handle, enum torture_samr_choice which_ops)
4760 struct samr_EnumDomains r;
4761 uint32_t resume_handle = 0;
4762 uint32_t num_entries = 0;
4763 struct samr_SamArray *sam = NULL;
4767 r.in.connect_handle = handle;
4768 r.in.resume_handle = &resume_handle;
4769 r.in.buf_size = (uint32_t)-1;
4770 r.out.resume_handle = &resume_handle;
4771 r.out.num_entries = &num_entries;
4774 status = dcerpc_samr_EnumDomains(p, tctx, &r);
4775 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
4781 for (i=0;i<sam->count;i++) {
4782 if (!test_LookupDomain(p, tctx, handle,
4783 sam->entries[i].name.string, which_ops)) {
4788 status = dcerpc_samr_EnumDomains(p, tctx, &r);
4789 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
4795 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
4796 struct policy_handle *handle)
4799 struct samr_Connect r;
4800 struct samr_Connect2 r2;
4801 struct samr_Connect3 r3;
4802 struct samr_Connect4 r4;
4803 struct samr_Connect5 r5;
4804 union samr_ConnectInfo info;
4805 struct policy_handle h;
4806 uint32_t level_out = 0;
4807 bool ret = true, got_handle = false;
4809 torture_comment(tctx, "testing samr_Connect\n");
4811 r.in.system_name = 0;
4812 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4813 r.out.connect_handle = &h;
4815 status = dcerpc_samr_Connect(p, tctx, &r);
4816 if (!NT_STATUS_IS_OK(status)) {
4817 torture_comment(tctx, "Connect failed - %s\n", nt_errstr(status));
4824 torture_comment(tctx, "testing samr_Connect2\n");
4826 r2.in.system_name = NULL;
4827 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4828 r2.out.connect_handle = &h;
4830 status = dcerpc_samr_Connect2(p, tctx, &r2);
4831 if (!NT_STATUS_IS_OK(status)) {
4832 torture_comment(tctx, "Connect2 failed - %s\n", nt_errstr(status));
4836 test_samr_handle_Close(p, tctx, handle);
4842 torture_comment(tctx, "testing samr_Connect3\n");
4844 r3.in.system_name = NULL;
4846 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4847 r3.out.connect_handle = &h;
4849 status = dcerpc_samr_Connect3(p, tctx, &r3);
4850 if (!NT_STATUS_IS_OK(status)) {
4851 printf("Connect3 failed - %s\n", nt_errstr(status));
4855 test_samr_handle_Close(p, tctx, handle);
4861 torture_comment(tctx, "testing samr_Connect4\n");
4863 r4.in.system_name = "";
4864 r4.in.client_version = 0;
4865 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4866 r4.out.connect_handle = &h;
4868 status = dcerpc_samr_Connect4(p, tctx, &r4);
4869 if (!NT_STATUS_IS_OK(status)) {
4870 printf("Connect4 failed - %s\n", nt_errstr(status));
4874 test_samr_handle_Close(p, tctx, handle);
4880 torture_comment(tctx, "testing samr_Connect5\n");
4882 info.info1.client_version = 0;
4883 info.info1.unknown2 = 0;
4885 r5.in.system_name = "";
4886 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4888 r5.out.level_out = &level_out;
4889 r5.in.info_in = &info;
4890 r5.out.info_out = &info;
4891 r5.out.connect_handle = &h;
4893 status = dcerpc_samr_Connect5(p, tctx, &r5);
4894 if (!NT_STATUS_IS_OK(status)) {
4895 printf("Connect5 failed - %s\n", nt_errstr(status));
4899 test_samr_handle_Close(p, tctx, handle);
4909 bool torture_rpc_samr(struct torture_context *torture)
4912 struct dcerpc_pipe *p;
4914 struct policy_handle handle;
4916 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4917 if (!NT_STATUS_IS_OK(status)) {
4921 ret &= test_Connect(p, torture, &handle);
4923 ret &= test_QuerySecurity(p, torture, &handle);
4925 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_OTHER);
4927 ret &= test_SetDsrmPassword(p, torture, &handle);
4929 ret &= test_Shutdown(p, torture, &handle);
4931 ret &= test_samr_handle_Close(p, torture, &handle);
4937 bool torture_rpc_samr_users(struct torture_context *torture)
4940 struct dcerpc_pipe *p;
4942 struct policy_handle handle;
4944 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4945 if (!NT_STATUS_IS_OK(status)) {
4949 ret &= test_Connect(p, torture, &handle);
4951 ret &= test_QuerySecurity(p, torture, &handle);
4953 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_USER_ATTRIBUTES);
4955 ret &= test_SetDsrmPassword(p, torture, &handle);
4957 ret &= test_Shutdown(p, torture, &handle);
4959 ret &= test_samr_handle_Close(p, torture, &handle);
4965 bool torture_rpc_samr_passwords(struct torture_context *torture)
4968 struct dcerpc_pipe *p;
4970 struct policy_handle handle;
4972 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4973 if (!NT_STATUS_IS_OK(status)) {
4977 ret &= test_Connect(p, torture, &handle);
4979 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_PASSWORDS);
4981 ret &= test_samr_handle_Close(p, torture, &handle);