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"
34 #define TEST_ACCOUNT_NAME "samrtorturetest"
35 #define TEST_ALIASNAME "samrtorturetestalias"
36 #define TEST_GROUPNAME "samrtorturetestgroup"
37 #define TEST_MACHINENAME "samrtestmach$"
38 #define TEST_DOMAINNAME "samrtestdom$"
40 enum torture_samr_choice {
41 TORTURE_SAMR_PASSWORDS,
42 TORTURE_SAMR_USER_ATTRIBUTES,
46 static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
47 struct policy_handle *handle);
49 static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
50 struct policy_handle *handle);
52 static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
53 struct policy_handle *handle);
55 static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
56 const char *acct_name,
57 struct policy_handle *domain_handle, char **password);
59 static void init_lsa_String(struct lsa_String *string, const char *s)
64 static void init_lsa_BinaryString(struct lsa_BinaryString *string, const char *s, uint32_t length)
66 string->length = length;
67 string->size = length;
68 string->array = (uint16_t *)discard_const(s);
71 bool test_samr_handle_Close(struct dcerpc_pipe *p, struct torture_context *tctx,
72 struct policy_handle *handle)
78 r.out.handle = handle;
80 status = dcerpc_samr_Close(p, tctx, &r);
81 torture_assert_ntstatus_ok(tctx, status, "Close");
86 static bool test_Shutdown(struct dcerpc_pipe *p, struct torture_context *tctx,
87 struct policy_handle *handle)
90 struct samr_Shutdown r;
92 if (!torture_setting_bool(tctx, "dangerous", false)) {
93 torture_skip(tctx, "samr_Shutdown disabled - enable dangerous tests to use\n");
97 r.in.connect_handle = handle;
99 torture_comment(tctx, "testing samr_Shutdown\n");
101 status = dcerpc_samr_Shutdown(p, tctx, &r);
102 torture_assert_ntstatus_ok(tctx, status, "samr_Shutdown");
107 static bool test_SetDsrmPassword(struct dcerpc_pipe *p, struct torture_context *tctx,
108 struct policy_handle *handle)
111 struct samr_SetDsrmPassword r;
112 struct lsa_String string;
113 struct samr_Password hash;
115 if (!torture_setting_bool(tctx, "dangerous", false)) {
116 torture_skip(tctx, "samr_SetDsrmPassword disabled - enable dangerous tests to use");
119 E_md4hash("TeSTDSRM123", hash.hash);
121 init_lsa_String(&string, "Administrator");
127 torture_comment(tctx, "testing samr_SetDsrmPassword\n");
129 status = dcerpc_samr_SetDsrmPassword(p, tctx, &r);
130 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_SUPPORTED, "samr_SetDsrmPassword");
136 static bool test_QuerySecurity(struct dcerpc_pipe *p,
137 struct torture_context *tctx,
138 struct policy_handle *handle)
141 struct samr_QuerySecurity r;
142 struct samr_SetSecurity s;
143 struct sec_desc_buf *sdbuf = NULL;
145 r.in.handle = handle;
147 r.out.sdbuf = &sdbuf;
149 status = dcerpc_samr_QuerySecurity(p, tctx, &r);
150 torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
152 torture_assert(tctx, sdbuf != NULL, "sdbuf is NULL");
154 s.in.handle = handle;
158 if (torture_setting_bool(tctx, "samba4", false)) {
159 torture_skip(tctx, "skipping SetSecurity test against Samba4\n");
162 status = dcerpc_samr_SetSecurity(p, tctx, &s);
163 torture_assert_ntstatus_ok(tctx, status, "SetSecurity");
165 status = dcerpc_samr_QuerySecurity(p, tctx, &r);
166 torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
172 static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
173 struct policy_handle *handle, uint32_t base_acct_flags,
174 const char *base_account_name)
177 struct samr_SetUserInfo s;
178 struct samr_SetUserInfo2 s2;
179 struct samr_QueryUserInfo q;
180 struct samr_QueryUserInfo q0;
181 union samr_UserInfo u;
182 union samr_UserInfo *info;
184 const char *test_account_name;
186 uint32_t user_extra_flags = 0;
187 if (base_acct_flags == ACB_NORMAL) {
188 /* When created, accounts are expired by default */
189 user_extra_flags = ACB_PW_EXPIRED;
192 s.in.user_handle = handle;
195 s2.in.user_handle = handle;
198 q.in.user_handle = handle;
202 #define TESTCALL(call, r) \
203 status = dcerpc_samr_ ##call(p, tctx, &r); \
204 if (!NT_STATUS_IS_OK(status)) { \
205 torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
206 r.in.level, nt_errstr(status), __location__); \
211 #define STRING_EQUAL(s1, s2, field) \
212 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
213 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
214 #field, s2, __location__); \
219 #define MEM_EQUAL(s1, s2, length, field) \
220 if ((s1 && !s2) || (s2 && !s1) || memcmp(s1, s2, length)) { \
221 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
222 #field, (const char *)s2, __location__); \
227 #define INT_EQUAL(i1, i2, field) \
229 torture_comment(tctx, "Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \
230 #field, (unsigned long long)i2, (unsigned long long)i1, __location__); \
235 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
236 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
238 TESTCALL(QueryUserInfo, q) \
240 s2.in.level = lvl1; \
243 ZERO_STRUCT(u.info21); \
244 u.info21.fields_present = fpval; \
246 init_lsa_String(&u.info ## lvl1.field1, value); \
247 TESTCALL(SetUserInfo, s) \
248 TESTCALL(SetUserInfo2, s2) \
249 init_lsa_String(&u.info ## lvl1.field1, ""); \
250 TESTCALL(QueryUserInfo, q); \
252 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
254 TESTCALL(QueryUserInfo, q) \
256 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
259 #define TEST_USERINFO_BINARYSTRING(lvl1, field1, lvl2, field2, value, fpval) do { \
260 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
262 TESTCALL(QueryUserInfo, q) \
264 s2.in.level = lvl1; \
267 ZERO_STRUCT(u.info21); \
268 u.info21.fields_present = fpval; \
270 init_lsa_BinaryString(&u.info ## lvl1.field1, value, strlen(value)); \
271 TESTCALL(SetUserInfo, s) \
272 TESTCALL(SetUserInfo2, s2) \
273 init_lsa_BinaryString(&u.info ## lvl1.field1, "", 1); \
274 TESTCALL(QueryUserInfo, q); \
276 MEM_EQUAL(u.info ## lvl1.field1.array, value, strlen(value), field1); \
278 TESTCALL(QueryUserInfo, q) \
280 MEM_EQUAL(u.info ## lvl2.field2.array, value, strlen(value), field2); \
283 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
284 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
286 TESTCALL(QueryUserInfo, q) \
288 s2.in.level = lvl1; \
291 uint8_t *bits = u.info21.logon_hours.bits; \
292 ZERO_STRUCT(u.info21); \
293 if (fpval == SAMR_FIELD_LOGON_HOURS) { \
294 u.info21.logon_hours.units_per_week = 168; \
295 u.info21.logon_hours.bits = bits; \
297 u.info21.fields_present = fpval; \
299 u.info ## lvl1.field1 = value; \
300 TESTCALL(SetUserInfo, s) \
301 TESTCALL(SetUserInfo2, s2) \
302 u.info ## lvl1.field1 = 0; \
303 TESTCALL(QueryUserInfo, q); \
305 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
307 TESTCALL(QueryUserInfo, q) \
309 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
312 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
313 TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
317 do { TESTCALL(QueryUserInfo, q0) } while (0);
319 TEST_USERINFO_STRING(2, comment, 1, comment, "xx2-1 comment", 0);
320 TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
321 TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment",
324 test_account_name = talloc_asprintf(tctx, "%sxx7-1", base_account_name);
325 TEST_USERINFO_STRING(7, account_name, 1, account_name, base_account_name, 0);
326 test_account_name = talloc_asprintf(tctx, "%sxx7-3", base_account_name);
327 TEST_USERINFO_STRING(7, account_name, 3, account_name, base_account_name, 0);
328 test_account_name = talloc_asprintf(tctx, "%sxx7-5", base_account_name);
329 TEST_USERINFO_STRING(7, account_name, 5, account_name, base_account_name, 0);
330 test_account_name = talloc_asprintf(tctx, "%sxx7-6", base_account_name);
331 TEST_USERINFO_STRING(7, account_name, 6, account_name, base_account_name, 0);
332 test_account_name = talloc_asprintf(tctx, "%sxx7-7", base_account_name);
333 TEST_USERINFO_STRING(7, account_name, 7, account_name, base_account_name, 0);
334 test_account_name = talloc_asprintf(tctx, "%sxx7-21", base_account_name);
335 TEST_USERINFO_STRING(7, account_name, 21, account_name, base_account_name, 0);
336 test_account_name = base_account_name;
337 TEST_USERINFO_STRING(21, account_name, 21, account_name, base_account_name,
338 SAMR_FIELD_ACCOUNT_NAME);
340 TEST_USERINFO_STRING(6, full_name, 1, full_name, "xx6-1 full_name", 0);
341 TEST_USERINFO_STRING(6, full_name, 3, full_name, "xx6-3 full_name", 0);
342 TEST_USERINFO_STRING(6, full_name, 5, full_name, "xx6-5 full_name", 0);
343 TEST_USERINFO_STRING(6, full_name, 6, full_name, "xx6-6 full_name", 0);
344 TEST_USERINFO_STRING(6, full_name, 8, full_name, "xx6-8 full_name", 0);
345 TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
346 TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
347 TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name",
348 SAMR_FIELD_FULL_NAME);
350 TEST_USERINFO_STRING(6, full_name, 1, full_name, "", 0);
351 TEST_USERINFO_STRING(6, full_name, 3, full_name, "", 0);
352 TEST_USERINFO_STRING(6, full_name, 5, full_name, "", 0);
353 TEST_USERINFO_STRING(6, full_name, 6, full_name, "", 0);
354 TEST_USERINFO_STRING(6, full_name, 8, full_name, "", 0);
355 TEST_USERINFO_STRING(6, full_name, 21, full_name, "", 0);
356 TEST_USERINFO_STRING(8, full_name, 21, full_name, "", 0);
357 TEST_USERINFO_STRING(21, full_name, 21, full_name, "",
358 SAMR_FIELD_FULL_NAME);
360 TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
361 TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
362 TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
363 TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script",
364 SAMR_FIELD_LOGON_SCRIPT);
366 TEST_USERINFO_STRING(12, profile_path, 3, profile_path, "xx12-3 profile_path", 0);
367 TEST_USERINFO_STRING(12, profile_path, 5, profile_path, "xx12-5 profile_path", 0);
368 TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
369 TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path",
370 SAMR_FIELD_PROFILE_PATH);
372 TEST_USERINFO_STRING(10, home_directory, 3, home_directory, "xx10-3 home_directory", 0);
373 TEST_USERINFO_STRING(10, home_directory, 5, home_directory, "xx10-5 home_directory", 0);
374 TEST_USERINFO_STRING(10, home_directory, 21, home_directory, "xx10-21 home_directory", 0);
375 TEST_USERINFO_STRING(21, home_directory, 21, home_directory, "xx21-21 home_directory",
376 SAMR_FIELD_HOME_DIRECTORY);
377 TEST_USERINFO_STRING(21, home_directory, 10, home_directory, "xx21-10 home_directory",
378 SAMR_FIELD_HOME_DIRECTORY);
380 TEST_USERINFO_STRING(10, home_drive, 3, home_drive, "xx10-3 home_drive", 0);
381 TEST_USERINFO_STRING(10, home_drive, 5, home_drive, "xx10-5 home_drive", 0);
382 TEST_USERINFO_STRING(10, home_drive, 21, home_drive, "xx10-21 home_drive", 0);
383 TEST_USERINFO_STRING(21, home_drive, 21, home_drive, "xx21-21 home_drive",
384 SAMR_FIELD_HOME_DRIVE);
385 TEST_USERINFO_STRING(21, home_drive, 10, home_drive, "xx21-10 home_drive",
386 SAMR_FIELD_HOME_DRIVE);
388 TEST_USERINFO_STRING(13, description, 1, description, "xx13-1 description", 0);
389 TEST_USERINFO_STRING(13, description, 5, description, "xx13-5 description", 0);
390 TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
391 TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description",
392 SAMR_FIELD_DESCRIPTION);
394 TEST_USERINFO_STRING(14, workstations, 3, workstations, "14workstation3", 0);
395 TEST_USERINFO_STRING(14, workstations, 5, workstations, "14workstation4", 0);
396 TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
397 TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21",
398 SAMR_FIELD_WORKSTATIONS);
399 TEST_USERINFO_STRING(21, workstations, 3, workstations, "21workstation3",
400 SAMR_FIELD_WORKSTATIONS);
401 TEST_USERINFO_STRING(21, workstations, 5, workstations, "21workstation5",
402 SAMR_FIELD_WORKSTATIONS);
403 TEST_USERINFO_STRING(21, workstations, 14, workstations, "21workstation14",
404 SAMR_FIELD_WORKSTATIONS);
406 TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
407 TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "xx21-21 parameters",
408 SAMR_FIELD_PARAMETERS);
409 TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "xx21-20 parameters",
410 SAMR_FIELD_PARAMETERS);
412 TEST_USERINFO_INT(2, country_code, 2, country_code, __LINE__, 0);
413 TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
414 TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__,
415 SAMR_FIELD_COUNTRY_CODE);
416 TEST_USERINFO_INT(21, country_code, 2, country_code, __LINE__,
417 SAMR_FIELD_COUNTRY_CODE);
419 TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
420 TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__,
421 SAMR_FIELD_CODE_PAGE);
422 TEST_USERINFO_INT(21, code_page, 2, code_page, __LINE__,
423 SAMR_FIELD_CODE_PAGE);
425 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, __LINE__, 0);
426 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, __LINE__, 0);
427 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, __LINE__,
428 SAMR_FIELD_ACCT_EXPIRY);
429 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, __LINE__,
430 SAMR_FIELD_ACCT_EXPIRY);
431 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, __LINE__,
432 SAMR_FIELD_ACCT_EXPIRY);
434 TEST_USERINFO_INT(4, logon_hours.bits[3], 3, logon_hours.bits[3], 1, 0);
435 TEST_USERINFO_INT(4, logon_hours.bits[3], 5, logon_hours.bits[3], 2, 0);
436 TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
437 TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4,
438 SAMR_FIELD_LOGON_HOURS);
440 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
441 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
442 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
444 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
445 (base_acct_flags | ACB_DISABLED),
446 (base_acct_flags | ACB_DISABLED | user_extra_flags),
449 /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
450 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
451 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
452 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
454 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
455 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
456 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
460 /* The 'autolock' flag doesn't stick - check this */
461 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
462 (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK),
463 (base_acct_flags | ACB_DISABLED | user_extra_flags),
466 /* Removing the 'disabled' flag doesn't stick - check this */
467 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
469 (base_acct_flags | ACB_DISABLED | user_extra_flags),
472 /* The 'store plaintext' flag does stick */
473 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
474 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED),
475 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags),
477 /* The 'use DES' flag does stick */
478 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
479 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY),
480 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags),
482 /* The 'don't require kerberos pre-authentication flag does stick */
483 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
484 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH),
485 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags),
487 /* The 'no kerberos PAC required' flag sticks */
488 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
489 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD),
490 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags),
493 TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags,
494 (base_acct_flags | ACB_DISABLED),
495 (base_acct_flags | ACB_DISABLED | user_extra_flags),
496 SAMR_FIELD_ACCT_FLAGS);
499 /* these fail with win2003 - it appears you can't set the primary gid?
500 the set succeeds, but the gid isn't changed. Very weird! */
501 TEST_USERINFO_INT(9, primary_gid, 1, primary_gid, 513);
502 TEST_USERINFO_INT(9, primary_gid, 3, primary_gid, 513);
503 TEST_USERINFO_INT(9, primary_gid, 5, primary_gid, 513);
504 TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
511 generate a random password for password change tests
513 static char *samr_rand_pass_silent(TALLOC_CTX *mem_ctx, int min_len)
515 size_t len = MAX(8, min_len) + (random() % 6);
516 char *s = generate_random_str(mem_ctx, len);
520 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
522 char *s = samr_rand_pass_silent(mem_ctx, min_len);
523 printf("Generated password '%s'\n", s);
529 generate a random password for password change tests
531 static DATA_BLOB samr_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
534 DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
535 generate_random_buffer(password.data, password.length);
537 for (i=0; i < len; i++) {
538 if (((uint16_t *)password.data)[i] == 0) {
539 ((uint16_t *)password.data)[i] = 1;
547 generate a random password for password change tests (fixed length)
549 static char *samr_rand_pass_fixed_len(TALLOC_CTX *mem_ctx, int len)
551 char *s = generate_random_str(mem_ctx, len);
552 printf("Generated password '%s'\n", s);
556 static bool test_SetUserPass(struct dcerpc_pipe *p, struct torture_context *tctx,
557 struct policy_handle *handle, char **password)
560 struct samr_SetUserInfo s;
561 union samr_UserInfo u;
563 DATA_BLOB session_key;
565 struct samr_GetUserPwInfo pwp;
566 struct samr_PwInfo info;
567 int policy_min_pw_len = 0;
568 pwp.in.user_handle = handle;
569 pwp.out.info = &info;
571 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
572 if (NT_STATUS_IS_OK(status)) {
573 policy_min_pw_len = pwp.out.info->min_password_length;
575 newpass = samr_rand_pass(tctx, policy_min_pw_len);
577 s.in.user_handle = handle;
581 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
582 u.info24.password_expired = 0;
584 status = dcerpc_fetch_session_key(p, &session_key);
585 if (!NT_STATUS_IS_OK(status)) {
586 printf("SetUserInfo level %u - no session key - %s\n",
587 s.in.level, nt_errstr(status));
591 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
593 torture_comment(tctx, "Testing SetUserInfo level 24 (set password)\n");
595 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
596 if (!NT_STATUS_IS_OK(status)) {
597 printf("SetUserInfo level %u failed - %s\n",
598 s.in.level, nt_errstr(status));
608 static bool test_SetUserPass_23(struct dcerpc_pipe *p, struct torture_context *tctx,
609 struct policy_handle *handle, uint32_t fields_present,
613 struct samr_SetUserInfo s;
614 union samr_UserInfo u;
616 DATA_BLOB session_key;
618 struct samr_GetUserPwInfo pwp;
619 struct samr_PwInfo info;
620 int policy_min_pw_len = 0;
621 pwp.in.user_handle = handle;
622 pwp.out.info = &info;
624 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
625 if (NT_STATUS_IS_OK(status)) {
626 policy_min_pw_len = pwp.out.info->min_password_length;
628 newpass = samr_rand_pass(tctx, policy_min_pw_len);
630 s.in.user_handle = handle;
636 u.info23.info.fields_present = fields_present;
638 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
640 status = dcerpc_fetch_session_key(p, &session_key);
641 if (!NT_STATUS_IS_OK(status)) {
642 printf("SetUserInfo level %u - no session key - %s\n",
643 s.in.level, nt_errstr(status));
647 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
649 torture_comment(tctx, "Testing SetUserInfo level 23 (set password)\n");
651 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
652 if (!NT_STATUS_IS_OK(status)) {
653 printf("SetUserInfo level %u failed - %s\n",
654 s.in.level, nt_errstr(status));
660 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
662 status = dcerpc_fetch_session_key(p, &session_key);
663 if (!NT_STATUS_IS_OK(status)) {
664 printf("SetUserInfo level %u - no session key - %s\n",
665 s.in.level, nt_errstr(status));
669 /* This should break the key nicely */
670 session_key.length--;
671 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
673 torture_comment(tctx, "Testing SetUserInfo level 23 (set password) with wrong password\n");
675 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
676 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
677 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
678 s.in.level, nt_errstr(status));
686 static bool test_SetUserPassEx(struct dcerpc_pipe *p, struct torture_context *tctx,
687 struct policy_handle *handle, bool makeshort,
691 struct samr_SetUserInfo s;
692 union samr_UserInfo u;
694 DATA_BLOB session_key;
695 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
696 uint8_t confounder[16];
698 struct MD5Context ctx;
699 struct samr_GetUserPwInfo pwp;
700 struct samr_PwInfo info;
701 int policy_min_pw_len = 0;
702 pwp.in.user_handle = handle;
703 pwp.out.info = &info;
705 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
706 if (NT_STATUS_IS_OK(status)) {
707 policy_min_pw_len = pwp.out.info->min_password_length;
709 if (makeshort && policy_min_pw_len) {
710 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len - 1);
712 newpass = samr_rand_pass(tctx, policy_min_pw_len);
715 s.in.user_handle = handle;
719 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
720 u.info26.password_expired = 0;
722 status = dcerpc_fetch_session_key(p, &session_key);
723 if (!NT_STATUS_IS_OK(status)) {
724 printf("SetUserInfo level %u - no session key - %s\n",
725 s.in.level, nt_errstr(status));
729 generate_random_buffer((uint8_t *)confounder, 16);
732 MD5Update(&ctx, confounder, 16);
733 MD5Update(&ctx, session_key.data, session_key.length);
734 MD5Final(confounded_session_key.data, &ctx);
736 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
737 memcpy(&u.info26.password.data[516], confounder, 16);
739 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex)\n");
741 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
742 if (!NT_STATUS_IS_OK(status)) {
743 printf("SetUserInfo level %u failed - %s\n",
744 s.in.level, nt_errstr(status));
750 /* This should break the key nicely */
751 confounded_session_key.data[0]++;
753 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
754 memcpy(&u.info26.password.data[516], confounder, 16);
756 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
758 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
759 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
760 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
761 s.in.level, nt_errstr(status));
770 static bool test_SetUserPass_25(struct dcerpc_pipe *p, struct torture_context *tctx,
771 struct policy_handle *handle, uint32_t fields_present,
775 struct samr_SetUserInfo s;
776 union samr_UserInfo u;
778 DATA_BLOB session_key;
779 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
780 struct MD5Context ctx;
781 uint8_t confounder[16];
783 struct samr_GetUserPwInfo pwp;
784 struct samr_PwInfo info;
785 int policy_min_pw_len = 0;
786 pwp.in.user_handle = handle;
787 pwp.out.info = &info;
789 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
790 if (NT_STATUS_IS_OK(status)) {
791 policy_min_pw_len = pwp.out.info->min_password_length;
793 newpass = samr_rand_pass(tctx, policy_min_pw_len);
795 s.in.user_handle = handle;
801 u.info25.info.fields_present = fields_present;
803 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
805 status = dcerpc_fetch_session_key(p, &session_key);
806 if (!NT_STATUS_IS_OK(status)) {
807 printf("SetUserInfo level %u - no session key - %s\n",
808 s.in.level, nt_errstr(status));
812 generate_random_buffer((uint8_t *)confounder, 16);
815 MD5Update(&ctx, confounder, 16);
816 MD5Update(&ctx, session_key.data, session_key.length);
817 MD5Final(confounded_session_key.data, &ctx);
819 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
820 memcpy(&u.info25.password.data[516], confounder, 16);
822 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex)\n");
824 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
825 if (!NT_STATUS_IS_OK(status)) {
826 printf("SetUserInfo level %u failed - %s\n",
827 s.in.level, nt_errstr(status));
833 /* This should break the key nicely */
834 confounded_session_key.data[0]++;
836 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
837 memcpy(&u.info25.password.data[516], confounder, 16);
839 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
841 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
842 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
843 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
844 s.in.level, nt_errstr(status));
851 static bool test_SetUserPass_level_ex(struct dcerpc_pipe *p,
852 struct torture_context *tctx,
853 struct policy_handle *handle,
855 uint32_t fields_present,
856 char **password, uint8_t password_expired,
857 bool use_setinfo2, NTSTATUS expected_error)
860 struct samr_SetUserInfo s;
861 struct samr_SetUserInfo2 s2;
862 union samr_UserInfo u;
864 DATA_BLOB session_key;
865 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
866 struct MD5Context ctx;
867 uint8_t confounder[16];
869 struct samr_GetUserPwInfo pwp;
870 struct samr_PwInfo info;
871 int policy_min_pw_len = 0;
872 pwp.in.user_handle = handle;
873 pwp.out.info = &info;
875 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
876 if (NT_STATUS_IS_OK(status)) {
877 policy_min_pw_len = pwp.out.info->min_password_length;
879 newpass = samr_rand_pass_silent(tctx, policy_min_pw_len);
882 s2.in.user_handle = handle;
886 s.in.user_handle = handle;
895 u.info21.fields_present = fields_present;
896 u.info21.password_expired = password_expired;
900 u.info23.info.fields_present = fields_present;
901 u.info23.info.password_expired = password_expired;
903 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
907 u.info24.password_expired = password_expired;
909 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
913 u.info25.info.fields_present = fields_present;
914 u.info25.info.password_expired = password_expired;
916 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
920 u.info26.password_expired = password_expired;
922 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
927 status = dcerpc_fetch_session_key(p, &session_key);
928 if (!NT_STATUS_IS_OK(status)) {
929 printf("SetUserInfo level %u - no session key - %s\n",
930 s.in.level, nt_errstr(status));
934 generate_random_buffer((uint8_t *)confounder, 16);
937 MD5Update(&ctx, confounder, 16);
938 MD5Update(&ctx, session_key.data, session_key.length);
939 MD5Final(confounded_session_key.data, &ctx);
943 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
946 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
949 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
950 memcpy(&u.info25.password.data[516], confounder, 16);
953 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
954 memcpy(&u.info26.password.data[516], confounder, 16);
959 status = dcerpc_samr_SetUserInfo2(p, tctx, &s2);
961 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
964 if (NT_STATUS_IS_ERR(expected_error)) {
965 torture_assert_ntstatus_equal(tctx, status, expected_error, "");
969 if (!NT_STATUS_IS_OK(status)) {
970 printf("SetUserInfo%s level %u failed - %s\n",
971 use_setinfo2 ? "2":"", level, nt_errstr(status));
982 static bool test_SetAliasInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
983 struct policy_handle *handle)
986 struct samr_SetAliasInfo r;
987 struct samr_QueryAliasInfo q;
988 union samr_AliasInfo *info;
989 uint16_t levels[] = {2, 3};
993 /* Ignoring switch level 1, as that includes the number of members for the alias
994 * and setting this to a wrong value might have negative consequences
997 for (i=0;i<ARRAY_SIZE(levels);i++) {
998 torture_comment(tctx, "Testing SetAliasInfo level %u\n", levels[i]);
1000 r.in.alias_handle = handle;
1001 r.in.level = levels[i];
1002 r.in.info = talloc(tctx, union samr_AliasInfo);
1003 switch (r.in.level) {
1004 case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
1005 case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
1006 "Test Description, should test I18N as well"); break;
1007 case ALIASINFOALL: printf("ALIASINFOALL ignored\n"); break;
1010 status = dcerpc_samr_SetAliasInfo(p, tctx, &r);
1011 if (!NT_STATUS_IS_OK(status)) {
1012 printf("SetAliasInfo level %u failed - %s\n",
1013 levels[i], nt_errstr(status));
1017 q.in.alias_handle = handle;
1018 q.in.level = levels[i];
1021 status = dcerpc_samr_QueryAliasInfo(p, tctx, &q);
1022 if (!NT_STATUS_IS_OK(status)) {
1023 printf("QueryAliasInfo level %u failed - %s\n",
1024 levels[i], nt_errstr(status));
1032 static bool test_GetGroupsForUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1033 struct policy_handle *user_handle)
1035 struct samr_GetGroupsForUser r;
1036 struct samr_RidWithAttributeArray *rids = NULL;
1039 torture_comment(tctx, "testing GetGroupsForUser\n");
1041 r.in.user_handle = user_handle;
1044 status = dcerpc_samr_GetGroupsForUser(p, tctx, &r);
1045 torture_assert_ntstatus_ok(tctx, status, "GetGroupsForUser");
1051 static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1052 struct lsa_String *domain_name)
1055 struct samr_GetDomPwInfo r;
1056 struct samr_PwInfo info;
1058 r.in.domain_name = domain_name;
1061 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1063 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1064 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1066 r.in.domain_name->string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1067 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1069 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1070 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1072 r.in.domain_name->string = "\\\\__NONAME__";
1073 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1075 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1076 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1078 r.in.domain_name->string = "\\\\Builtin";
1079 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1081 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1082 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1087 static bool test_GetUserPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1088 struct policy_handle *handle)
1091 struct samr_GetUserPwInfo r;
1092 struct samr_PwInfo info;
1094 torture_comment(tctx, "Testing GetUserPwInfo\n");
1096 r.in.user_handle = handle;
1099 status = dcerpc_samr_GetUserPwInfo(p, tctx, &r);
1100 torture_assert_ntstatus_ok(tctx, status, "GetUserPwInfo");
1105 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, struct torture_context *tctx,
1106 struct policy_handle *domain_handle, const char *name,
1110 struct samr_LookupNames n;
1111 struct lsa_String sname[2];
1112 struct samr_Ids rids, types;
1114 init_lsa_String(&sname[0], name);
1116 n.in.domain_handle = domain_handle;
1120 n.out.types = &types;
1121 status = dcerpc_samr_LookupNames(p, tctx, &n);
1122 if (NT_STATUS_IS_OK(status)) {
1123 *rid = n.out.rids->ids[0];
1128 init_lsa_String(&sname[1], "xxNONAMExx");
1130 status = dcerpc_samr_LookupNames(p, tctx, &n);
1131 if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
1132 printf("LookupNames[2] failed - %s\n", nt_errstr(status));
1133 if (NT_STATUS_IS_OK(status)) {
1134 return NT_STATUS_UNSUCCESSFUL;
1140 status = dcerpc_samr_LookupNames(p, tctx, &n);
1141 if (!NT_STATUS_IS_OK(status)) {
1142 printf("LookupNames[0] failed - %s\n", nt_errstr(status));
1146 init_lsa_String(&sname[0], "xxNONAMExx");
1148 status = dcerpc_samr_LookupNames(p, tctx, &n);
1149 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1150 printf("LookupNames[1 bad name] failed - %s\n", nt_errstr(status));
1151 if (NT_STATUS_IS_OK(status)) {
1152 return NT_STATUS_UNSUCCESSFUL;
1157 init_lsa_String(&sname[0], "xxNONAMExx");
1158 init_lsa_String(&sname[1], "xxNONAME2xx");
1160 status = dcerpc_samr_LookupNames(p, tctx, &n);
1161 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1162 printf("LookupNames[2 bad names] failed - %s\n", nt_errstr(status));
1163 if (NT_STATUS_IS_OK(status)) {
1164 return NT_STATUS_UNSUCCESSFUL;
1169 return NT_STATUS_OK;
1172 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1173 struct policy_handle *domain_handle,
1174 const char *name, struct policy_handle *user_handle)
1177 struct samr_OpenUser r;
1180 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
1181 if (!NT_STATUS_IS_OK(status)) {
1185 r.in.domain_handle = domain_handle;
1186 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1188 r.out.user_handle = user_handle;
1189 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
1190 if (!NT_STATUS_IS_OK(status)) {
1191 printf("OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(status));
1198 static bool test_ChangePasswordNT3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1199 struct policy_handle *handle)
1202 struct samr_ChangePasswordUser r;
1204 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1205 struct policy_handle user_handle;
1206 char *oldpass = "test";
1207 char *newpass = "test2";
1208 uint8_t old_nt_hash[16], new_nt_hash[16];
1209 uint8_t old_lm_hash[16], new_lm_hash[16];
1211 status = test_OpenUser_byname(p, mem_ctx, handle, "testuser", &user_handle);
1212 if (!NT_STATUS_IS_OK(status)) {
1216 printf("Testing ChangePasswordUser for user 'testuser'\n");
1218 printf("old password: %s\n", oldpass);
1219 printf("new password: %s\n", newpass);
1221 E_md4hash(oldpass, old_nt_hash);
1222 E_md4hash(newpass, new_nt_hash);
1223 E_deshash(oldpass, old_lm_hash);
1224 E_deshash(newpass, new_lm_hash);
1226 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1227 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1228 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1229 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1230 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1231 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1233 r.in.handle = &user_handle;
1234 r.in.lm_present = 1;
1235 r.in.old_lm_crypted = &hash1;
1236 r.in.new_lm_crypted = &hash2;
1237 r.in.nt_present = 1;
1238 r.in.old_nt_crypted = &hash3;
1239 r.in.new_nt_crypted = &hash4;
1240 r.in.cross1_present = 1;
1241 r.in.nt_cross = &hash5;
1242 r.in.cross2_present = 1;
1243 r.in.lm_cross = &hash6;
1245 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1246 if (!NT_STATUS_IS_OK(status)) {
1247 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1251 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1259 static bool test_ChangePasswordUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1260 const char *acct_name,
1261 struct policy_handle *handle, char **password)
1264 struct samr_ChangePasswordUser r;
1266 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1267 struct policy_handle user_handle;
1269 uint8_t old_nt_hash[16], new_nt_hash[16];
1270 uint8_t old_lm_hash[16], new_lm_hash[16];
1271 bool changed = true;
1274 struct samr_GetUserPwInfo pwp;
1275 struct samr_PwInfo info;
1276 int policy_min_pw_len = 0;
1278 status = test_OpenUser_byname(p, tctx, handle, acct_name, &user_handle);
1279 if (!NT_STATUS_IS_OK(status)) {
1282 pwp.in.user_handle = &user_handle;
1283 pwp.out.info = &info;
1285 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1286 if (NT_STATUS_IS_OK(status)) {
1287 policy_min_pw_len = pwp.out.info->min_password_length;
1289 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1291 torture_comment(tctx, "Testing ChangePasswordUser\n");
1293 torture_assert(tctx, *password != NULL,
1294 "Failing ChangePasswordUser as old password was NULL. Previous test failed?");
1296 oldpass = *password;
1298 E_md4hash(oldpass, old_nt_hash);
1299 E_md4hash(newpass, new_nt_hash);
1300 E_deshash(oldpass, old_lm_hash);
1301 E_deshash(newpass, new_lm_hash);
1303 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1304 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1305 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1306 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1307 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1308 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1310 r.in.user_handle = &user_handle;
1311 r.in.lm_present = 1;
1312 /* Break the LM hash */
1314 r.in.old_lm_crypted = &hash1;
1315 r.in.new_lm_crypted = &hash2;
1316 r.in.nt_present = 1;
1317 r.in.old_nt_crypted = &hash3;
1318 r.in.new_nt_crypted = &hash4;
1319 r.in.cross1_present = 1;
1320 r.in.nt_cross = &hash5;
1321 r.in.cross2_present = 1;
1322 r.in.lm_cross = &hash6;
1324 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1325 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1326 "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash");
1328 /* Unbreak the LM hash */
1331 r.in.user_handle = &user_handle;
1332 r.in.lm_present = 1;
1333 r.in.old_lm_crypted = &hash1;
1334 r.in.new_lm_crypted = &hash2;
1335 /* Break the NT hash */
1337 r.in.nt_present = 1;
1338 r.in.old_nt_crypted = &hash3;
1339 r.in.new_nt_crypted = &hash4;
1340 r.in.cross1_present = 1;
1341 r.in.nt_cross = &hash5;
1342 r.in.cross2_present = 1;
1343 r.in.lm_cross = &hash6;
1345 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1346 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1347 "expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash");
1349 /* Unbreak the NT hash */
1352 r.in.user_handle = &user_handle;
1353 r.in.lm_present = 1;
1354 r.in.old_lm_crypted = &hash1;
1355 r.in.new_lm_crypted = &hash2;
1356 r.in.nt_present = 1;
1357 r.in.old_nt_crypted = &hash3;
1358 r.in.new_nt_crypted = &hash4;
1359 r.in.cross1_present = 1;
1360 r.in.nt_cross = &hash5;
1361 r.in.cross2_present = 1;
1362 /* Break the LM cross */
1364 r.in.lm_cross = &hash6;
1366 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1367 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1368 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status));
1372 /* Unbreak the LM cross */
1375 r.in.user_handle = &user_handle;
1376 r.in.lm_present = 1;
1377 r.in.old_lm_crypted = &hash1;
1378 r.in.new_lm_crypted = &hash2;
1379 r.in.nt_present = 1;
1380 r.in.old_nt_crypted = &hash3;
1381 r.in.new_nt_crypted = &hash4;
1382 r.in.cross1_present = 1;
1383 /* Break the NT cross */
1385 r.in.nt_cross = &hash5;
1386 r.in.cross2_present = 1;
1387 r.in.lm_cross = &hash6;
1389 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1390 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1391 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status));
1395 /* Unbreak the NT cross */
1399 /* Reset the hashes to not broken values */
1400 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1401 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1402 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1403 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1404 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1405 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1407 r.in.user_handle = &user_handle;
1408 r.in.lm_present = 1;
1409 r.in.old_lm_crypted = &hash1;
1410 r.in.new_lm_crypted = &hash2;
1411 r.in.nt_present = 1;
1412 r.in.old_nt_crypted = &hash3;
1413 r.in.new_nt_crypted = &hash4;
1414 r.in.cross1_present = 1;
1415 r.in.nt_cross = &hash5;
1416 r.in.cross2_present = 0;
1417 r.in.lm_cross = NULL;
1419 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1420 if (NT_STATUS_IS_OK(status)) {
1422 *password = newpass;
1423 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1424 printf("ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(status));
1429 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1431 E_md4hash(oldpass, old_nt_hash);
1432 E_md4hash(newpass, new_nt_hash);
1433 E_deshash(oldpass, old_lm_hash);
1434 E_deshash(newpass, new_lm_hash);
1437 /* Reset the hashes to not broken values */
1438 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1439 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1440 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1441 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1442 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1443 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1445 r.in.user_handle = &user_handle;
1446 r.in.lm_present = 1;
1447 r.in.old_lm_crypted = &hash1;
1448 r.in.new_lm_crypted = &hash2;
1449 r.in.nt_present = 1;
1450 r.in.old_nt_crypted = &hash3;
1451 r.in.new_nt_crypted = &hash4;
1452 r.in.cross1_present = 0;
1453 r.in.nt_cross = NULL;
1454 r.in.cross2_present = 1;
1455 r.in.lm_cross = &hash6;
1457 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1458 if (NT_STATUS_IS_OK(status)) {
1460 *password = newpass;
1461 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1462 printf("ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status));
1467 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1469 E_md4hash(oldpass, old_nt_hash);
1470 E_md4hash(newpass, new_nt_hash);
1471 E_deshash(oldpass, old_lm_hash);
1472 E_deshash(newpass, new_lm_hash);
1475 /* Reset the hashes to not broken values */
1476 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1477 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1478 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1479 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1480 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1481 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1483 r.in.user_handle = &user_handle;
1484 r.in.lm_present = 1;
1485 r.in.old_lm_crypted = &hash1;
1486 r.in.new_lm_crypted = &hash2;
1487 r.in.nt_present = 1;
1488 r.in.old_nt_crypted = &hash3;
1489 r.in.new_nt_crypted = &hash4;
1490 r.in.cross1_present = 1;
1491 r.in.nt_cross = &hash5;
1492 r.in.cross2_present = 1;
1493 r.in.lm_cross = &hash6;
1495 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1496 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1497 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1498 } else if (!NT_STATUS_IS_OK(status)) {
1499 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1503 *password = newpass;
1506 r.in.user_handle = &user_handle;
1507 r.in.lm_present = 1;
1508 r.in.old_lm_crypted = &hash1;
1509 r.in.new_lm_crypted = &hash2;
1510 r.in.nt_present = 1;
1511 r.in.old_nt_crypted = &hash3;
1512 r.in.new_nt_crypted = &hash4;
1513 r.in.cross1_present = 1;
1514 r.in.nt_cross = &hash5;
1515 r.in.cross2_present = 1;
1516 r.in.lm_cross = &hash6;
1519 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1520 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1521 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1522 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1523 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status));
1529 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
1537 static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
1538 const char *acct_name,
1539 struct policy_handle *handle, char **password)
1542 struct samr_OemChangePasswordUser2 r;
1544 struct samr_Password lm_verifier;
1545 struct samr_CryptPassword lm_pass;
1546 struct lsa_AsciiString server, account, account_bad;
1549 uint8_t old_lm_hash[16], new_lm_hash[16];
1551 struct samr_GetDomPwInfo dom_pw_info;
1552 struct samr_PwInfo info;
1553 int policy_min_pw_len = 0;
1555 struct lsa_String domain_name;
1557 domain_name.string = "";
1558 dom_pw_info.in.domain_name = &domain_name;
1559 dom_pw_info.out.info = &info;
1561 torture_comment(tctx, "Testing OemChangePasswordUser2\n");
1563 torture_assert(tctx, *password != NULL,
1564 "Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?");
1566 oldpass = *password;
1568 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
1569 if (NT_STATUS_IS_OK(status)) {
1570 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
1573 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1575 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1576 account.string = acct_name;
1578 E_deshash(oldpass, old_lm_hash);
1579 E_deshash(newpass, new_lm_hash);
1581 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1582 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1583 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1585 r.in.server = &server;
1586 r.in.account = &account;
1587 r.in.password = &lm_pass;
1588 r.in.hash = &lm_verifier;
1590 /* Break the verification */
1591 lm_verifier.hash[0]++;
1593 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1595 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1596 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1597 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1602 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1603 /* Break the old password */
1605 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1606 /* unbreak it for the next operation */
1608 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1610 r.in.server = &server;
1611 r.in.account = &account;
1612 r.in.password = &lm_pass;
1613 r.in.hash = &lm_verifier;
1615 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1617 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1618 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1619 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1624 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1625 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1627 r.in.server = &server;
1628 r.in.account = &account;
1629 r.in.password = &lm_pass;
1632 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1634 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1635 && !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1636 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
1641 /* This shouldn't be a valid name */
1642 account_bad.string = TEST_ACCOUNT_NAME "XX";
1643 r.in.account = &account_bad;
1645 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1647 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1648 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
1653 /* This shouldn't be a valid name */
1654 account_bad.string = TEST_ACCOUNT_NAME "XX";
1655 r.in.account = &account_bad;
1656 r.in.password = &lm_pass;
1657 r.in.hash = &lm_verifier;
1659 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1661 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1662 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1667 /* This shouldn't be a valid name */
1668 account_bad.string = TEST_ACCOUNT_NAME "XX";
1669 r.in.account = &account_bad;
1670 r.in.password = NULL;
1671 r.in.hash = &lm_verifier;
1673 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1675 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1676 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
1681 E_deshash(oldpass, old_lm_hash);
1682 E_deshash(newpass, new_lm_hash);
1684 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1685 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1686 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1688 r.in.server = &server;
1689 r.in.account = &account;
1690 r.in.password = &lm_pass;
1691 r.in.hash = &lm_verifier;
1693 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1694 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1695 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1696 } else if (!NT_STATUS_IS_OK(status)) {
1697 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
1700 *password = newpass;
1707 static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
1708 const char *acct_name,
1710 char *newpass, bool allow_password_restriction)
1713 struct samr_ChangePasswordUser2 r;
1715 struct lsa_String server, account;
1716 struct samr_CryptPassword nt_pass, lm_pass;
1717 struct samr_Password nt_verifier, lm_verifier;
1719 uint8_t old_nt_hash[16], new_nt_hash[16];
1720 uint8_t old_lm_hash[16], new_lm_hash[16];
1722 struct samr_GetDomPwInfo dom_pw_info;
1723 struct samr_PwInfo info;
1725 struct lsa_String domain_name;
1727 domain_name.string = "";
1728 dom_pw_info.in.domain_name = &domain_name;
1729 dom_pw_info.out.info = &info;
1731 torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name);
1733 torture_assert(tctx, *password != NULL,
1734 "Failing ChangePasswordUser2 as old password was NULL. Previous test failed?");
1735 oldpass = *password;
1738 int policy_min_pw_len = 0;
1739 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
1740 if (NT_STATUS_IS_OK(status)) {
1741 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
1744 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1747 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1748 init_lsa_String(&account, acct_name);
1750 E_md4hash(oldpass, old_nt_hash);
1751 E_md4hash(newpass, new_nt_hash);
1753 E_deshash(oldpass, old_lm_hash);
1754 E_deshash(newpass, new_lm_hash);
1756 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
1757 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1758 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1760 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1761 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1762 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1764 r.in.server = &server;
1765 r.in.account = &account;
1766 r.in.nt_password = &nt_pass;
1767 r.in.nt_verifier = &nt_verifier;
1769 r.in.lm_password = &lm_pass;
1770 r.in.lm_verifier = &lm_verifier;
1772 status = dcerpc_samr_ChangePasswordUser2(p, tctx, &r);
1773 if (allow_password_restriction && NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1774 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1775 } else if (!NT_STATUS_IS_OK(status)) {
1776 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
1779 *password = newpass;
1786 bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tctx,
1787 const char *account_string,
1788 int policy_min_pw_len,
1790 const char *newpass,
1791 NTTIME last_password_change,
1792 bool handle_reject_reason)
1795 struct samr_ChangePasswordUser3 r;
1797 struct lsa_String server, account, account_bad;
1798 struct samr_CryptPassword nt_pass, lm_pass;
1799 struct samr_Password nt_verifier, lm_verifier;
1801 uint8_t old_nt_hash[16], new_nt_hash[16];
1802 uint8_t old_lm_hash[16], new_lm_hash[16];
1804 struct samr_DomInfo1 *dominfo = NULL;
1805 struct samr_ChangeReject *reject = NULL;
1807 torture_comment(tctx, "Testing ChangePasswordUser3\n");
1809 if (newpass == NULL) {
1811 if (policy_min_pw_len == 0) {
1812 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1814 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len);
1816 } while (check_password_quality(newpass) == false);
1818 torture_comment(tctx, "Using password '%s'\n", newpass);
1821 torture_assert(tctx, *password != NULL,
1822 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
1824 oldpass = *password;
1825 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1826 init_lsa_String(&account, account_string);
1828 E_md4hash(oldpass, old_nt_hash);
1829 E_md4hash(newpass, new_nt_hash);
1831 E_deshash(oldpass, old_lm_hash);
1832 E_deshash(newpass, new_lm_hash);
1834 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1835 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1836 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1838 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1839 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1840 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1842 /* Break the verification */
1843 nt_verifier.hash[0]++;
1845 r.in.server = &server;
1846 r.in.account = &account;
1847 r.in.nt_password = &nt_pass;
1848 r.in.nt_verifier = &nt_verifier;
1850 r.in.lm_password = &lm_pass;
1851 r.in.lm_verifier = &lm_verifier;
1852 r.in.password3 = NULL;
1853 r.out.dominfo = &dominfo;
1854 r.out.reject = &reject;
1856 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1857 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1858 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1859 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1864 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1865 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1866 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1868 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1869 /* Break the NT hash */
1871 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1872 /* Unbreak it again */
1874 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1876 r.in.server = &server;
1877 r.in.account = &account;
1878 r.in.nt_password = &nt_pass;
1879 r.in.nt_verifier = &nt_verifier;
1881 r.in.lm_password = &lm_pass;
1882 r.in.lm_verifier = &lm_verifier;
1883 r.in.password3 = NULL;
1884 r.out.dominfo = &dominfo;
1885 r.out.reject = &reject;
1887 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1888 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1889 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1890 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1895 /* This shouldn't be a valid name */
1896 init_lsa_String(&account_bad, talloc_asprintf(tctx, "%sXX", account_string));
1898 r.in.account = &account_bad;
1899 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1900 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1901 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
1906 E_md4hash(oldpass, old_nt_hash);
1907 E_md4hash(newpass, new_nt_hash);
1909 E_deshash(oldpass, old_lm_hash);
1910 E_deshash(newpass, new_lm_hash);
1912 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1913 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1914 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1916 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1917 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1918 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1920 r.in.server = &server;
1921 r.in.account = &account;
1922 r.in.nt_password = &nt_pass;
1923 r.in.nt_verifier = &nt_verifier;
1925 r.in.lm_password = &lm_pass;
1926 r.in.lm_verifier = &lm_verifier;
1927 r.in.password3 = NULL;
1928 r.out.dominfo = &dominfo;
1929 r.out.reject = &reject;
1931 unix_to_nt_time(&t, time(NULL));
1933 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1935 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1938 && handle_reject_reason
1939 && (!null_nttime(last_password_change) || !dominfo->min_password_age)) {
1940 if (dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
1942 if (reject && (reject->reason != SAMR_REJECT_OTHER)) {
1943 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1944 SAMR_REJECT_OTHER, reject->reason);
1949 /* We tested the order of precendence which is as follows:
1958 if ((dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
1959 (last_password_change + dominfo->min_password_age > t)) {
1961 if (reject->reason != SAMR_REJECT_OTHER) {
1962 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1963 SAMR_REJECT_OTHER, reject->reason);
1967 } else if ((dominfo->min_password_length > 0) &&
1968 (strlen(newpass) < dominfo->min_password_length)) {
1970 if (reject->reason != SAMR_REJECT_TOO_SHORT) {
1971 printf("expected SAMR_REJECT_TOO_SHORT (%d), got %d\n",
1972 SAMR_REJECT_TOO_SHORT, reject->reason);
1976 } else if ((dominfo->password_history_length > 0) &&
1977 strequal(oldpass, newpass)) {
1979 if (reject->reason != SAMR_REJECT_IN_HISTORY) {
1980 printf("expected SAMR_REJECT_IN_HISTORY (%d), got %d\n",
1981 SAMR_REJECT_IN_HISTORY, reject->reason);
1984 } else if (dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
1986 if (reject->reason != SAMR_REJECT_COMPLEXITY) {
1987 printf("expected SAMR_REJECT_COMPLEXITY (%d), got %d\n",
1988 SAMR_REJECT_COMPLEXITY, reject->reason);
1994 if (reject->reason == SAMR_REJECT_TOO_SHORT) {
1995 /* retry with adjusted size */
1996 return test_ChangePasswordUser3(p, tctx, account_string,
1997 dominfo->min_password_length,
1998 password, NULL, 0, false);
2002 } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2003 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2004 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2005 SAMR_REJECT_OTHER, reject->reason);
2008 /* Perhaps the server has a 'min password age' set? */
2011 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3");
2012 *password = talloc_strdup(tctx, newpass);
2018 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_context *tctx,
2019 const char *account_string,
2020 struct policy_handle *handle,
2024 struct samr_ChangePasswordUser3 r;
2025 struct samr_SetUserInfo s;
2026 union samr_UserInfo u;
2027 DATA_BLOB session_key;
2028 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
2029 uint8_t confounder[16];
2030 struct MD5Context ctx;
2033 struct lsa_String server, account;
2034 struct samr_CryptPassword nt_pass;
2035 struct samr_Password nt_verifier;
2036 DATA_BLOB new_random_pass;
2039 uint8_t old_nt_hash[16], new_nt_hash[16];
2041 struct samr_DomInfo1 *dominfo = NULL;
2042 struct samr_ChangeReject *reject = NULL;
2044 new_random_pass = samr_very_rand_pass(tctx, 128);
2046 torture_assert(tctx, *password != NULL,
2047 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2049 oldpass = *password;
2050 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2051 init_lsa_String(&account, account_string);
2053 s.in.user_handle = handle;
2059 u.info25.info.fields_present = SAMR_FIELD_PASSWORD;
2061 set_pw_in_buffer(u.info25.password.data, &new_random_pass);
2063 status = dcerpc_fetch_session_key(p, &session_key);
2064 if (!NT_STATUS_IS_OK(status)) {
2065 printf("SetUserInfo level %u - no session key - %s\n",
2066 s.in.level, nt_errstr(status));
2070 generate_random_buffer((uint8_t *)confounder, 16);
2073 MD5Update(&ctx, confounder, 16);
2074 MD5Update(&ctx, session_key.data, session_key.length);
2075 MD5Final(confounded_session_key.data, &ctx);
2077 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
2078 memcpy(&u.info25.password.data[516], confounder, 16);
2080 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
2082 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
2083 if (!NT_STATUS_IS_OK(status)) {
2084 printf("SetUserInfo level %u failed - %s\n",
2085 s.in.level, nt_errstr(status));
2089 torture_comment(tctx, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
2091 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2093 new_random_pass = samr_very_rand_pass(tctx, 128);
2095 mdfour(new_nt_hash, new_random_pass.data, new_random_pass.length);
2097 set_pw_in_buffer(nt_pass.data, &new_random_pass);
2098 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2099 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2101 r.in.server = &server;
2102 r.in.account = &account;
2103 r.in.nt_password = &nt_pass;
2104 r.in.nt_verifier = &nt_verifier;
2106 r.in.lm_password = NULL;
2107 r.in.lm_verifier = NULL;
2108 r.in.password3 = NULL;
2109 r.out.dominfo = &dominfo;
2110 r.out.reject = &reject;
2112 unix_to_nt_time(&t, time(NULL));
2114 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2116 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2117 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2118 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2119 SAMR_REJECT_OTHER, reject->reason);
2122 /* Perhaps the server has a 'min password age' set? */
2124 } else if (!NT_STATUS_IS_OK(status)) {
2125 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
2129 newpass = samr_rand_pass(tctx, 128);
2131 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2133 E_md4hash(newpass, new_nt_hash);
2135 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2136 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2137 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2139 r.in.server = &server;
2140 r.in.account = &account;
2141 r.in.nt_password = &nt_pass;
2142 r.in.nt_verifier = &nt_verifier;
2144 r.in.lm_password = NULL;
2145 r.in.lm_verifier = NULL;
2146 r.in.password3 = NULL;
2147 r.out.dominfo = &dominfo;
2148 r.out.reject = &reject;
2150 unix_to_nt_time(&t, time(NULL));
2152 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2154 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2155 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2156 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2157 SAMR_REJECT_OTHER, reject->reason);
2160 /* Perhaps the server has a 'min password age' set? */
2163 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3 (on second random password)");
2164 *password = talloc_strdup(tctx, newpass);
2171 static bool test_GetMembersInAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2172 struct policy_handle *alias_handle)
2174 struct samr_GetMembersInAlias r;
2175 struct lsa_SidArray sids;
2178 torture_comment(tctx, "Testing GetMembersInAlias\n");
2180 r.in.alias_handle = alias_handle;
2183 status = dcerpc_samr_GetMembersInAlias(p, tctx, &r);
2184 torture_assert_ntstatus_ok(tctx, status, "GetMembersInAlias");
2189 static bool test_AddMemberToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2190 struct policy_handle *alias_handle,
2191 const struct dom_sid *domain_sid)
2193 struct samr_AddAliasMember r;
2194 struct samr_DeleteAliasMember d;
2196 struct dom_sid *sid;
2198 sid = dom_sid_add_rid(tctx, domain_sid, 512);
2200 torture_comment(tctx, "testing AddAliasMember\n");
2201 r.in.alias_handle = alias_handle;
2204 status = dcerpc_samr_AddAliasMember(p, tctx, &r);
2205 torture_assert_ntstatus_ok(tctx, status, "AddAliasMember");
2207 d.in.alias_handle = alias_handle;
2210 status = dcerpc_samr_DeleteAliasMember(p, tctx, &d);
2211 torture_assert_ntstatus_ok(tctx, status, "DelAliasMember");
2216 static bool test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2217 struct policy_handle *alias_handle)
2219 struct samr_AddMultipleMembersToAlias a;
2220 struct samr_RemoveMultipleMembersFromAlias r;
2222 struct lsa_SidArray sids;
2224 torture_comment(tctx, "testing AddMultipleMembersToAlias\n");
2225 a.in.alias_handle = alias_handle;
2229 sids.sids = talloc_array(tctx, struct lsa_SidPtr, 3);
2231 sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2232 sids.sids[1].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-2");
2233 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-3");
2235 status = dcerpc_samr_AddMultipleMembersToAlias(p, tctx, &a);
2236 torture_assert_ntstatus_ok(tctx, status, "AddMultipleMembersToAlias");
2239 torture_comment(tctx, "testing RemoveMultipleMembersFromAlias\n");
2240 r.in.alias_handle = alias_handle;
2243 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2244 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2246 /* strange! removing twice doesn't give any error */
2247 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2248 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2250 /* but removing an alias that isn't there does */
2251 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-4");
2253 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2254 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, "RemoveMultipleMembersFromAlias");
2259 static bool test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2260 struct policy_handle *user_handle)
2262 struct samr_TestPrivateFunctionsUser r;
2265 torture_comment(tctx, "Testing TestPrivateFunctionsUser\n");
2267 r.in.user_handle = user_handle;
2269 status = dcerpc_samr_TestPrivateFunctionsUser(p, tctx, &r);
2270 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsUser");
2275 static bool test_QueryUserInfo_pwdlastset(struct dcerpc_pipe *p,
2276 struct torture_context *tctx,
2277 struct policy_handle *handle,
2282 uint16_t levels[] = { /* 3, */ 5, 21 };
2284 NTTIME pwdlastset3 = 0;
2285 NTTIME pwdlastset5 = 0;
2286 NTTIME pwdlastset21 = 0;
2288 torture_comment(tctx, "Testing QueryUserInfo%s level 5 and 21 call ",
2289 use_info2 ? "2":"");
2291 for (i=0; i<ARRAY_SIZE(levels); i++) {
2293 struct samr_QueryUserInfo r;
2294 struct samr_QueryUserInfo2 r2;
2295 union samr_UserInfo *info;
2298 r2.in.user_handle = handle;
2299 r2.in.level = levels[i];
2300 r2.out.info = &info;
2301 status = dcerpc_samr_QueryUserInfo2(p, tctx, &r2);
2304 r.in.user_handle = handle;
2305 r.in.level = levels[i];
2307 status = dcerpc_samr_QueryUserInfo(p, tctx, &r);
2310 if (!NT_STATUS_IS_OK(status) &&
2311 !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
2312 printf("QueryUserInfo%s level %u failed - %s\n",
2313 use_info2 ? "2":"", levels[i], nt_errstr(status));
2317 switch (levels[i]) {
2319 pwdlastset3 = info->info3.last_password_change;
2322 pwdlastset5 = info->info5.last_password_change;
2325 pwdlastset21 = info->info21.last_password_change;
2331 /* torture_assert_int_equal(tctx, pwdlastset3, pwdlastset5,
2332 "pwdlastset mixup"); */
2333 torture_assert_int_equal(tctx, pwdlastset5, pwdlastset21,
2334 "pwdlastset mixup");
2336 *pwdlastset = pwdlastset21;
2338 torture_comment(tctx, "(pwdlastset: %lld)\n", *pwdlastset);
2343 static bool test_SetPassword_level(struct dcerpc_pipe *p,
2344 struct torture_context *tctx,
2345 struct policy_handle *handle,
2347 uint32_t fields_present,
2348 uint8_t password_expired,
2349 NTSTATUS expected_error,
2352 bool use_queryinfo2,
2355 const char *fields = NULL;
2362 fields = talloc_asprintf(tctx, "(fields_present: 0x%08x)",
2369 torture_comment(tctx, "Testing SetUserInfo%s level %d call "
2370 "(password_expired: %d) %s\n",
2371 use_setinfo2 ? "2":"", level, password_expired,
2372 fields ? fields : "");
2380 if (!test_SetUserPass_level_ex(p, tctx, handle, level,
2393 if (!test_QueryUserInfo_pwdlastset(p, tctx, handle,
2402 static bool test_SetPassword_pwdlastset(struct dcerpc_pipe *p,
2403 struct torture_context *tctx,
2404 uint32_t acct_flags,
2405 struct policy_handle *handle,
2411 bool set_levels[] = { false, true };
2412 bool query_levels[] = { false, true };
2416 uint8_t password_expired_nonzero;
2417 uint32_t fields_present;
2426 .password_expired_nonzero = 1,
2427 .fields_present = SAMR_FIELD_EXPIRED_FLAG
2430 .password_expired_nonzero = 1,
2431 .fields_present = SAMR_FIELD_LAST_PWD_CHANGE,
2432 .set_error = NT_STATUS_ACCESS_DENIED
2437 .password_expired_nonzero = 1,
2438 .fields_present = SAMR_FIELD_PASSWORD |
2439 SAMR_FIELD_PASSWORD2 |
2440 SAMR_FIELD_LAST_PWD_CHANGE,
2441 .query_info2 = false,
2442 .set_error = NT_STATUS_ACCESS_DENIED
2448 .password_expired_nonzero = 1,
2449 .fields_present = SAMR_FIELD_EXPIRED_FLAG
2452 .password_expired_nonzero = 1,
2453 .fields_present = SAMR_FIELD_LAST_PWD_CHANGE,
2454 .set_error = NT_STATUS_ACCESS_DENIED
2457 .password_expired_nonzero = 1,
2458 .fields_present = SAMR_FIELD_LAST_PWD_CHANGE |
2459 SAMR_FIELD_PASSWORD |
2460 SAMR_FIELD_PASSWORD2,
2461 .set_error = NT_STATUS_ACCESS_DENIED
2464 .password_expired_nonzero = 1,
2465 .fields_present = SAMR_FIELD_LAST_PWD_CHANGE |
2466 SAMR_FIELD_PASSWORD |
2467 SAMR_FIELD_PASSWORD2 |
2468 SAMR_FIELD_EXPIRED_FLAG,
2469 .set_error = NT_STATUS_ACCESS_DENIED
2472 .password_expired_nonzero = 1,
2473 .fields_present = SAMR_FIELD_PASSWORD |
2474 SAMR_FIELD_PASSWORD2 |
2475 SAMR_FIELD_EXPIRED_FLAG
2478 .password_expired_nonzero = 1,
2479 .fields_present = SAMR_FIELD_PASSWORD |
2480 SAMR_FIELD_PASSWORD2
2486 .password_expired_nonzero = 1
2489 .password_expired_nonzero = 24
2495 .password_expired_nonzero = 1,
2496 .fields_present = SAMR_FIELD_LAST_PWD_CHANGE,
2497 .set_error = NT_STATUS_ACCESS_DENIED
2500 .password_expired_nonzero = 1,
2501 .fields_present = SAMR_FIELD_EXPIRED_FLAG,
2504 .password_expired_nonzero = 1,
2505 .fields_present = SAMR_FIELD_PASSWORD |
2506 SAMR_FIELD_PASSWORD2 |
2507 SAMR_FIELD_EXPIRED_FLAG
2510 .password_expired_nonzero = 1,
2511 .fields_present = SAMR_FIELD_PASSWORD |
2512 SAMR_FIELD_PASSWORD2
2518 .password_expired_nonzero = 1
2521 .password_expired_nonzero = 24
2525 if (torture_setting_bool(tctx, "samba3", false)) {
2527 printf("Samba3 has second granularity, setting delay to: %d\n",
2532 for (i=0; i<ARRAY_SIZE(pwd_tests); i++) {
2533 for (s=0; s<ARRAY_SIZE(set_levels); s++) {
2534 for (q=0; q<ARRAY_SIZE(query_levels); q++) {
2536 NTTIME pwdlastset_old = 0;
2537 NTTIME pwdlastset_new = 0;
2541 torture_comment(tctx, "------------------------------\n"
2542 "Testing pwdLastSet attribute for flags: 0x%08x "
2543 "(s: %d (l: %d), q: %d)\n",
2544 acct_flags, s, pwd_tests[i].level, q);
2546 if (!test_SetPassword_level(p, tctx, handle,
2548 pwd_tests[i].fields_present,
2549 pwd_tests[i].password_expired_nonzero, /* will set pwdlast to 0 */
2550 pwd_tests[i].set_error,
2558 if (!NT_STATUS_IS_OK(pwd_tests[i].set_error)) {
2559 /* skipping on expected failure */
2563 /* pwdlastset must be 0 afterwards, except for a level 23 and 25
2564 * set without the SAMR_FIELD_EXPIRED_FLAG */
2566 switch (pwd_tests[i].level) {
2569 if ((pwdlastset_new != 0) &&
2570 !(pwd_tests[i].fields_present & SAMR_FIELD_EXPIRED_FLAG)) {
2571 torture_comment(tctx, "not considering a non-0 "
2572 "pwdLastSet as a an error as the "
2573 "SAMR_FIELD_EXPIRED_FLAG has not "
2578 if (pwdlastset_new != 0) {
2579 torture_warning(tctx, "pwdLastSet test failed: "
2580 "expected pwdLastSet 0 but got %lld\n",
2591 if (!test_SetPassword_level(p, tctx, handle, pwd_tests[i].level,
2592 pwd_tests[i].fields_present,
2594 /* will normally update (increase) the pwdlast */
2595 pwd_tests[i].set_error,
2604 /* pwdlastset must not be 0 afterwards and must be larger then
2607 if (pwdlastset_old >= pwdlastset_new) {
2608 torture_warning(tctx, "pwdLastSet test failed: "
2609 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
2610 pwdlastset_old, pwdlastset_new);
2613 if (pwdlastset_new == 0) {
2614 torture_warning(tctx, "pwdLastSet test failed: "
2615 "expected non-0 pwdlastset, got: %lld\n",
2619 pwdlastset_old = pwdlastset_new;
2625 if (!test_SetPassword_level(p, tctx, handle, pwd_tests[i].level,
2626 pwd_tests[i].fields_present,
2627 pwd_tests[i].password_expired_nonzero,
2628 pwd_tests[i].set_error,
2636 if (pwdlastset_old == pwdlastset_new) {
2637 torture_warning(tctx, "pwdLastSet test failed: "
2638 "expected last pwdlastset (%lld) != new pwdlastset (%lld)\n",
2639 pwdlastset_old, pwdlastset_new);
2643 /* pwdlastset must be 0 afterwards, except for a level 23 and 25
2644 * set without the SAMR_FIELD_EXPIRED_FLAG */
2646 switch (pwd_tests[i].level) {
2649 if ((pwdlastset_new != 0) &&
2650 !(pwd_tests[i].fields_present & SAMR_FIELD_EXPIRED_FLAG)) {
2654 if (pwdlastset_new != 0) {
2655 torture_warning(tctx, "pwdLastSet test failed: "
2656 "expected pwdLastSet 0, got %lld\n",
2669 static bool test_user_ops(struct dcerpc_pipe *p,
2670 struct torture_context *tctx,
2671 struct policy_handle *user_handle,
2672 struct policy_handle *domain_handle,
2673 uint32_t base_acct_flags,
2674 const char *base_acct_name, enum torture_samr_choice which_ops)
2676 char *password = NULL;
2677 struct samr_QueryUserInfo q;
2678 union samr_UserInfo *info;
2684 const uint32_t password_fields[] = {
2685 SAMR_FIELD_PASSWORD,
2686 SAMR_FIELD_PASSWORD2,
2687 SAMR_FIELD_PASSWORD | SAMR_FIELD_PASSWORD2,
2691 status = test_LookupName(p, tctx, domain_handle, base_acct_name, &rid);
2692 if (!NT_STATUS_IS_OK(status)) {
2696 switch (which_ops) {
2697 case TORTURE_SAMR_USER_ATTRIBUTES:
2698 if (!test_QuerySecurity(p, tctx, user_handle)) {
2702 if (!test_QueryUserInfo(p, tctx, user_handle)) {
2706 if (!test_QueryUserInfo2(p, tctx, user_handle)) {
2710 if (!test_SetUserInfo(p, tctx, user_handle, base_acct_flags,
2715 if (!test_GetUserPwInfo(p, tctx, user_handle)) {
2719 if (!test_TestPrivateFunctionsUser(p, tctx, user_handle)) {
2723 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
2727 case TORTURE_SAMR_PASSWORDS:
2728 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
2729 char simple_pass[9];
2730 char *v = generate_random_str(tctx, 1);
2732 ZERO_STRUCT(simple_pass);
2733 memset(simple_pass, *v, sizeof(simple_pass) - 1);
2735 printf("Testing machine account password policy rules\n");
2737 /* Workstation trust accounts don't seem to need to honour password quality policy */
2738 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
2742 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
2746 /* reset again, to allow another 'user' password change */
2747 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
2751 /* Try a 'short' password */
2752 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
2756 /* Try a compleatly random password */
2757 if (!test_ChangePasswordRandomBytes(p, tctx, base_acct_name, user_handle, &password)) {
2762 /* test last password change timestamp behaviour */
2763 if (!test_SetPassword_pwdlastset(p, tctx, user_handle, &password)) {
2767 for (i = 0; password_fields[i]; i++) {
2768 if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
2772 /* check it was set right */
2773 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
2778 for (i = 0; password_fields[i]; i++) {
2779 if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
2783 /* check it was set right */
2784 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
2789 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
2793 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
2797 q.in.user_handle = user_handle;
2801 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
2802 if (!NT_STATUS_IS_OK(status)) {
2803 printf("QueryUserInfo level %u failed - %s\n",
2804 q.in.level, nt_errstr(status));
2807 uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
2808 if ((info->info5.acct_flags) != expected_flags) {
2809 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2810 info->info5.acct_flags,
2814 if (info->info5.rid != rid) {
2815 printf("QuerUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
2816 info->info5.rid, rid);
2822 case TORTURE_SAMR_OTHER:
2823 /* We just need the account to exist */
2829 static bool test_alias_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
2830 struct policy_handle *alias_handle,
2831 const struct dom_sid *domain_sid)
2835 if (!test_QuerySecurity(p, tctx, alias_handle)) {
2839 if (!test_QueryAliasInfo(p, tctx, alias_handle)) {
2843 if (!test_SetAliasInfo(p, tctx, alias_handle)) {
2847 if (!test_AddMemberToAlias(p, tctx, alias_handle, domain_sid)) {
2851 if (torture_setting_bool(tctx, "samba4", false)) {
2852 printf("skipping MultipleMembers Alias tests against Samba4\n");
2856 if (!test_AddMultipleMembersToAlias(p, tctx, alias_handle)) {
2864 static bool test_DeleteUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2865 struct policy_handle *user_handle)
2867 struct samr_DeleteUser d;
2869 torture_comment(tctx, "Testing DeleteUser\n");
2871 d.in.user_handle = user_handle;
2872 d.out.user_handle = user_handle;
2874 status = dcerpc_samr_DeleteUser(p, tctx, &d);
2875 torture_assert_ntstatus_ok(tctx, status, "DeleteUser");
2880 bool test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2881 struct policy_handle *handle, const char *name)
2884 struct samr_DeleteUser d;
2885 struct policy_handle user_handle;
2888 status = test_LookupName(p, mem_ctx, handle, name, &rid);
2889 if (!NT_STATUS_IS_OK(status)) {
2893 status = test_OpenUser_byname(p, mem_ctx, handle, name, &user_handle);
2894 if (!NT_STATUS_IS_OK(status)) {
2898 d.in.user_handle = &user_handle;
2899 d.out.user_handle = &user_handle;
2900 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
2901 if (!NT_STATUS_IS_OK(status)) {
2908 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
2913 static bool test_DeleteGroup_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2914 struct policy_handle *handle, const char *name)
2917 struct samr_OpenGroup r;
2918 struct samr_DeleteDomainGroup d;
2919 struct policy_handle group_handle;
2922 status = test_LookupName(p, mem_ctx, handle, name, &rid);
2923 if (!NT_STATUS_IS_OK(status)) {
2927 r.in.domain_handle = handle;
2928 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2930 r.out.group_handle = &group_handle;
2931 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
2932 if (!NT_STATUS_IS_OK(status)) {
2936 d.in.group_handle = &group_handle;
2937 d.out.group_handle = &group_handle;
2938 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
2939 if (!NT_STATUS_IS_OK(status)) {
2946 printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
2951 static bool test_DeleteAlias_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2952 struct policy_handle *domain_handle, const char *name)
2955 struct samr_OpenAlias r;
2956 struct samr_DeleteDomAlias d;
2957 struct policy_handle alias_handle;
2960 printf("testing DeleteAlias_byname\n");
2962 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
2963 if (!NT_STATUS_IS_OK(status)) {
2967 r.in.domain_handle = domain_handle;
2968 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2970 r.out.alias_handle = &alias_handle;
2971 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
2972 if (!NT_STATUS_IS_OK(status)) {
2976 d.in.alias_handle = &alias_handle;
2977 d.out.alias_handle = &alias_handle;
2978 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
2979 if (!NT_STATUS_IS_OK(status)) {
2986 printf("DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
2990 static bool test_DeleteAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2991 struct policy_handle *alias_handle)
2993 struct samr_DeleteDomAlias d;
2996 printf("Testing DeleteAlias\n");
2998 d.in.alias_handle = alias_handle;
2999 d.out.alias_handle = alias_handle;
3001 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
3002 if (!NT_STATUS_IS_OK(status)) {
3003 printf("DeleteAlias failed - %s\n", nt_errstr(status));
3010 static bool test_CreateAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
3011 struct policy_handle *domain_handle,
3012 struct policy_handle *alias_handle,
3013 const struct dom_sid *domain_sid)
3016 struct samr_CreateDomAlias r;
3017 struct lsa_String name;
3021 init_lsa_String(&name, TEST_ALIASNAME);
3022 r.in.domain_handle = domain_handle;
3023 r.in.alias_name = &name;
3024 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3025 r.out.alias_handle = alias_handle;
3028 printf("Testing CreateAlias (%s)\n", r.in.alias_name->string);
3030 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
3032 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
3033 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
3034 printf("Server correctly refused create of '%s'\n", r.in.alias_name->string);
3037 printf("Server should have refused create of '%s', got %s instead\n", r.in.alias_name->string,
3043 if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
3044 if (!test_DeleteAlias_byname(p, tctx, domain_handle, r.in.alias_name->string)) {
3047 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
3050 if (!NT_STATUS_IS_OK(status)) {
3051 printf("CreateAlias failed - %s\n", nt_errstr(status));
3055 if (!test_alias_ops(p, tctx, alias_handle, domain_sid)) {
3062 static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3063 const char *acct_name,
3064 struct policy_handle *domain_handle, char **password)
3072 if (!test_ChangePasswordUser(p, mem_ctx, acct_name, domain_handle, password)) {
3076 if (!test_ChangePasswordUser2(p, mem_ctx, acct_name, password, 0, true)) {
3080 if (!test_OemChangePasswordUser2(p, mem_ctx, acct_name, domain_handle, password)) {
3084 /* test what happens when setting the old password again */
3085 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, *password, 0, true)) {
3090 char simple_pass[9];
3091 char *v = generate_random_str(mem_ctx, 1);
3093 ZERO_STRUCT(simple_pass);
3094 memset(simple_pass, *v, sizeof(simple_pass) - 1);
3096 /* test what happens when picking a simple password */
3097 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, simple_pass, 0, true)) {
3102 /* set samr_SetDomainInfo level 1 with min_length 5 */
3104 struct samr_QueryDomainInfo r;
3105 union samr_DomainInfo *info = NULL;
3106 struct samr_SetDomainInfo s;
3107 uint16_t len_old, len;
3108 uint32_t pwd_prop_old;
3109 int64_t min_pwd_age_old;
3114 r.in.domain_handle = domain_handle;
3118 printf("testing samr_QueryDomainInfo level 1\n");
3119 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
3120 if (!NT_STATUS_IS_OK(status)) {
3124 s.in.domain_handle = domain_handle;
3128 /* remember the old min length, so we can reset it */
3129 len_old = s.in.info->info1.min_password_length;
3130 s.in.info->info1.min_password_length = len;
3131 pwd_prop_old = s.in.info->info1.password_properties;
3132 /* turn off password complexity checks for this test */
3133 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
3135 min_pwd_age_old = s.in.info->info1.min_password_age;
3136 s.in.info->info1.min_password_age = 0;
3138 printf("testing samr_SetDomainInfo level 1\n");
3139 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
3140 if (!NT_STATUS_IS_OK(status)) {
3144 printf("calling test_ChangePasswordUser3 with too short password\n");
3146 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, len - 1, password, NULL, 0, true)) {
3150 s.in.info->info1.min_password_length = len_old;
3151 s.in.info->info1.password_properties = pwd_prop_old;
3152 s.in.info->info1.min_password_age = min_pwd_age_old;
3154 printf("testing samr_SetDomainInfo level 1\n");
3155 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
3156 if (!NT_STATUS_IS_OK(status)) {
3164 struct samr_OpenUser r;
3165 struct samr_QueryUserInfo q;
3166 union samr_UserInfo *info;
3167 struct samr_LookupNames n;
3168 struct policy_handle user_handle;
3169 struct samr_Ids rids, types;
3171 n.in.domain_handle = domain_handle;
3173 n.in.names = talloc_array(mem_ctx, struct lsa_String, 1);
3174 n.in.names[0].string = acct_name;
3176 n.out.types = &types;
3178 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
3179 if (!NT_STATUS_IS_OK(status)) {
3180 printf("LookupNames failed - %s\n", nt_errstr(status));
3184 r.in.domain_handle = domain_handle;
3185 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3186 r.in.rid = n.out.rids->ids[0];
3187 r.out.user_handle = &user_handle;
3189 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3190 if (!NT_STATUS_IS_OK(status)) {
3191 printf("OpenUser(%u) failed - %s\n", n.out.rids->ids[0], nt_errstr(status));
3195 q.in.user_handle = &user_handle;
3199 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
3200 if (!NT_STATUS_IS_OK(status)) {
3201 printf("QueryUserInfo failed - %s\n", nt_errstr(status));
3205 printf("calling test_ChangePasswordUser3 with too early password change\n");
3207 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL,
3208 info->info5.last_password_change, true)) {
3213 /* we change passwords twice - this has the effect of verifying
3214 they were changed correctly for the final call */
3215 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, true)) {
3219 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, true)) {
3226 static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
3227 struct policy_handle *domain_handle,
3228 struct policy_handle *user_handle_out,
3229 struct dom_sid *domain_sid,
3230 enum torture_samr_choice which_ops)
3233 TALLOC_CTX *user_ctx;
3236 struct samr_CreateUser r;
3237 struct samr_QueryUserInfo q;
3238 union samr_UserInfo *info;
3239 struct samr_DeleteUser d;
3242 /* This call creates a 'normal' account - check that it really does */
3243 const uint32_t acct_flags = ACB_NORMAL;
3244 struct lsa_String name;
3247 struct policy_handle user_handle;
3248 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
3249 init_lsa_String(&name, TEST_ACCOUNT_NAME);
3251 r.in.domain_handle = domain_handle;
3252 r.in.account_name = &name;
3253 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3254 r.out.user_handle = &user_handle;
3257 printf("Testing CreateUser(%s)\n", r.in.account_name->string);
3259 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
3261 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
3262 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
3263 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
3266 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
3272 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
3273 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
3274 talloc_free(user_ctx);
3277 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
3279 if (!NT_STATUS_IS_OK(status)) {
3280 talloc_free(user_ctx);
3281 printf("CreateUser failed - %s\n", nt_errstr(status));
3284 q.in.user_handle = &user_handle;
3288 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
3289 if (!NT_STATUS_IS_OK(status)) {
3290 printf("QueryUserInfo level %u failed - %s\n",
3291 q.in.level, nt_errstr(status));
3294 if ((info->info16.acct_flags & acct_flags) != acct_flags) {
3295 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
3296 info->info16.acct_flags,
3302 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
3303 acct_flags, name.string, which_ops)) {
3307 if (user_handle_out) {
3308 *user_handle_out = user_handle;
3310 printf("Testing DeleteUser (createuser test)\n");
3312 d.in.user_handle = &user_handle;
3313 d.out.user_handle = &user_handle;
3315 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
3316 if (!NT_STATUS_IS_OK(status)) {
3317 printf("DeleteUser failed - %s\n", nt_errstr(status));
3324 talloc_free(user_ctx);
3330 static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
3331 struct policy_handle *domain_handle,
3332 struct dom_sid *domain_sid,
3333 enum torture_samr_choice which_ops)
3336 struct samr_CreateUser2 r;
3337 struct samr_QueryUserInfo q;
3338 union samr_UserInfo *info;
3339 struct samr_DeleteUser d;
3340 struct policy_handle user_handle;
3342 struct lsa_String name;
3347 uint32_t acct_flags;
3348 const char *account_name;
3350 } account_types[] = {
3351 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
3352 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
3353 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
3354 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
3355 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
3356 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
3357 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
3358 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
3359 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
3360 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
3361 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
3362 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
3363 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
3364 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
3365 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
3368 for (i = 0; account_types[i].account_name; i++) {
3369 TALLOC_CTX *user_ctx;
3370 uint32_t acct_flags = account_types[i].acct_flags;
3371 uint32_t access_granted;
3372 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
3373 init_lsa_String(&name, account_types[i].account_name);
3375 r.in.domain_handle = domain_handle;
3376 r.in.account_name = &name;
3377 r.in.acct_flags = acct_flags;
3378 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3379 r.out.user_handle = &user_handle;
3380 r.out.access_granted = &access_granted;
3383 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
3385 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
3387 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
3388 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
3389 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
3392 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
3399 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
3400 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
3401 talloc_free(user_ctx);
3405 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
3408 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
3409 printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
3410 nt_errstr(status), nt_errstr(account_types[i].nt_status));
3414 if (NT_STATUS_IS_OK(status)) {
3415 q.in.user_handle = &user_handle;
3419 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
3420 if (!NT_STATUS_IS_OK(status)) {
3421 printf("QueryUserInfo level %u failed - %s\n",
3422 q.in.level, nt_errstr(status));
3425 uint32_t expected_flags = (acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
3426 if (acct_flags == ACB_NORMAL) {
3427 expected_flags |= ACB_PW_EXPIRED;
3429 if ((info->info5.acct_flags) != expected_flags) {
3430 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
3431 info->info5.acct_flags,
3435 switch (acct_flags) {
3437 if (info->info5.primary_gid != DOMAIN_RID_DCS) {
3438 printf("QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n",
3439 DOMAIN_RID_DCS, info->info5.primary_gid);
3444 if (info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
3445 printf("QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
3446 DOMAIN_RID_DOMAIN_MEMBERS, info->info5.primary_gid);
3451 if (info->info5.primary_gid != DOMAIN_RID_USERS) {
3452 printf("QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n",
3453 DOMAIN_RID_USERS, info->info5.primary_gid);
3460 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
3461 acct_flags, name.string, which_ops)) {
3465 printf("Testing DeleteUser (createuser2 test)\n");
3467 d.in.user_handle = &user_handle;
3468 d.out.user_handle = &user_handle;
3470 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
3471 if (!NT_STATUS_IS_OK(status)) {
3472 printf("DeleteUser failed - %s\n", nt_errstr(status));
3476 talloc_free(user_ctx);
3482 static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3483 struct policy_handle *handle)
3486 struct samr_QueryAliasInfo r;
3487 union samr_AliasInfo *info;
3488 uint16_t levels[] = {1, 2, 3};
3492 for (i=0;i<ARRAY_SIZE(levels);i++) {
3493 printf("Testing QueryAliasInfo level %u\n", levels[i]);
3495 r.in.alias_handle = handle;
3496 r.in.level = levels[i];
3499 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
3500 if (!NT_STATUS_IS_OK(status)) {
3501 printf("QueryAliasInfo level %u failed - %s\n",
3502 levels[i], nt_errstr(status));
3510 static bool test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3511 struct policy_handle *handle)
3514 struct samr_QueryGroupInfo r;
3515 union samr_GroupInfo *info;
3516 uint16_t levels[] = {1, 2, 3, 4, 5};
3520 for (i=0;i<ARRAY_SIZE(levels);i++) {
3521 printf("Testing QueryGroupInfo level %u\n", levels[i]);
3523 r.in.group_handle = handle;
3524 r.in.level = levels[i];
3527 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
3528 if (!NT_STATUS_IS_OK(status)) {
3529 printf("QueryGroupInfo level %u failed - %s\n",
3530 levels[i], nt_errstr(status));
3538 static bool test_QueryGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3539 struct policy_handle *handle)
3542 struct samr_QueryGroupMember r;
3543 struct samr_RidTypeArray *rids = NULL;
3546 printf("Testing QueryGroupMember\n");
3548 r.in.group_handle = handle;
3551 status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &r);
3552 if (!NT_STATUS_IS_OK(status)) {
3553 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
3561 static bool test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3562 struct policy_handle *handle)
3565 struct samr_QueryGroupInfo r;
3566 union samr_GroupInfo *info;
3567 struct samr_SetGroupInfo s;
3568 uint16_t levels[] = {1, 2, 3, 4};
3569 uint16_t set_ok[] = {0, 1, 1, 1};
3573 for (i=0;i<ARRAY_SIZE(levels);i++) {
3574 printf("Testing QueryGroupInfo level %u\n", levels[i]);
3576 r.in.group_handle = handle;
3577 r.in.level = levels[i];
3580 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
3581 if (!NT_STATUS_IS_OK(status)) {
3582 printf("QueryGroupInfo level %u failed - %s\n",
3583 levels[i], nt_errstr(status));
3587 printf("Testing SetGroupInfo level %u\n", levels[i]);
3589 s.in.group_handle = handle;
3590 s.in.level = levels[i];
3591 s.in.info = *r.out.info;
3594 /* disabled this, as it changes the name only from the point of view of samr,
3595 but leaves the name from the point of view of w2k3 internals (and ldap). This means
3596 the name is still reserved, so creating the old name fails, but deleting by the old name
3598 if (s.in.level == 2) {
3599 init_lsa_String(&s.in.info->string, "NewName");
3603 if (s.in.level == 4) {
3604 init_lsa_String(&s.in.info->description, "test description");
3607 status = dcerpc_samr_SetGroupInfo(p, mem_ctx, &s);
3609 if (!NT_STATUS_IS_OK(status)) {
3610 printf("SetGroupInfo level %u failed - %s\n",
3611 r.in.level, nt_errstr(status));
3616 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
3617 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
3618 r.in.level, nt_errstr(status));
3628 static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3629 struct policy_handle *handle)
3632 struct samr_QueryUserInfo r;
3633 union samr_UserInfo *info;
3634 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
3635 11, 12, 13, 14, 16, 17, 20, 21};
3639 for (i=0;i<ARRAY_SIZE(levels);i++) {
3640 printf("Testing QueryUserInfo level %u\n", levels[i]);
3642 r.in.user_handle = handle;
3643 r.in.level = levels[i];
3646 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
3647 if (!NT_STATUS_IS_OK(status)) {
3648 printf("QueryUserInfo level %u failed - %s\n",
3649 levels[i], nt_errstr(status));
3657 static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3658 struct policy_handle *handle)
3661 struct samr_QueryUserInfo2 r;
3662 union samr_UserInfo *info;
3663 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
3664 11, 12, 13, 14, 16, 17, 20, 21};
3668 for (i=0;i<ARRAY_SIZE(levels);i++) {
3669 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
3671 r.in.user_handle = handle;
3672 r.in.level = levels[i];
3675 status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r);
3676 if (!NT_STATUS_IS_OK(status)) {
3677 printf("QueryUserInfo2 level %u failed - %s\n",
3678 levels[i], nt_errstr(status));
3686 static bool test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3687 struct policy_handle *handle, uint32_t rid)
3690 struct samr_OpenUser r;
3691 struct policy_handle user_handle;
3694 printf("Testing OpenUser(%u)\n", rid);
3696 r.in.domain_handle = handle;
3697 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3699 r.out.user_handle = &user_handle;
3701 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3702 if (!NT_STATUS_IS_OK(status)) {
3703 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
3707 if (!test_QuerySecurity(p, mem_ctx, &user_handle)) {
3711 if (!test_QueryUserInfo(p, mem_ctx, &user_handle)) {
3715 if (!test_QueryUserInfo2(p, mem_ctx, &user_handle)) {
3719 if (!test_GetUserPwInfo(p, mem_ctx, &user_handle)) {
3723 if (!test_GetGroupsForUser(p,mem_ctx, &user_handle)) {
3727 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
3734 static bool test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3735 struct policy_handle *handle, uint32_t rid)
3738 struct samr_OpenGroup r;
3739 struct policy_handle group_handle;
3742 printf("Testing OpenGroup(%u)\n", rid);
3744 r.in.domain_handle = handle;
3745 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3747 r.out.group_handle = &group_handle;
3749 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
3750 if (!NT_STATUS_IS_OK(status)) {
3751 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
3755 if (!test_QuerySecurity(p, mem_ctx, &group_handle)) {
3759 if (!test_QueryGroupInfo(p, mem_ctx, &group_handle)) {
3763 if (!test_QueryGroupMember(p, mem_ctx, &group_handle)) {
3767 if (!test_samr_handle_Close(p, mem_ctx, &group_handle)) {
3774 static bool test_OpenAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
3775 struct policy_handle *handle, uint32_t rid)
3778 struct samr_OpenAlias r;
3779 struct policy_handle alias_handle;
3782 torture_comment(tctx, "Testing OpenAlias(%u)\n", rid);
3784 r.in.domain_handle = handle;
3785 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3787 r.out.alias_handle = &alias_handle;
3789 status = dcerpc_samr_OpenAlias(p, tctx, &r);
3790 if (!NT_STATUS_IS_OK(status)) {
3791 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
3795 if (!test_QuerySecurity(p, tctx, &alias_handle)) {
3799 if (!test_QueryAliasInfo(p, tctx, &alias_handle)) {
3803 if (!test_GetMembersInAlias(p, tctx, &alias_handle)) {
3807 if (!test_samr_handle_Close(p, tctx, &alias_handle)) {
3814 static bool check_mask(struct dcerpc_pipe *p, struct torture_context *tctx,
3815 struct policy_handle *handle, uint32_t rid,
3816 uint32_t acct_flag_mask)
3819 struct samr_OpenUser r;
3820 struct samr_QueryUserInfo q;
3821 union samr_UserInfo *info;
3822 struct policy_handle user_handle;
3825 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
3827 r.in.domain_handle = handle;
3828 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3830 r.out.user_handle = &user_handle;
3832 status = dcerpc_samr_OpenUser(p, tctx, &r);
3833 if (!NT_STATUS_IS_OK(status)) {
3834 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
3838 q.in.user_handle = &user_handle;
3842 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
3843 if (!NT_STATUS_IS_OK(status)) {
3844 printf("QueryUserInfo level 16 failed - %s\n",
3848 if ((acct_flag_mask & info->info16.acct_flags) == 0) {
3849 printf("Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
3850 acct_flag_mask, info->info16.acct_flags, rid);
3855 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
3862 static bool test_EnumDomainUsers(struct dcerpc_pipe *p, struct torture_context *tctx,
3863 struct policy_handle *handle)
3865 NTSTATUS status = STATUS_MORE_ENTRIES;
3866 struct samr_EnumDomainUsers r;
3867 uint32_t mask, resume_handle=0;
3870 struct samr_LookupNames n;
3871 struct samr_LookupRids lr ;
3872 struct lsa_Strings names;
3873 struct samr_Ids rids, types;
3874 struct samr_SamArray *sam = NULL;
3875 uint32_t num_entries = 0;
3877 uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
3878 ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
3879 ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
3882 printf("Testing EnumDomainUsers\n");
3884 for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
3885 r.in.domain_handle = handle;
3886 r.in.resume_handle = &resume_handle;
3887 r.in.acct_flags = mask = masks[mask_idx];
3888 r.in.max_size = (uint32_t)-1;
3889 r.out.resume_handle = &resume_handle;
3890 r.out.num_entries = &num_entries;
3893 status = dcerpc_samr_EnumDomainUsers(p, tctx, &r);
3894 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
3895 !NT_STATUS_IS_OK(status)) {
3896 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
3900 torture_assert(tctx, sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
3902 if (sam->count == 0) {
3906 for (i=0;i<sam->count;i++) {
3908 if (!check_mask(p, tctx, handle, sam->entries[i].idx, mask)) {
3911 } else if (!test_OpenUser(p, tctx, handle, sam->entries[i].idx)) {
3917 printf("Testing LookupNames\n");
3918 n.in.domain_handle = handle;
3919 n.in.num_names = sam->count;
3920 n.in.names = talloc_array(tctx, struct lsa_String, sam->count);
3922 n.out.types = &types;
3923 for (i=0;i<sam->count;i++) {
3924 n.in.names[i].string = sam->entries[i].name.string;
3926 status = dcerpc_samr_LookupNames(p, tctx, &n);
3927 if (!NT_STATUS_IS_OK(status)) {
3928 printf("LookupNames failed - %s\n", nt_errstr(status));
3933 printf("Testing LookupRids\n");
3934 lr.in.domain_handle = handle;
3935 lr.in.num_rids = sam->count;
3936 lr.in.rids = talloc_array(tctx, uint32_t, sam->count);
3937 lr.out.names = &names;
3938 lr.out.types = &types;
3939 for (i=0;i<sam->count;i++) {
3940 lr.in.rids[i] = sam->entries[i].idx;
3942 status = dcerpc_samr_LookupRids(p, tctx, &lr);
3943 torture_assert_ntstatus_ok(tctx, status, "LookupRids");
3949 try blasting the server with a bunch of sync requests
3951 static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, struct torture_context *tctx,
3952 struct policy_handle *handle)
3955 struct samr_EnumDomainUsers r;
3956 uint32_t resume_handle=0;
3958 #define ASYNC_COUNT 100
3959 struct rpc_request *req[ASYNC_COUNT];
3961 if (!torture_setting_bool(tctx, "dangerous", false)) {
3962 torture_skip(tctx, "samr async test disabled - enable dangerous tests to use\n");
3965 torture_comment(tctx, "Testing EnumDomainUsers_async\n");
3967 r.in.domain_handle = handle;
3968 r.in.resume_handle = &resume_handle;
3969 r.in.acct_flags = 0;
3970 r.in.max_size = (uint32_t)-1;
3971 r.out.resume_handle = &resume_handle;
3973 for (i=0;i<ASYNC_COUNT;i++) {
3974 req[i] = dcerpc_samr_EnumDomainUsers_send(p, tctx, &r);
3977 for (i=0;i<ASYNC_COUNT;i++) {
3978 status = dcerpc_ndr_request_recv(req[i]);
3979 if (!NT_STATUS_IS_OK(status)) {
3980 printf("EnumDomainUsers[%d] failed - %s\n",
3981 i, nt_errstr(status));
3986 torture_comment(tctx, "%d async requests OK\n", i);
3991 static bool test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3992 struct policy_handle *handle)
3995 struct samr_EnumDomainGroups r;
3996 uint32_t resume_handle=0;
3997 struct samr_SamArray *sam = NULL;
3998 uint32_t num_entries = 0;
4002 printf("Testing EnumDomainGroups\n");
4004 r.in.domain_handle = handle;
4005 r.in.resume_handle = &resume_handle;
4006 r.in.max_size = (uint32_t)-1;
4007 r.out.resume_handle = &resume_handle;
4008 r.out.num_entries = &num_entries;
4011 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
4012 if (!NT_STATUS_IS_OK(status)) {
4013 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
4021 for (i=0;i<sam->count;i++) {
4022 if (!test_OpenGroup(p, mem_ctx, handle, sam->entries[i].idx)) {
4030 static bool test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4031 struct policy_handle *handle)
4034 struct samr_EnumDomainAliases r;
4035 uint32_t resume_handle=0;
4036 struct samr_SamArray *sam = NULL;
4037 uint32_t num_entries = 0;
4041 printf("Testing EnumDomainAliases\n");
4043 r.in.domain_handle = handle;
4044 r.in.resume_handle = &resume_handle;
4045 r.in.max_size = (uint32_t)-1;
4047 r.out.num_entries = &num_entries;
4048 r.out.resume_handle = &resume_handle;
4050 status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
4051 if (!NT_STATUS_IS_OK(status)) {
4052 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
4060 for (i=0;i<sam->count;i++) {
4061 if (!test_OpenAlias(p, mem_ctx, handle, sam->entries[i].idx)) {
4069 static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4070 struct policy_handle *handle)
4073 struct samr_GetDisplayEnumerationIndex r;
4075 uint16_t levels[] = {1, 2, 3, 4, 5};
4076 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
4077 struct lsa_String name;
4081 for (i=0;i<ARRAY_SIZE(levels);i++) {
4082 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
4084 init_lsa_String(&name, TEST_ACCOUNT_NAME);
4086 r.in.domain_handle = handle;
4087 r.in.level = levels[i];
4091 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
4094 !NT_STATUS_IS_OK(status) &&
4095 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
4096 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
4097 levels[i], nt_errstr(status));
4101 init_lsa_String(&name, "zzzzzzzz");
4103 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
4105 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
4106 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
4107 levels[i], nt_errstr(status));
4115 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4116 struct policy_handle *handle)
4119 struct samr_GetDisplayEnumerationIndex2 r;
4121 uint16_t levels[] = {1, 2, 3, 4, 5};
4122 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
4123 struct lsa_String name;
4127 for (i=0;i<ARRAY_SIZE(levels);i++) {
4128 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
4130 init_lsa_String(&name, TEST_ACCOUNT_NAME);
4132 r.in.domain_handle = handle;
4133 r.in.level = levels[i];
4137 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
4139 !NT_STATUS_IS_OK(status) &&
4140 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
4141 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
4142 levels[i], nt_errstr(status));
4146 init_lsa_String(&name, "zzzzzzzz");
4148 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
4149 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
4150 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
4151 levels[i], nt_errstr(status));
4159 #define STRING_EQUAL_QUERY(s1, s2, user) \
4160 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
4161 /* odd, but valid */ \
4162 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
4163 printf("%s mismatch for %s: %s != %s (%s)\n", \
4164 #s1, user.string, s1.string, s2.string, __location__); \
4167 #define INT_EQUAL_QUERY(s1, s2, user) \
4169 printf("%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
4170 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
4174 static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4175 struct samr_QueryDisplayInfo *querydisplayinfo,
4176 bool *seen_testuser)
4178 struct samr_OpenUser r;
4179 struct samr_QueryUserInfo q;
4180 union samr_UserInfo *info;
4181 struct policy_handle user_handle;
4184 r.in.domain_handle = querydisplayinfo->in.domain_handle;
4185 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4186 for (i = 0; ; i++) {
4187 switch (querydisplayinfo->in.level) {
4189 if (i >= querydisplayinfo->out.info->info1.count) {
4192 r.in.rid = querydisplayinfo->out.info->info1.entries[i].rid;
4195 if (i >= querydisplayinfo->out.info->info2.count) {
4198 r.in.rid = querydisplayinfo->out.info->info2.entries[i].rid;
4204 /* Not interested in validating just the account name */
4208 r.out.user_handle = &user_handle;
4210 switch (querydisplayinfo->in.level) {
4213 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
4214 if (!NT_STATUS_IS_OK(status)) {
4215 printf("OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(status));
4220 q.in.user_handle = &user_handle;
4223 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
4224 if (!NT_STATUS_IS_OK(status)) {
4225 printf("QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(status));
4229 switch (querydisplayinfo->in.level) {
4231 if (seen_testuser && strcmp(info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
4232 *seen_testuser = true;
4234 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].full_name,
4235 info->info21.full_name, info->info21.account_name);
4236 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].account_name,
4237 info->info21.account_name, info->info21.account_name);
4238 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].description,
4239 info->info21.description, info->info21.account_name);
4240 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].rid,
4241 info->info21.rid, info->info21.account_name);
4242 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].acct_flags,
4243 info->info21.acct_flags, info->info21.account_name);
4247 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].account_name,
4248 info->info21.account_name, info->info21.account_name);
4249 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].description,
4250 info->info21.description, info->info21.account_name);
4251 INT_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].rid,
4252 info->info21.rid, info->info21.account_name);
4253 INT_EQUAL_QUERY((querydisplayinfo->out.info->info2.entries[i].acct_flags & ~ACB_NORMAL),
4254 info->info21.acct_flags, info->info21.account_name);
4256 if (!(querydisplayinfo->out.info->info2.entries[i].acct_flags & ACB_NORMAL)) {
4257 printf("Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
4258 info->info21.account_name.string);
4261 if (!(info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
4262 printf("Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
4263 info->info21.account_name.string,
4264 querydisplayinfo->out.info->info2.entries[i].acct_flags,
4265 info->info21.acct_flags);
4272 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
4279 static bool test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4280 struct policy_handle *handle)
4283 struct samr_QueryDisplayInfo r;
4284 struct samr_QueryDomainInfo dom_info;
4285 union samr_DomainInfo *info = NULL;
4287 uint16_t levels[] = {1, 2, 3, 4, 5};
4289 bool seen_testuser = false;
4290 uint32_t total_size;
4291 uint32_t returned_size;
4292 union samr_DispInfo disp_info;
4295 for (i=0;i<ARRAY_SIZE(levels);i++) {
4296 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
4299 status = STATUS_MORE_ENTRIES;
4300 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
4301 r.in.domain_handle = handle;
4302 r.in.level = levels[i];
4303 r.in.max_entries = 2;
4304 r.in.buf_size = (uint32_t)-1;
4305 r.out.total_size = &total_size;
4306 r.out.returned_size = &returned_size;
4307 r.out.info = &disp_info;
4309 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
4310 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(status)) {
4311 printf("QueryDisplayInfo level %u failed - %s\n",
4312 levels[i], nt_errstr(status));
4315 switch (r.in.level) {
4317 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, &seen_testuser)) {
4320 r.in.start_idx += r.out.info->info1.count;
4323 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, NULL)) {
4326 r.in.start_idx += r.out.info->info2.count;
4329 r.in.start_idx += r.out.info->info3.count;
4332 r.in.start_idx += r.out.info->info4.count;
4335 r.in.start_idx += r.out.info->info5.count;
4339 dom_info.in.domain_handle = handle;
4340 dom_info.in.level = 2;
4341 dom_info.out.info = &info;
4343 /* Check number of users returned is correct */
4344 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &dom_info);
4345 if (!NT_STATUS_IS_OK(status)) {
4346 printf("QueryDomainInfo level %u failed - %s\n",
4347 r.in.level, nt_errstr(status));
4351 switch (r.in.level) {
4354 if (info->general.num_users < r.in.start_idx) {
4355 printf("QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
4356 r.in.start_idx, info->general.num_groups,
4357 info->general.domain_name.string);
4360 if (!seen_testuser) {
4361 struct policy_handle user_handle;
4362 if (NT_STATUS_IS_OK(test_OpenUser_byname(p, mem_ctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
4363 printf("Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
4364 info->general.domain_name.string);
4366 test_samr_handle_Close(p, mem_ctx, &user_handle);
4372 if (info->general.num_groups != r.in.start_idx) {
4373 printf("QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
4374 r.in.start_idx, info->general.num_groups,
4375 info->general.domain_name.string);
4387 static bool test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4388 struct policy_handle *handle)
4391 struct samr_QueryDisplayInfo2 r;
4393 uint16_t levels[] = {1, 2, 3, 4, 5};
4395 uint32_t total_size;
4396 uint32_t returned_size;
4397 union samr_DispInfo info;
4399 for (i=0;i<ARRAY_SIZE(levels);i++) {
4400 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
4402 r.in.domain_handle = handle;
4403 r.in.level = levels[i];
4405 r.in.max_entries = 1000;
4406 r.in.buf_size = (uint32_t)-1;
4407 r.out.total_size = &total_size;
4408 r.out.returned_size = &returned_size;
4411 status = dcerpc_samr_QueryDisplayInfo2(p, mem_ctx, &r);
4412 if (!NT_STATUS_IS_OK(status)) {
4413 printf("QueryDisplayInfo2 level %u failed - %s\n",
4414 levels[i], nt_errstr(status));
4422 static bool test_QueryDisplayInfo3(struct dcerpc_pipe *p, struct torture_context *tctx,
4423 struct policy_handle *handle)
4426 struct samr_QueryDisplayInfo3 r;
4428 uint16_t levels[] = {1, 2, 3, 4, 5};
4430 uint32_t total_size;
4431 uint32_t returned_size;
4432 union samr_DispInfo info;
4434 for (i=0;i<ARRAY_SIZE(levels);i++) {
4435 torture_comment(tctx, "Testing QueryDisplayInfo3 level %u\n", levels[i]);
4437 r.in.domain_handle = handle;
4438 r.in.level = levels[i];
4440 r.in.max_entries = 1000;
4441 r.in.buf_size = (uint32_t)-1;
4442 r.out.total_size = &total_size;
4443 r.out.returned_size = &returned_size;
4446 status = dcerpc_samr_QueryDisplayInfo3(p, tctx, &r);
4447 if (!NT_STATUS_IS_OK(status)) {
4448 printf("QueryDisplayInfo3 level %u failed - %s\n",
4449 levels[i], nt_errstr(status));
4458 static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4459 struct policy_handle *handle)
4462 struct samr_QueryDisplayInfo r;
4464 uint32_t total_size;
4465 uint32_t returned_size;
4466 union samr_DispInfo info;
4468 printf("Testing QueryDisplayInfo continuation\n");
4470 r.in.domain_handle = handle;
4473 r.in.max_entries = 1;
4474 r.in.buf_size = (uint32_t)-1;
4475 r.out.total_size = &total_size;
4476 r.out.returned_size = &returned_size;
4480 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
4481 if (NT_STATUS_IS_OK(status) && *r.out.returned_size != 0) {
4482 if (r.out.info->info1.entries[0].idx != r.in.start_idx + 1) {
4483 printf("expected idx %d but got %d\n",
4485 r.out.info->info1.entries[0].idx);
4489 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
4490 !NT_STATUS_IS_OK(status)) {
4491 printf("QueryDisplayInfo level %u failed - %s\n",
4492 r.in.level, nt_errstr(status));
4497 } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
4498 NT_STATUS_IS_OK(status)) &&
4499 *r.out.returned_size != 0);
4504 static bool test_QueryDomainInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
4505 struct policy_handle *handle)
4508 struct samr_QueryDomainInfo r;
4509 union samr_DomainInfo *info = NULL;
4510 struct samr_SetDomainInfo s;
4511 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
4512 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
4515 const char *domain_comment = talloc_asprintf(tctx,
4516 "Tortured by Samba4 RPC-SAMR: %s",
4517 timestring(tctx, time(NULL)));
4519 s.in.domain_handle = handle;
4521 s.in.info = talloc(tctx, union samr_DomainInfo);
4523 s.in.info->oem.oem_information.string = domain_comment;
4524 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
4525 if (!NT_STATUS_IS_OK(status)) {
4526 printf("SetDomainInfo level %u (set comment) failed - %s\n",
4527 r.in.level, nt_errstr(status));
4531 for (i=0;i<ARRAY_SIZE(levels);i++) {
4532 torture_comment(tctx, "Testing QueryDomainInfo level %u\n", levels[i]);
4534 r.in.domain_handle = handle;
4535 r.in.level = levels[i];
4538 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
4539 if (!NT_STATUS_IS_OK(status)) {
4540 printf("QueryDomainInfo level %u failed - %s\n",
4541 r.in.level, nt_errstr(status));
4546 switch (levels[i]) {
4548 if (strcmp(info->general.oem_information.string, domain_comment) != 0) {
4549 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
4550 levels[i], info->general.oem_information.string, domain_comment);
4553 if (!info->general.primary.string) {
4554 printf("QueryDomainInfo level %u returned no PDC name\n",
4557 } else if (info->general.role == SAMR_ROLE_DOMAIN_PDC) {
4558 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), info->general.primary.string) != 0) {
4559 printf("QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
4560 levels[i], info->general.primary.string, dcerpc_server_name(p));
4565 if (strcmp(info->oem.oem_information.string, domain_comment) != 0) {
4566 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
4567 levels[i], info->oem.oem_information.string, domain_comment);
4572 if (!info->info6.primary.string) {
4573 printf("QueryDomainInfo level %u returned no PDC name\n",
4579 if (strcmp(info->general2.general.oem_information.string, domain_comment) != 0) {
4580 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
4581 levels[i], info->general2.general.oem_information.string, domain_comment);
4587 torture_comment(tctx, "Testing SetDomainInfo level %u\n", levels[i]);
4589 s.in.domain_handle = handle;
4590 s.in.level = levels[i];
4593 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
4595 if (!NT_STATUS_IS_OK(status)) {
4596 printf("SetDomainInfo level %u failed - %s\n",
4597 r.in.level, nt_errstr(status));
4602 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
4603 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
4604 r.in.level, nt_errstr(status));
4610 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
4611 if (!NT_STATUS_IS_OK(status)) {
4612 printf("QueryDomainInfo level %u failed - %s\n",
4613 r.in.level, nt_errstr(status));
4623 static bool test_QueryDomainInfo2(struct dcerpc_pipe *p, struct torture_context *tctx,
4624 struct policy_handle *handle)
4627 struct samr_QueryDomainInfo2 r;
4628 union samr_DomainInfo *info = NULL;
4629 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
4633 for (i=0;i<ARRAY_SIZE(levels);i++) {
4634 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
4636 r.in.domain_handle = handle;
4637 r.in.level = levels[i];
4640 status = dcerpc_samr_QueryDomainInfo2(p, tctx, &r);
4641 if (!NT_STATUS_IS_OK(status)) {
4642 printf("QueryDomainInfo2 level %u failed - %s\n",
4643 r.in.level, nt_errstr(status));
4652 /* Test whether querydispinfo level 5 and enumdomgroups return the same
4653 set of group names. */
4654 static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx,
4655 struct policy_handle *handle)
4657 struct samr_EnumDomainGroups q1;
4658 struct samr_QueryDisplayInfo q2;
4660 uint32_t resume_handle=0;
4661 struct samr_SamArray *sam = NULL;
4662 uint32_t num_entries = 0;
4665 uint32_t total_size;
4666 uint32_t returned_size;
4667 union samr_DispInfo info;
4670 const char **names = NULL;
4672 torture_comment(tctx, "Testing coherency of querydispinfo vs enumdomgroups\n");
4674 q1.in.domain_handle = handle;
4675 q1.in.resume_handle = &resume_handle;
4677 q1.out.resume_handle = &resume_handle;
4678 q1.out.num_entries = &num_entries;
4681 status = STATUS_MORE_ENTRIES;
4682 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
4683 status = dcerpc_samr_EnumDomainGroups(p, tctx, &q1);
4685 if (!NT_STATUS_IS_OK(status) &&
4686 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
4689 for (i=0; i<*q1.out.num_entries; i++) {
4690 add_string_to_array(tctx,
4691 sam->entries[i].name.string,
4692 &names, &num_names);
4696 torture_assert_ntstatus_ok(tctx, status, "EnumDomainGroups");
4698 torture_assert(tctx, sam, "EnumDomainGroups failed to return sam");
4700 q2.in.domain_handle = handle;
4702 q2.in.start_idx = 0;
4703 q2.in.max_entries = 5;
4704 q2.in.buf_size = (uint32_t)-1;
4705 q2.out.total_size = &total_size;
4706 q2.out.returned_size = &returned_size;
4707 q2.out.info = &info;
4709 status = STATUS_MORE_ENTRIES;
4710 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
4711 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &q2);
4713 if (!NT_STATUS_IS_OK(status) &&
4714 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
4717 for (i=0; i<q2.out.info->info5.count; i++) {
4719 const char *name = q2.out.info->info5.entries[i].account_name.string;
4721 for (j=0; j<num_names; j++) {
4722 if (names[j] == NULL)
4724 if (strequal(names[j], name)) {
4732 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
4737 q2.in.start_idx += q2.out.info->info5.count;
4740 if (!NT_STATUS_IS_OK(status)) {
4741 printf("QueryDisplayInfo level 5 failed - %s\n",
4746 for (i=0; i<num_names; i++) {
4747 if (names[i] != NULL) {
4748 printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
4757 static bool test_DeleteDomainGroup(struct dcerpc_pipe *p, struct torture_context *tctx,
4758 struct policy_handle *group_handle)
4760 struct samr_DeleteDomainGroup d;
4763 torture_comment(tctx, "Testing DeleteDomainGroup\n");
4765 d.in.group_handle = group_handle;
4766 d.out.group_handle = group_handle;
4768 status = dcerpc_samr_DeleteDomainGroup(p, tctx, &d);
4769 torture_assert_ntstatus_ok(tctx, status, "DeleteDomainGroup");
4774 static bool test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
4775 struct policy_handle *domain_handle)
4777 struct samr_TestPrivateFunctionsDomain r;
4781 torture_comment(tctx, "Testing TestPrivateFunctionsDomain\n");
4783 r.in.domain_handle = domain_handle;
4785 status = dcerpc_samr_TestPrivateFunctionsDomain(p, tctx, &r);
4786 torture_assert_ntstatus_equal(tctx, NT_STATUS_NOT_IMPLEMENTED, status, "TestPrivateFunctionsDomain");
4791 static bool test_RidToSid(struct dcerpc_pipe *p, struct torture_context *tctx,
4792 struct dom_sid *domain_sid,
4793 struct policy_handle *domain_handle)
4795 struct samr_RidToSid r;
4798 struct dom_sid *calc_sid, *out_sid;
4799 int rids[] = { 0, 42, 512, 10200 };
4802 for (i=0;i<ARRAY_SIZE(rids);i++) {
4803 torture_comment(tctx, "Testing RidToSid\n");
4805 calc_sid = dom_sid_dup(tctx, domain_sid);
4806 r.in.domain_handle = domain_handle;
4808 r.out.sid = &out_sid;
4810 status = dcerpc_samr_RidToSid(p, tctx, &r);
4811 if (!NT_STATUS_IS_OK(status)) {
4812 printf("RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
4815 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
4817 if (!dom_sid_equal(calc_sid, out_sid)) {
4818 printf("RidToSid for %d failed - got %s, expected %s\n", rids[i],
4819 dom_sid_string(tctx, out_sid),
4820 dom_sid_string(tctx, calc_sid));
4829 static bool test_GetBootKeyInformation(struct dcerpc_pipe *p, struct torture_context *tctx,
4830 struct policy_handle *domain_handle)
4832 struct samr_GetBootKeyInformation r;
4835 uint32_t unknown = 0;
4837 torture_comment(tctx, "Testing GetBootKeyInformation\n");
4839 r.in.domain_handle = domain_handle;
4840 r.out.unknown = &unknown;
4842 status = dcerpc_samr_GetBootKeyInformation(p, tctx, &r);
4843 if (!NT_STATUS_IS_OK(status)) {
4844 /* w2k3 seems to fail this sometimes and pass it sometimes */
4845 torture_comment(tctx, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
4851 static bool test_AddGroupMember(struct dcerpc_pipe *p, struct torture_context *tctx,
4852 struct policy_handle *domain_handle,
4853 struct policy_handle *group_handle)
4856 struct samr_AddGroupMember r;
4857 struct samr_DeleteGroupMember d;
4858 struct samr_QueryGroupMember q;
4859 struct samr_RidTypeArray *rids = NULL;
4860 struct samr_SetMemberAttributesOfGroup s;
4863 status = test_LookupName(p, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
4864 torture_assert_ntstatus_ok(tctx, status, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME);
4866 r.in.group_handle = group_handle;
4868 r.in.flags = 0; /* ??? */
4870 torture_comment(tctx, "Testing AddGroupMember and DeleteGroupMember\n");
4872 d.in.group_handle = group_handle;
4875 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
4876 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_NOT_IN_GROUP, status, "DeleteGroupMember");
4878 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4879 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
4881 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4882 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_IN_GROUP, status, "AddGroupMember");
4884 if (torture_setting_bool(tctx, "samba4", false)) {
4885 torture_comment(tctx, "skipping SetMemberAttributesOfGroup test against Samba4\n");
4887 /* this one is quite strange. I am using random inputs in the
4888 hope of triggering an error that might give us a clue */
4890 s.in.group_handle = group_handle;
4891 s.in.unknown1 = random();
4892 s.in.unknown2 = random();
4894 status = dcerpc_samr_SetMemberAttributesOfGroup(p, tctx, &s);
4895 torture_assert_ntstatus_ok(tctx, status, "SetMemberAttributesOfGroup");
4898 q.in.group_handle = group_handle;
4901 status = dcerpc_samr_QueryGroupMember(p, tctx, &q);
4902 torture_assert_ntstatus_ok(tctx, status, "QueryGroupMember");
4904 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
4905 torture_assert_ntstatus_ok(tctx, status, "DeleteGroupMember");
4907 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4908 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
4914 static bool test_CreateDomainGroup(struct dcerpc_pipe *p,
4915 struct torture_context *tctx,
4916 struct policy_handle *domain_handle,
4917 struct policy_handle *group_handle,
4918 struct dom_sid *domain_sid)
4921 struct samr_CreateDomainGroup r;
4923 struct lsa_String name;
4926 init_lsa_String(&name, TEST_GROUPNAME);
4928 r.in.domain_handle = domain_handle;
4930 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4931 r.out.group_handle = group_handle;
4934 printf("Testing CreateDomainGroup(%s)\n", r.in.name->string);
4936 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
4938 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
4939 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
4940 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.name->string);
4943 printf("Server should have refused create of '%s', got %s instead\n", r.in.name->string,
4949 if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS)) {
4950 if (!test_DeleteGroup_byname(p, tctx, domain_handle, r.in.name->string)) {
4951 printf("CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
4955 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
4957 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
4958 if (!test_DeleteUser_byname(p, tctx, domain_handle, r.in.name->string)) {
4960 printf("CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
4964 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
4966 torture_assert_ntstatus_ok(tctx, status, "CreateDomainGroup");
4968 if (!test_AddGroupMember(p, tctx, domain_handle, group_handle)) {
4969 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
4973 if (!test_SetGroupInfo(p, tctx, group_handle)) {
4982 its not totally clear what this does. It seems to accept any sid you like.
4984 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p,
4985 struct torture_context *tctx,
4986 struct policy_handle *domain_handle)
4989 struct samr_RemoveMemberFromForeignDomain r;
4991 r.in.domain_handle = domain_handle;
4992 r.in.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-12-34-56-78");
4994 status = dcerpc_samr_RemoveMemberFromForeignDomain(p, tctx, &r);
4995 torture_assert_ntstatus_ok(tctx, status, "RemoveMemberFromForeignDomain");
5002 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
5003 struct policy_handle *handle);
5005 static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
5006 struct policy_handle *handle, struct dom_sid *sid,
5007 enum torture_samr_choice which_ops)
5010 struct samr_OpenDomain r;
5011 struct policy_handle domain_handle;
5012 struct policy_handle alias_handle;
5013 struct policy_handle user_handle;
5014 struct policy_handle group_handle;
5017 ZERO_STRUCT(alias_handle);
5018 ZERO_STRUCT(user_handle);
5019 ZERO_STRUCT(group_handle);
5020 ZERO_STRUCT(domain_handle);
5022 torture_comment(tctx, "Testing OpenDomain of %s\n", dom_sid_string(tctx, sid));
5024 r.in.connect_handle = handle;
5025 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5027 r.out.domain_handle = &domain_handle;
5029 status = dcerpc_samr_OpenDomain(p, tctx, &r);
5030 torture_assert_ntstatus_ok(tctx, status, "OpenDomain");
5032 /* run the domain tests with the main handle closed - this tests
5033 the servers reference counting */
5034 ret &= test_samr_handle_Close(p, tctx, handle);
5036 switch (which_ops) {
5037 case TORTURE_SAMR_USER_ATTRIBUTES:
5038 case TORTURE_SAMR_PASSWORDS:
5039 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops);
5040 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops);
5041 /* This test needs 'complex' users to validate */
5042 ret &= test_QueryDisplayInfo(p, tctx, &domain_handle);
5044 printf("Testing PASSWORDS or ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
5047 case TORTURE_SAMR_OTHER:
5048 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops);
5050 printf("Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid));
5052 ret &= test_QuerySecurity(p, tctx, &domain_handle);
5053 ret &= test_RemoveMemberFromForeignDomain(p, tctx, &domain_handle);
5054 ret &= test_CreateAlias(p, tctx, &domain_handle, &alias_handle, sid);
5055 ret &= test_CreateDomainGroup(p, tctx, &domain_handle, &group_handle, sid);
5056 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
5057 ret &= test_QueryDomainInfo2(p, tctx, &domain_handle);
5058 ret &= test_EnumDomainUsers(p, tctx, &domain_handle);
5059 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
5060 ret &= test_EnumDomainGroups(p, tctx, &domain_handle);
5061 ret &= test_EnumDomainAliases(p, tctx, &domain_handle);
5062 ret &= test_QueryDisplayInfo2(p, tctx, &domain_handle);
5063 ret &= test_QueryDisplayInfo3(p, tctx, &domain_handle);
5064 ret &= test_QueryDisplayInfo_continue(p, tctx, &domain_handle);
5066 if (torture_setting_bool(tctx, "samba4", false)) {
5067 torture_comment(tctx, "skipping GetDisplayEnumerationIndex test against Samba4\n");
5069 ret &= test_GetDisplayEnumerationIndex(p, tctx, &domain_handle);
5070 ret &= test_GetDisplayEnumerationIndex2(p, tctx, &domain_handle);
5072 ret &= test_GroupList(p, tctx, &domain_handle);
5073 ret &= test_TestPrivateFunctionsDomain(p, tctx, &domain_handle);
5074 ret &= test_RidToSid(p, tctx, sid, &domain_handle);
5075 ret &= test_GetBootKeyInformation(p, tctx, &domain_handle);
5077 torture_comment(tctx, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx, sid));
5082 if (!policy_handle_empty(&user_handle) &&
5083 !test_DeleteUser(p, tctx, &user_handle)) {
5087 if (!policy_handle_empty(&alias_handle) &&
5088 !test_DeleteAlias(p, tctx, &alias_handle)) {
5092 if (!policy_handle_empty(&group_handle) &&
5093 !test_DeleteDomainGroup(p, tctx, &group_handle)) {
5097 ret &= test_samr_handle_Close(p, tctx, &domain_handle);
5099 /* reconnect the main handle */
5100 ret &= test_Connect(p, tctx, handle);
5103 printf("Testing domain %s failed!\n", dom_sid_string(tctx, sid));
5109 static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
5110 struct policy_handle *handle, const char *domain,
5111 enum torture_samr_choice which_ops)
5114 struct samr_LookupDomain r;
5115 struct dom_sid2 *sid = NULL;
5116 struct lsa_String n1;
5117 struct lsa_String n2;
5120 torture_comment(tctx, "Testing LookupDomain(%s)\n", domain);
5122 /* check for correct error codes */
5123 r.in.connect_handle = handle;
5124 r.in.domain_name = &n2;
5128 status = dcerpc_samr_LookupDomain(p, tctx, &r);
5129 torture_assert_ntstatus_equal(tctx, NT_STATUS_INVALID_PARAMETER, status, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
5131 init_lsa_String(&n2, "xxNODOMAINxx");
5133 status = dcerpc_samr_LookupDomain(p, tctx, &r);
5134 torture_assert_ntstatus_equal(tctx, NT_STATUS_NO_SUCH_DOMAIN, status, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
5136 r.in.connect_handle = handle;
5138 init_lsa_String(&n1, domain);
5139 r.in.domain_name = &n1;
5141 status = dcerpc_samr_LookupDomain(p, tctx, &r);
5142 torture_assert_ntstatus_ok(tctx, status, "LookupDomain");
5144 if (!test_GetDomPwInfo(p, tctx, &n1)) {
5148 if (!test_OpenDomain(p, tctx, handle, *r.out.sid, which_ops)) {
5156 static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
5157 struct policy_handle *handle, enum torture_samr_choice which_ops)
5160 struct samr_EnumDomains r;
5161 uint32_t resume_handle = 0;
5162 uint32_t num_entries = 0;
5163 struct samr_SamArray *sam = NULL;
5167 r.in.connect_handle = handle;
5168 r.in.resume_handle = &resume_handle;
5169 r.in.buf_size = (uint32_t)-1;
5170 r.out.resume_handle = &resume_handle;
5171 r.out.num_entries = &num_entries;
5174 status = dcerpc_samr_EnumDomains(p, tctx, &r);
5175 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
5181 for (i=0;i<sam->count;i++) {
5182 if (!test_LookupDomain(p, tctx, handle,
5183 sam->entries[i].name.string, which_ops)) {
5188 status = dcerpc_samr_EnumDomains(p, tctx, &r);
5189 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
5195 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
5196 struct policy_handle *handle)
5199 struct samr_Connect r;
5200 struct samr_Connect2 r2;
5201 struct samr_Connect3 r3;
5202 struct samr_Connect4 r4;
5203 struct samr_Connect5 r5;
5204 union samr_ConnectInfo info;
5205 struct policy_handle h;
5206 uint32_t level_out = 0;
5207 bool ret = true, got_handle = false;
5209 torture_comment(tctx, "testing samr_Connect\n");
5211 r.in.system_name = 0;
5212 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5213 r.out.connect_handle = &h;
5215 status = dcerpc_samr_Connect(p, tctx, &r);
5216 if (!NT_STATUS_IS_OK(status)) {
5217 torture_comment(tctx, "Connect failed - %s\n", nt_errstr(status));
5224 torture_comment(tctx, "testing samr_Connect2\n");
5226 r2.in.system_name = NULL;
5227 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5228 r2.out.connect_handle = &h;
5230 status = dcerpc_samr_Connect2(p, tctx, &r2);
5231 if (!NT_STATUS_IS_OK(status)) {
5232 torture_comment(tctx, "Connect2 failed - %s\n", nt_errstr(status));
5236 test_samr_handle_Close(p, tctx, handle);
5242 torture_comment(tctx, "testing samr_Connect3\n");
5244 r3.in.system_name = NULL;
5246 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5247 r3.out.connect_handle = &h;
5249 status = dcerpc_samr_Connect3(p, tctx, &r3);
5250 if (!NT_STATUS_IS_OK(status)) {
5251 printf("Connect3 failed - %s\n", nt_errstr(status));
5255 test_samr_handle_Close(p, tctx, handle);
5261 torture_comment(tctx, "testing samr_Connect4\n");
5263 r4.in.system_name = "";
5264 r4.in.client_version = 0;
5265 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5266 r4.out.connect_handle = &h;
5268 status = dcerpc_samr_Connect4(p, tctx, &r4);
5269 if (!NT_STATUS_IS_OK(status)) {
5270 printf("Connect4 failed - %s\n", nt_errstr(status));
5274 test_samr_handle_Close(p, tctx, handle);
5280 torture_comment(tctx, "testing samr_Connect5\n");
5282 info.info1.client_version = 0;
5283 info.info1.unknown2 = 0;
5285 r5.in.system_name = "";
5286 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5288 r5.out.level_out = &level_out;
5289 r5.in.info_in = &info;
5290 r5.out.info_out = &info;
5291 r5.out.connect_handle = &h;
5293 status = dcerpc_samr_Connect5(p, tctx, &r5);
5294 if (!NT_STATUS_IS_OK(status)) {
5295 printf("Connect5 failed - %s\n", nt_errstr(status));
5299 test_samr_handle_Close(p, tctx, handle);
5309 bool torture_rpc_samr(struct torture_context *torture)
5312 struct dcerpc_pipe *p;
5314 struct policy_handle handle;
5316 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
5317 if (!NT_STATUS_IS_OK(status)) {
5321 ret &= test_Connect(p, torture, &handle);
5323 ret &= test_QuerySecurity(p, torture, &handle);
5325 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_OTHER);
5327 ret &= test_SetDsrmPassword(p, torture, &handle);
5329 ret &= test_Shutdown(p, torture, &handle);
5331 ret &= test_samr_handle_Close(p, torture, &handle);
5337 bool torture_rpc_samr_users(struct torture_context *torture)
5340 struct dcerpc_pipe *p;
5342 struct policy_handle handle;
5344 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
5345 if (!NT_STATUS_IS_OK(status)) {
5349 ret &= test_Connect(p, torture, &handle);
5351 ret &= test_QuerySecurity(p, torture, &handle);
5353 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_USER_ATTRIBUTES);
5355 ret &= test_SetDsrmPassword(p, torture, &handle);
5357 ret &= test_Shutdown(p, torture, &handle);
5359 ret &= test_samr_handle_Close(p, torture, &handle);
5365 bool torture_rpc_samr_passwords(struct torture_context *torture)
5368 struct dcerpc_pipe *p;
5370 struct policy_handle handle;
5372 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
5373 if (!NT_STATUS_IS_OK(status)) {
5377 ret &= test_Connect(p, torture, &handle);
5379 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_PASSWORDS);
5381 ret &= test_samr_handle_Close(p, torture, &handle);