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_PASSWORDS_PWDLASTSET,
43 TORTURE_SAMR_USER_ATTRIBUTES,
47 static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
48 struct policy_handle *handle);
50 static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
51 struct policy_handle *handle);
53 static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
54 struct policy_handle *handle);
56 static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
57 const char *acct_name,
58 struct policy_handle *domain_handle, char **password);
60 static void init_lsa_String(struct lsa_String *string, const char *s)
65 static void init_lsa_BinaryString(struct lsa_BinaryString *string, const char *s, uint32_t length)
67 string->length = length;
68 string->size = length;
69 string->array = (uint16_t *)discard_const(s);
72 bool test_samr_handle_Close(struct dcerpc_pipe *p, struct torture_context *tctx,
73 struct policy_handle *handle)
79 r.out.handle = handle;
81 status = dcerpc_samr_Close(p, tctx, &r);
82 torture_assert_ntstatus_ok(tctx, status, "Close");
87 static bool test_Shutdown(struct dcerpc_pipe *p, struct torture_context *tctx,
88 struct policy_handle *handle)
91 struct samr_Shutdown r;
93 if (!torture_setting_bool(tctx, "dangerous", false)) {
94 torture_skip(tctx, "samr_Shutdown disabled - enable dangerous tests to use\n");
98 r.in.connect_handle = handle;
100 torture_comment(tctx, "testing samr_Shutdown\n");
102 status = dcerpc_samr_Shutdown(p, tctx, &r);
103 torture_assert_ntstatus_ok(tctx, status, "samr_Shutdown");
108 static bool test_SetDsrmPassword(struct dcerpc_pipe *p, struct torture_context *tctx,
109 struct policy_handle *handle)
112 struct samr_SetDsrmPassword r;
113 struct lsa_String string;
114 struct samr_Password hash;
116 if (!torture_setting_bool(tctx, "dangerous", false)) {
117 torture_skip(tctx, "samr_SetDsrmPassword disabled - enable dangerous tests to use");
120 E_md4hash("TeSTDSRM123", hash.hash);
122 init_lsa_String(&string, "Administrator");
128 torture_comment(tctx, "testing samr_SetDsrmPassword\n");
130 status = dcerpc_samr_SetDsrmPassword(p, tctx, &r);
131 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_SUPPORTED, "samr_SetDsrmPassword");
137 static bool test_QuerySecurity(struct dcerpc_pipe *p,
138 struct torture_context *tctx,
139 struct policy_handle *handle)
142 struct samr_QuerySecurity r;
143 struct samr_SetSecurity s;
144 struct sec_desc_buf *sdbuf = NULL;
146 r.in.handle = handle;
148 r.out.sdbuf = &sdbuf;
150 status = dcerpc_samr_QuerySecurity(p, tctx, &r);
151 torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
153 torture_assert(tctx, sdbuf != NULL, "sdbuf is NULL");
155 s.in.handle = handle;
159 if (torture_setting_bool(tctx, "samba4", false)) {
160 torture_skip(tctx, "skipping SetSecurity test against Samba4\n");
163 status = dcerpc_samr_SetSecurity(p, tctx, &s);
164 torture_assert_ntstatus_ok(tctx, status, "SetSecurity");
166 status = dcerpc_samr_QuerySecurity(p, tctx, &r);
167 torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
173 static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
174 struct policy_handle *handle, uint32_t base_acct_flags,
175 const char *base_account_name)
178 struct samr_SetUserInfo s;
179 struct samr_SetUserInfo2 s2;
180 struct samr_QueryUserInfo q;
181 struct samr_QueryUserInfo q0;
182 union samr_UserInfo u;
183 union samr_UserInfo *info;
185 const char *test_account_name;
187 uint32_t user_extra_flags = 0;
188 if (base_acct_flags == ACB_NORMAL) {
189 /* When created, accounts are expired by default */
190 user_extra_flags = ACB_PW_EXPIRED;
193 s.in.user_handle = handle;
196 s2.in.user_handle = handle;
199 q.in.user_handle = handle;
203 #define TESTCALL(call, r) \
204 status = dcerpc_samr_ ##call(p, tctx, &r); \
205 if (!NT_STATUS_IS_OK(status)) { \
206 torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
207 r.in.level, nt_errstr(status), __location__); \
212 #define STRING_EQUAL(s1, s2, field) \
213 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
214 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
215 #field, s2, __location__); \
220 #define MEM_EQUAL(s1, s2, length, field) \
221 if ((s1 && !s2) || (s2 && !s1) || memcmp(s1, s2, length)) { \
222 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
223 #field, (const char *)s2, __location__); \
228 #define INT_EQUAL(i1, i2, field) \
230 torture_comment(tctx, "Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \
231 #field, (unsigned long long)i2, (unsigned long long)i1, __location__); \
236 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
237 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
239 TESTCALL(QueryUserInfo, q) \
241 s2.in.level = lvl1; \
244 ZERO_STRUCT(u.info21); \
245 u.info21.fields_present = fpval; \
247 init_lsa_String(&u.info ## lvl1.field1, value); \
248 TESTCALL(SetUserInfo, s) \
249 TESTCALL(SetUserInfo2, s2) \
250 init_lsa_String(&u.info ## lvl1.field1, ""); \
251 TESTCALL(QueryUserInfo, q); \
253 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
255 TESTCALL(QueryUserInfo, q) \
257 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
260 #define TEST_USERINFO_BINARYSTRING(lvl1, field1, lvl2, field2, value, fpval) do { \
261 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
263 TESTCALL(QueryUserInfo, q) \
265 s2.in.level = lvl1; \
268 ZERO_STRUCT(u.info21); \
269 u.info21.fields_present = fpval; \
271 init_lsa_BinaryString(&u.info ## lvl1.field1, value, strlen(value)); \
272 TESTCALL(SetUserInfo, s) \
273 TESTCALL(SetUserInfo2, s2) \
274 init_lsa_BinaryString(&u.info ## lvl1.field1, "", 1); \
275 TESTCALL(QueryUserInfo, q); \
277 MEM_EQUAL(u.info ## lvl1.field1.array, value, strlen(value), field1); \
279 TESTCALL(QueryUserInfo, q) \
281 MEM_EQUAL(u.info ## lvl2.field2.array, value, strlen(value), field2); \
284 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
285 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
287 TESTCALL(QueryUserInfo, q) \
289 s2.in.level = lvl1; \
292 uint8_t *bits = u.info21.logon_hours.bits; \
293 ZERO_STRUCT(u.info21); \
294 if (fpval == SAMR_FIELD_LOGON_HOURS) { \
295 u.info21.logon_hours.units_per_week = 168; \
296 u.info21.logon_hours.bits = bits; \
298 u.info21.fields_present = fpval; \
300 u.info ## lvl1.field1 = value; \
301 TESTCALL(SetUserInfo, s) \
302 TESTCALL(SetUserInfo2, s2) \
303 u.info ## lvl1.field1 = 0; \
304 TESTCALL(QueryUserInfo, q); \
306 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
308 TESTCALL(QueryUserInfo, q) \
310 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
313 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
314 TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
318 do { TESTCALL(QueryUserInfo, q0) } while (0);
320 TEST_USERINFO_STRING(2, comment, 1, comment, "xx2-1 comment", 0);
321 TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
322 TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment",
325 test_account_name = talloc_asprintf(tctx, "%sxx7-1", base_account_name);
326 TEST_USERINFO_STRING(7, account_name, 1, account_name, base_account_name, 0);
327 test_account_name = talloc_asprintf(tctx, "%sxx7-3", base_account_name);
328 TEST_USERINFO_STRING(7, account_name, 3, account_name, base_account_name, 0);
329 test_account_name = talloc_asprintf(tctx, "%sxx7-5", base_account_name);
330 TEST_USERINFO_STRING(7, account_name, 5, account_name, base_account_name, 0);
331 test_account_name = talloc_asprintf(tctx, "%sxx7-6", base_account_name);
332 TEST_USERINFO_STRING(7, account_name, 6, account_name, base_account_name, 0);
333 test_account_name = talloc_asprintf(tctx, "%sxx7-7", base_account_name);
334 TEST_USERINFO_STRING(7, account_name, 7, account_name, base_account_name, 0);
335 test_account_name = talloc_asprintf(tctx, "%sxx7-21", base_account_name);
336 TEST_USERINFO_STRING(7, account_name, 21, account_name, base_account_name, 0);
337 test_account_name = base_account_name;
338 TEST_USERINFO_STRING(21, account_name, 21, account_name, base_account_name,
339 SAMR_FIELD_ACCOUNT_NAME);
341 TEST_USERINFO_STRING(6, full_name, 1, full_name, "xx6-1 full_name", 0);
342 TEST_USERINFO_STRING(6, full_name, 3, full_name, "xx6-3 full_name", 0);
343 TEST_USERINFO_STRING(6, full_name, 5, full_name, "xx6-5 full_name", 0);
344 TEST_USERINFO_STRING(6, full_name, 6, full_name, "xx6-6 full_name", 0);
345 TEST_USERINFO_STRING(6, full_name, 8, full_name, "xx6-8 full_name", 0);
346 TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
347 TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
348 TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name",
349 SAMR_FIELD_FULL_NAME);
351 TEST_USERINFO_STRING(6, full_name, 1, full_name, "", 0);
352 TEST_USERINFO_STRING(6, full_name, 3, full_name, "", 0);
353 TEST_USERINFO_STRING(6, full_name, 5, full_name, "", 0);
354 TEST_USERINFO_STRING(6, full_name, 6, full_name, "", 0);
355 TEST_USERINFO_STRING(6, full_name, 8, full_name, "", 0);
356 TEST_USERINFO_STRING(6, full_name, 21, full_name, "", 0);
357 TEST_USERINFO_STRING(8, full_name, 21, full_name, "", 0);
358 TEST_USERINFO_STRING(21, full_name, 21, full_name, "",
359 SAMR_FIELD_FULL_NAME);
361 TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
362 TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
363 TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
364 TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script",
365 SAMR_FIELD_LOGON_SCRIPT);
367 TEST_USERINFO_STRING(12, profile_path, 3, profile_path, "xx12-3 profile_path", 0);
368 TEST_USERINFO_STRING(12, profile_path, 5, profile_path, "xx12-5 profile_path", 0);
369 TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
370 TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path",
371 SAMR_FIELD_PROFILE_PATH);
373 TEST_USERINFO_STRING(10, home_directory, 3, home_directory, "xx10-3 home_directory", 0);
374 TEST_USERINFO_STRING(10, home_directory, 5, home_directory, "xx10-5 home_directory", 0);
375 TEST_USERINFO_STRING(10, home_directory, 21, home_directory, "xx10-21 home_directory", 0);
376 TEST_USERINFO_STRING(21, home_directory, 21, home_directory, "xx21-21 home_directory",
377 SAMR_FIELD_HOME_DIRECTORY);
378 TEST_USERINFO_STRING(21, home_directory, 10, home_directory, "xx21-10 home_directory",
379 SAMR_FIELD_HOME_DIRECTORY);
381 TEST_USERINFO_STRING(10, home_drive, 3, home_drive, "xx10-3 home_drive", 0);
382 TEST_USERINFO_STRING(10, home_drive, 5, home_drive, "xx10-5 home_drive", 0);
383 TEST_USERINFO_STRING(10, home_drive, 21, home_drive, "xx10-21 home_drive", 0);
384 TEST_USERINFO_STRING(21, home_drive, 21, home_drive, "xx21-21 home_drive",
385 SAMR_FIELD_HOME_DRIVE);
386 TEST_USERINFO_STRING(21, home_drive, 10, home_drive, "xx21-10 home_drive",
387 SAMR_FIELD_HOME_DRIVE);
389 TEST_USERINFO_STRING(13, description, 1, description, "xx13-1 description", 0);
390 TEST_USERINFO_STRING(13, description, 5, description, "xx13-5 description", 0);
391 TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
392 TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description",
393 SAMR_FIELD_DESCRIPTION);
395 TEST_USERINFO_STRING(14, workstations, 3, workstations, "14workstation3", 0);
396 TEST_USERINFO_STRING(14, workstations, 5, workstations, "14workstation4", 0);
397 TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
398 TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21",
399 SAMR_FIELD_WORKSTATIONS);
400 TEST_USERINFO_STRING(21, workstations, 3, workstations, "21workstation3",
401 SAMR_FIELD_WORKSTATIONS);
402 TEST_USERINFO_STRING(21, workstations, 5, workstations, "21workstation5",
403 SAMR_FIELD_WORKSTATIONS);
404 TEST_USERINFO_STRING(21, workstations, 14, workstations, "21workstation14",
405 SAMR_FIELD_WORKSTATIONS);
407 TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
408 TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "xx21-21 parameters",
409 SAMR_FIELD_PARAMETERS);
410 TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "xx21-20 parameters",
411 SAMR_FIELD_PARAMETERS);
413 TEST_USERINFO_INT(2, country_code, 2, country_code, __LINE__, 0);
414 TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
415 TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__,
416 SAMR_FIELD_COUNTRY_CODE);
417 TEST_USERINFO_INT(21, country_code, 2, country_code, __LINE__,
418 SAMR_FIELD_COUNTRY_CODE);
420 TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
421 TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__,
422 SAMR_FIELD_CODE_PAGE);
423 TEST_USERINFO_INT(21, code_page, 2, code_page, __LINE__,
424 SAMR_FIELD_CODE_PAGE);
426 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, __LINE__, 0);
427 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, __LINE__, 0);
428 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, __LINE__,
429 SAMR_FIELD_ACCT_EXPIRY);
430 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, __LINE__,
431 SAMR_FIELD_ACCT_EXPIRY);
432 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, __LINE__,
433 SAMR_FIELD_ACCT_EXPIRY);
435 TEST_USERINFO_INT(4, logon_hours.bits[3], 3, logon_hours.bits[3], 1, 0);
436 TEST_USERINFO_INT(4, logon_hours.bits[3], 5, logon_hours.bits[3], 2, 0);
437 TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
438 TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4,
439 SAMR_FIELD_LOGON_HOURS);
441 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
442 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
443 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
445 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
446 (base_acct_flags | ACB_DISABLED),
447 (base_acct_flags | ACB_DISABLED | user_extra_flags),
450 /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
451 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
452 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
453 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
455 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
456 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
457 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
461 /* The 'autolock' flag doesn't stick - check this */
462 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
463 (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK),
464 (base_acct_flags | ACB_DISABLED | user_extra_flags),
467 /* Removing the 'disabled' flag doesn't stick - check this */
468 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
470 (base_acct_flags | ACB_DISABLED | user_extra_flags),
473 /* The 'store plaintext' flag does stick */
474 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
475 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED),
476 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags),
478 /* The 'use DES' flag does stick */
479 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
480 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY),
481 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags),
483 /* The 'don't require kerberos pre-authentication flag does stick */
484 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
485 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH),
486 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags),
488 /* The 'no kerberos PAC required' flag sticks */
489 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
490 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD),
491 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags),
494 TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags,
495 (base_acct_flags | ACB_DISABLED),
496 (base_acct_flags | ACB_DISABLED | user_extra_flags),
497 SAMR_FIELD_ACCT_FLAGS);
500 /* these fail with win2003 - it appears you can't set the primary gid?
501 the set succeeds, but the gid isn't changed. Very weird! */
502 TEST_USERINFO_INT(9, primary_gid, 1, primary_gid, 513);
503 TEST_USERINFO_INT(9, primary_gid, 3, primary_gid, 513);
504 TEST_USERINFO_INT(9, primary_gid, 5, primary_gid, 513);
505 TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
512 generate a random password for password change tests
514 static char *samr_rand_pass_silent(TALLOC_CTX *mem_ctx, int min_len)
516 size_t len = MAX(8, min_len) + (random() % 6);
517 char *s = generate_random_str(mem_ctx, len);
521 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
523 char *s = samr_rand_pass_silent(mem_ctx, min_len);
524 printf("Generated password '%s'\n", s);
530 generate a random password for password change tests
532 static DATA_BLOB samr_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
535 DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
536 generate_random_buffer(password.data, password.length);
538 for (i=0; i < len; i++) {
539 if (((uint16_t *)password.data)[i] == 0) {
540 ((uint16_t *)password.data)[i] = 1;
548 generate a random password for password change tests (fixed length)
550 static char *samr_rand_pass_fixed_len(TALLOC_CTX *mem_ctx, int len)
552 char *s = generate_random_str(mem_ctx, len);
553 printf("Generated password '%s'\n", s);
557 static bool test_SetUserPass(struct dcerpc_pipe *p, struct torture_context *tctx,
558 struct policy_handle *handle, char **password)
561 struct samr_SetUserInfo s;
562 union samr_UserInfo u;
564 DATA_BLOB session_key;
566 struct samr_GetUserPwInfo pwp;
567 struct samr_PwInfo info;
568 int policy_min_pw_len = 0;
569 pwp.in.user_handle = handle;
570 pwp.out.info = &info;
572 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
573 if (NT_STATUS_IS_OK(status)) {
574 policy_min_pw_len = pwp.out.info->min_password_length;
576 newpass = samr_rand_pass(tctx, policy_min_pw_len);
578 s.in.user_handle = handle;
582 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
583 u.info24.password_expired = 0;
585 status = dcerpc_fetch_session_key(p, &session_key);
586 if (!NT_STATUS_IS_OK(status)) {
587 printf("SetUserInfo level %u - no session key - %s\n",
588 s.in.level, nt_errstr(status));
592 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
594 torture_comment(tctx, "Testing SetUserInfo level 24 (set password)\n");
596 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
597 if (!NT_STATUS_IS_OK(status)) {
598 printf("SetUserInfo level %u failed - %s\n",
599 s.in.level, nt_errstr(status));
609 static bool test_SetUserPass_23(struct dcerpc_pipe *p, struct torture_context *tctx,
610 struct policy_handle *handle, uint32_t fields_present,
614 struct samr_SetUserInfo s;
615 union samr_UserInfo u;
617 DATA_BLOB session_key;
619 struct samr_GetUserPwInfo pwp;
620 struct samr_PwInfo info;
621 int policy_min_pw_len = 0;
622 pwp.in.user_handle = handle;
623 pwp.out.info = &info;
625 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
626 if (NT_STATUS_IS_OK(status)) {
627 policy_min_pw_len = pwp.out.info->min_password_length;
629 newpass = samr_rand_pass(tctx, policy_min_pw_len);
631 s.in.user_handle = handle;
637 u.info23.info.fields_present = fields_present;
639 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
641 status = dcerpc_fetch_session_key(p, &session_key);
642 if (!NT_STATUS_IS_OK(status)) {
643 printf("SetUserInfo level %u - no session key - %s\n",
644 s.in.level, nt_errstr(status));
648 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
650 torture_comment(tctx, "Testing SetUserInfo level 23 (set password)\n");
652 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
653 if (!NT_STATUS_IS_OK(status)) {
654 printf("SetUserInfo level %u failed - %s\n",
655 s.in.level, nt_errstr(status));
661 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
663 status = dcerpc_fetch_session_key(p, &session_key);
664 if (!NT_STATUS_IS_OK(status)) {
665 printf("SetUserInfo level %u - no session key - %s\n",
666 s.in.level, nt_errstr(status));
670 /* This should break the key nicely */
671 session_key.length--;
672 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
674 torture_comment(tctx, "Testing SetUserInfo level 23 (set password) with wrong password\n");
676 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
677 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
678 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
679 s.in.level, nt_errstr(status));
687 static bool test_SetUserPassEx(struct dcerpc_pipe *p, struct torture_context *tctx,
688 struct policy_handle *handle, bool makeshort,
692 struct samr_SetUserInfo s;
693 union samr_UserInfo u;
695 DATA_BLOB session_key;
696 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
697 uint8_t confounder[16];
699 struct MD5Context ctx;
700 struct samr_GetUserPwInfo pwp;
701 struct samr_PwInfo info;
702 int policy_min_pw_len = 0;
703 pwp.in.user_handle = handle;
704 pwp.out.info = &info;
706 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
707 if (NT_STATUS_IS_OK(status)) {
708 policy_min_pw_len = pwp.out.info->min_password_length;
710 if (makeshort && policy_min_pw_len) {
711 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len - 1);
713 newpass = samr_rand_pass(tctx, policy_min_pw_len);
716 s.in.user_handle = handle;
720 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
721 u.info26.password_expired = 0;
723 status = dcerpc_fetch_session_key(p, &session_key);
724 if (!NT_STATUS_IS_OK(status)) {
725 printf("SetUserInfo level %u - no session key - %s\n",
726 s.in.level, nt_errstr(status));
730 generate_random_buffer((uint8_t *)confounder, 16);
733 MD5Update(&ctx, confounder, 16);
734 MD5Update(&ctx, session_key.data, session_key.length);
735 MD5Final(confounded_session_key.data, &ctx);
737 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
738 memcpy(&u.info26.password.data[516], confounder, 16);
740 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex)\n");
742 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
743 if (!NT_STATUS_IS_OK(status)) {
744 printf("SetUserInfo level %u failed - %s\n",
745 s.in.level, nt_errstr(status));
751 /* This should break the key nicely */
752 confounded_session_key.data[0]++;
754 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
755 memcpy(&u.info26.password.data[516], confounder, 16);
757 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
759 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
760 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
761 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
762 s.in.level, nt_errstr(status));
771 static bool test_SetUserPass_25(struct dcerpc_pipe *p, struct torture_context *tctx,
772 struct policy_handle *handle, uint32_t fields_present,
776 struct samr_SetUserInfo s;
777 union samr_UserInfo u;
779 DATA_BLOB session_key;
780 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
781 struct MD5Context ctx;
782 uint8_t confounder[16];
784 struct samr_GetUserPwInfo pwp;
785 struct samr_PwInfo info;
786 int policy_min_pw_len = 0;
787 pwp.in.user_handle = handle;
788 pwp.out.info = &info;
790 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
791 if (NT_STATUS_IS_OK(status)) {
792 policy_min_pw_len = pwp.out.info->min_password_length;
794 newpass = samr_rand_pass(tctx, policy_min_pw_len);
796 s.in.user_handle = handle;
802 u.info25.info.fields_present = fields_present;
804 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
806 status = dcerpc_fetch_session_key(p, &session_key);
807 if (!NT_STATUS_IS_OK(status)) {
808 printf("SetUserInfo level %u - no session key - %s\n",
809 s.in.level, nt_errstr(status));
813 generate_random_buffer((uint8_t *)confounder, 16);
816 MD5Update(&ctx, confounder, 16);
817 MD5Update(&ctx, session_key.data, session_key.length);
818 MD5Final(confounded_session_key.data, &ctx);
820 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
821 memcpy(&u.info25.password.data[516], confounder, 16);
823 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex)\n");
825 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
826 if (!NT_STATUS_IS_OK(status)) {
827 printf("SetUserInfo level %u failed - %s\n",
828 s.in.level, nt_errstr(status));
834 /* This should break the key nicely */
835 confounded_session_key.data[0]++;
837 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
838 memcpy(&u.info25.password.data[516], confounder, 16);
840 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
842 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
843 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
844 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
845 s.in.level, nt_errstr(status));
852 static bool test_SetUserPass_level_ex(struct dcerpc_pipe *p,
853 struct torture_context *tctx,
854 struct policy_handle *handle,
856 uint32_t fields_present,
857 char **password, uint8_t password_expired,
858 bool use_setinfo2, NTSTATUS expected_error)
861 struct samr_SetUserInfo s;
862 struct samr_SetUserInfo2 s2;
863 union samr_UserInfo u;
865 DATA_BLOB session_key;
866 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
867 struct MD5Context ctx;
868 uint8_t confounder[16];
870 struct samr_GetUserPwInfo pwp;
871 struct samr_PwInfo info;
872 int policy_min_pw_len = 0;
873 pwp.in.user_handle = handle;
874 pwp.out.info = &info;
876 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
877 if (NT_STATUS_IS_OK(status)) {
878 policy_min_pw_len = pwp.out.info->min_password_length;
880 newpass = samr_rand_pass_silent(tctx, policy_min_pw_len);
883 s2.in.user_handle = handle;
887 s.in.user_handle = handle;
896 u.info21.fields_present = fields_present;
897 u.info21.password_expired = password_expired;
901 u.info23.info.fields_present = fields_present;
902 u.info23.info.password_expired = password_expired;
904 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
908 u.info24.password_expired = password_expired;
910 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
914 u.info25.info.fields_present = fields_present;
915 u.info25.info.password_expired = password_expired;
917 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
921 u.info26.password_expired = password_expired;
923 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
928 status = dcerpc_fetch_session_key(p, &session_key);
929 if (!NT_STATUS_IS_OK(status)) {
930 printf("SetUserInfo level %u - no session key - %s\n",
931 s.in.level, nt_errstr(status));
935 generate_random_buffer((uint8_t *)confounder, 16);
938 MD5Update(&ctx, confounder, 16);
939 MD5Update(&ctx, session_key.data, session_key.length);
940 MD5Final(confounded_session_key.data, &ctx);
944 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
947 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
950 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
951 memcpy(&u.info25.password.data[516], confounder, 16);
954 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
955 memcpy(&u.info26.password.data[516], confounder, 16);
960 status = dcerpc_samr_SetUserInfo2(p, tctx, &s2);
962 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
965 if (NT_STATUS_IS_ERR(expected_error)) {
966 torture_assert_ntstatus_equal(tctx, status, expected_error, "");
970 if (!NT_STATUS_IS_OK(status)) {
971 printf("SetUserInfo%s level %u failed - %s\n",
972 use_setinfo2 ? "2":"", level, nt_errstr(status));
983 static bool test_SetAliasInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
984 struct policy_handle *handle)
987 struct samr_SetAliasInfo r;
988 struct samr_QueryAliasInfo q;
989 union samr_AliasInfo *info;
990 uint16_t levels[] = {2, 3};
994 /* Ignoring switch level 1, as that includes the number of members for the alias
995 * and setting this to a wrong value might have negative consequences
998 for (i=0;i<ARRAY_SIZE(levels);i++) {
999 torture_comment(tctx, "Testing SetAliasInfo level %u\n", levels[i]);
1001 r.in.alias_handle = handle;
1002 r.in.level = levels[i];
1003 r.in.info = talloc(tctx, union samr_AliasInfo);
1004 switch (r.in.level) {
1005 case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
1006 case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
1007 "Test Description, should test I18N as well"); break;
1008 case ALIASINFOALL: printf("ALIASINFOALL ignored\n"); break;
1011 status = dcerpc_samr_SetAliasInfo(p, tctx, &r);
1012 if (!NT_STATUS_IS_OK(status)) {
1013 printf("SetAliasInfo level %u failed - %s\n",
1014 levels[i], nt_errstr(status));
1018 q.in.alias_handle = handle;
1019 q.in.level = levels[i];
1022 status = dcerpc_samr_QueryAliasInfo(p, tctx, &q);
1023 if (!NT_STATUS_IS_OK(status)) {
1024 printf("QueryAliasInfo level %u failed - %s\n",
1025 levels[i], nt_errstr(status));
1033 static bool test_GetGroupsForUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1034 struct policy_handle *user_handle)
1036 struct samr_GetGroupsForUser r;
1037 struct samr_RidWithAttributeArray *rids = NULL;
1040 torture_comment(tctx, "testing GetGroupsForUser\n");
1042 r.in.user_handle = user_handle;
1045 status = dcerpc_samr_GetGroupsForUser(p, tctx, &r);
1046 torture_assert_ntstatus_ok(tctx, status, "GetGroupsForUser");
1052 static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1053 struct lsa_String *domain_name)
1056 struct samr_GetDomPwInfo r;
1057 struct samr_PwInfo info;
1059 r.in.domain_name = domain_name;
1062 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1064 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1065 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1067 r.in.domain_name->string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1068 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1070 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1071 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1073 r.in.domain_name->string = "\\\\__NONAME__";
1074 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1076 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1077 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1079 r.in.domain_name->string = "\\\\Builtin";
1080 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1082 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1083 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1088 static bool test_GetUserPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1089 struct policy_handle *handle)
1092 struct samr_GetUserPwInfo r;
1093 struct samr_PwInfo info;
1095 torture_comment(tctx, "Testing GetUserPwInfo\n");
1097 r.in.user_handle = handle;
1100 status = dcerpc_samr_GetUserPwInfo(p, tctx, &r);
1101 torture_assert_ntstatus_ok(tctx, status, "GetUserPwInfo");
1106 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, struct torture_context *tctx,
1107 struct policy_handle *domain_handle, const char *name,
1111 struct samr_LookupNames n;
1112 struct lsa_String sname[2];
1113 struct samr_Ids rids, types;
1115 init_lsa_String(&sname[0], name);
1117 n.in.domain_handle = domain_handle;
1121 n.out.types = &types;
1122 status = dcerpc_samr_LookupNames(p, tctx, &n);
1123 if (NT_STATUS_IS_OK(status)) {
1124 *rid = n.out.rids->ids[0];
1129 init_lsa_String(&sname[1], "xxNONAMExx");
1131 status = dcerpc_samr_LookupNames(p, tctx, &n);
1132 if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
1133 printf("LookupNames[2] failed - %s\n", nt_errstr(status));
1134 if (NT_STATUS_IS_OK(status)) {
1135 return NT_STATUS_UNSUCCESSFUL;
1141 status = dcerpc_samr_LookupNames(p, tctx, &n);
1142 if (!NT_STATUS_IS_OK(status)) {
1143 printf("LookupNames[0] failed - %s\n", nt_errstr(status));
1147 init_lsa_String(&sname[0], "xxNONAMExx");
1149 status = dcerpc_samr_LookupNames(p, tctx, &n);
1150 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1151 printf("LookupNames[1 bad name] failed - %s\n", nt_errstr(status));
1152 if (NT_STATUS_IS_OK(status)) {
1153 return NT_STATUS_UNSUCCESSFUL;
1158 init_lsa_String(&sname[0], "xxNONAMExx");
1159 init_lsa_String(&sname[1], "xxNONAME2xx");
1161 status = dcerpc_samr_LookupNames(p, tctx, &n);
1162 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1163 printf("LookupNames[2 bad names] failed - %s\n", nt_errstr(status));
1164 if (NT_STATUS_IS_OK(status)) {
1165 return NT_STATUS_UNSUCCESSFUL;
1170 return NT_STATUS_OK;
1173 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1174 struct policy_handle *domain_handle,
1175 const char *name, struct policy_handle *user_handle)
1178 struct samr_OpenUser r;
1181 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
1182 if (!NT_STATUS_IS_OK(status)) {
1186 r.in.domain_handle = domain_handle;
1187 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1189 r.out.user_handle = user_handle;
1190 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
1191 if (!NT_STATUS_IS_OK(status)) {
1192 printf("OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(status));
1199 static bool test_ChangePasswordNT3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1200 struct policy_handle *handle)
1203 struct samr_ChangePasswordUser r;
1205 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1206 struct policy_handle user_handle;
1207 char *oldpass = "test";
1208 char *newpass = "test2";
1209 uint8_t old_nt_hash[16], new_nt_hash[16];
1210 uint8_t old_lm_hash[16], new_lm_hash[16];
1212 status = test_OpenUser_byname(p, mem_ctx, handle, "testuser", &user_handle);
1213 if (!NT_STATUS_IS_OK(status)) {
1217 printf("Testing ChangePasswordUser for user 'testuser'\n");
1219 printf("old password: %s\n", oldpass);
1220 printf("new password: %s\n", newpass);
1222 E_md4hash(oldpass, old_nt_hash);
1223 E_md4hash(newpass, new_nt_hash);
1224 E_deshash(oldpass, old_lm_hash);
1225 E_deshash(newpass, new_lm_hash);
1227 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1228 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1229 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1230 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1231 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1232 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1234 r.in.handle = &user_handle;
1235 r.in.lm_present = 1;
1236 r.in.old_lm_crypted = &hash1;
1237 r.in.new_lm_crypted = &hash2;
1238 r.in.nt_present = 1;
1239 r.in.old_nt_crypted = &hash3;
1240 r.in.new_nt_crypted = &hash4;
1241 r.in.cross1_present = 1;
1242 r.in.nt_cross = &hash5;
1243 r.in.cross2_present = 1;
1244 r.in.lm_cross = &hash6;
1246 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1247 if (!NT_STATUS_IS_OK(status)) {
1248 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1252 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1260 static bool test_ChangePasswordUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1261 const char *acct_name,
1262 struct policy_handle *handle, char **password)
1265 struct samr_ChangePasswordUser r;
1267 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1268 struct policy_handle user_handle;
1270 uint8_t old_nt_hash[16], new_nt_hash[16];
1271 uint8_t old_lm_hash[16], new_lm_hash[16];
1272 bool changed = true;
1275 struct samr_GetUserPwInfo pwp;
1276 struct samr_PwInfo info;
1277 int policy_min_pw_len = 0;
1279 status = test_OpenUser_byname(p, tctx, handle, acct_name, &user_handle);
1280 if (!NT_STATUS_IS_OK(status)) {
1283 pwp.in.user_handle = &user_handle;
1284 pwp.out.info = &info;
1286 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1287 if (NT_STATUS_IS_OK(status)) {
1288 policy_min_pw_len = pwp.out.info->min_password_length;
1290 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1292 torture_comment(tctx, "Testing ChangePasswordUser\n");
1294 torture_assert(tctx, *password != NULL,
1295 "Failing ChangePasswordUser as old password was NULL. Previous test failed?");
1297 oldpass = *password;
1299 E_md4hash(oldpass, old_nt_hash);
1300 E_md4hash(newpass, new_nt_hash);
1301 E_deshash(oldpass, old_lm_hash);
1302 E_deshash(newpass, new_lm_hash);
1304 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1305 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1306 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1307 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1308 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1309 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1311 r.in.user_handle = &user_handle;
1312 r.in.lm_present = 1;
1313 /* Break the LM hash */
1315 r.in.old_lm_crypted = &hash1;
1316 r.in.new_lm_crypted = &hash2;
1317 r.in.nt_present = 1;
1318 r.in.old_nt_crypted = &hash3;
1319 r.in.new_nt_crypted = &hash4;
1320 r.in.cross1_present = 1;
1321 r.in.nt_cross = &hash5;
1322 r.in.cross2_present = 1;
1323 r.in.lm_cross = &hash6;
1325 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1326 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1327 "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash");
1329 /* Unbreak the LM hash */
1332 r.in.user_handle = &user_handle;
1333 r.in.lm_present = 1;
1334 r.in.old_lm_crypted = &hash1;
1335 r.in.new_lm_crypted = &hash2;
1336 /* Break the NT hash */
1338 r.in.nt_present = 1;
1339 r.in.old_nt_crypted = &hash3;
1340 r.in.new_nt_crypted = &hash4;
1341 r.in.cross1_present = 1;
1342 r.in.nt_cross = &hash5;
1343 r.in.cross2_present = 1;
1344 r.in.lm_cross = &hash6;
1346 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1347 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1348 "expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash");
1350 /* Unbreak the NT hash */
1353 r.in.user_handle = &user_handle;
1354 r.in.lm_present = 1;
1355 r.in.old_lm_crypted = &hash1;
1356 r.in.new_lm_crypted = &hash2;
1357 r.in.nt_present = 1;
1358 r.in.old_nt_crypted = &hash3;
1359 r.in.new_nt_crypted = &hash4;
1360 r.in.cross1_present = 1;
1361 r.in.nt_cross = &hash5;
1362 r.in.cross2_present = 1;
1363 /* Break the LM cross */
1365 r.in.lm_cross = &hash6;
1367 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1368 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1369 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status));
1373 /* Unbreak the LM cross */
1376 r.in.user_handle = &user_handle;
1377 r.in.lm_present = 1;
1378 r.in.old_lm_crypted = &hash1;
1379 r.in.new_lm_crypted = &hash2;
1380 r.in.nt_present = 1;
1381 r.in.old_nt_crypted = &hash3;
1382 r.in.new_nt_crypted = &hash4;
1383 r.in.cross1_present = 1;
1384 /* Break the NT cross */
1386 r.in.nt_cross = &hash5;
1387 r.in.cross2_present = 1;
1388 r.in.lm_cross = &hash6;
1390 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1391 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1392 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status));
1396 /* Unbreak the NT cross */
1400 /* Reset the hashes to not broken values */
1401 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1402 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1403 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1404 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1405 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1406 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1408 r.in.user_handle = &user_handle;
1409 r.in.lm_present = 1;
1410 r.in.old_lm_crypted = &hash1;
1411 r.in.new_lm_crypted = &hash2;
1412 r.in.nt_present = 1;
1413 r.in.old_nt_crypted = &hash3;
1414 r.in.new_nt_crypted = &hash4;
1415 r.in.cross1_present = 1;
1416 r.in.nt_cross = &hash5;
1417 r.in.cross2_present = 0;
1418 r.in.lm_cross = NULL;
1420 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1421 if (NT_STATUS_IS_OK(status)) {
1423 *password = newpass;
1424 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1425 printf("ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(status));
1430 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1432 E_md4hash(oldpass, old_nt_hash);
1433 E_md4hash(newpass, new_nt_hash);
1434 E_deshash(oldpass, old_lm_hash);
1435 E_deshash(newpass, new_lm_hash);
1438 /* Reset the hashes to not broken values */
1439 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1440 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1441 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1442 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1443 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1444 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1446 r.in.user_handle = &user_handle;
1447 r.in.lm_present = 1;
1448 r.in.old_lm_crypted = &hash1;
1449 r.in.new_lm_crypted = &hash2;
1450 r.in.nt_present = 1;
1451 r.in.old_nt_crypted = &hash3;
1452 r.in.new_nt_crypted = &hash4;
1453 r.in.cross1_present = 0;
1454 r.in.nt_cross = NULL;
1455 r.in.cross2_present = 1;
1456 r.in.lm_cross = &hash6;
1458 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1459 if (NT_STATUS_IS_OK(status)) {
1461 *password = newpass;
1462 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1463 printf("ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status));
1468 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1470 E_md4hash(oldpass, old_nt_hash);
1471 E_md4hash(newpass, new_nt_hash);
1472 E_deshash(oldpass, old_lm_hash);
1473 E_deshash(newpass, new_lm_hash);
1476 /* Reset the hashes to not broken values */
1477 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1478 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1479 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1480 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1481 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1482 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1484 r.in.user_handle = &user_handle;
1485 r.in.lm_present = 1;
1486 r.in.old_lm_crypted = &hash1;
1487 r.in.new_lm_crypted = &hash2;
1488 r.in.nt_present = 1;
1489 r.in.old_nt_crypted = &hash3;
1490 r.in.new_nt_crypted = &hash4;
1491 r.in.cross1_present = 1;
1492 r.in.nt_cross = &hash5;
1493 r.in.cross2_present = 1;
1494 r.in.lm_cross = &hash6;
1496 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1497 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1498 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1499 } else if (!NT_STATUS_IS_OK(status)) {
1500 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1504 *password = newpass;
1507 r.in.user_handle = &user_handle;
1508 r.in.lm_present = 1;
1509 r.in.old_lm_crypted = &hash1;
1510 r.in.new_lm_crypted = &hash2;
1511 r.in.nt_present = 1;
1512 r.in.old_nt_crypted = &hash3;
1513 r.in.new_nt_crypted = &hash4;
1514 r.in.cross1_present = 1;
1515 r.in.nt_cross = &hash5;
1516 r.in.cross2_present = 1;
1517 r.in.lm_cross = &hash6;
1520 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1521 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1522 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1523 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1524 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status));
1530 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
1538 static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
1539 const char *acct_name,
1540 struct policy_handle *handle, char **password)
1543 struct samr_OemChangePasswordUser2 r;
1545 struct samr_Password lm_verifier;
1546 struct samr_CryptPassword lm_pass;
1547 struct lsa_AsciiString server, account, account_bad;
1550 uint8_t old_lm_hash[16], new_lm_hash[16];
1552 struct samr_GetDomPwInfo dom_pw_info;
1553 struct samr_PwInfo info;
1554 int policy_min_pw_len = 0;
1556 struct lsa_String domain_name;
1558 domain_name.string = "";
1559 dom_pw_info.in.domain_name = &domain_name;
1560 dom_pw_info.out.info = &info;
1562 torture_comment(tctx, "Testing OemChangePasswordUser2\n");
1564 torture_assert(tctx, *password != NULL,
1565 "Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?");
1567 oldpass = *password;
1569 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
1570 if (NT_STATUS_IS_OK(status)) {
1571 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
1574 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1576 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1577 account.string = acct_name;
1579 E_deshash(oldpass, old_lm_hash);
1580 E_deshash(newpass, new_lm_hash);
1582 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1583 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1584 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1586 r.in.server = &server;
1587 r.in.account = &account;
1588 r.in.password = &lm_pass;
1589 r.in.hash = &lm_verifier;
1591 /* Break the verification */
1592 lm_verifier.hash[0]++;
1594 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1596 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1597 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1598 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1603 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1604 /* Break the old password */
1606 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1607 /* unbreak it for the next operation */
1609 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1611 r.in.server = &server;
1612 r.in.account = &account;
1613 r.in.password = &lm_pass;
1614 r.in.hash = &lm_verifier;
1616 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1618 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1619 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1620 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1625 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1626 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1628 r.in.server = &server;
1629 r.in.account = &account;
1630 r.in.password = &lm_pass;
1633 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1635 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1636 && !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1637 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
1642 /* This shouldn't be a valid name */
1643 account_bad.string = TEST_ACCOUNT_NAME "XX";
1644 r.in.account = &account_bad;
1646 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1648 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1649 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
1654 /* This shouldn't be a valid name */
1655 account_bad.string = TEST_ACCOUNT_NAME "XX";
1656 r.in.account = &account_bad;
1657 r.in.password = &lm_pass;
1658 r.in.hash = &lm_verifier;
1660 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1662 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1663 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1668 /* This shouldn't be a valid name */
1669 account_bad.string = TEST_ACCOUNT_NAME "XX";
1670 r.in.account = &account_bad;
1671 r.in.password = NULL;
1672 r.in.hash = &lm_verifier;
1674 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1676 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1677 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
1682 E_deshash(oldpass, old_lm_hash);
1683 E_deshash(newpass, new_lm_hash);
1685 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1686 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1687 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1689 r.in.server = &server;
1690 r.in.account = &account;
1691 r.in.password = &lm_pass;
1692 r.in.hash = &lm_verifier;
1694 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1695 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1696 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1697 } else if (!NT_STATUS_IS_OK(status)) {
1698 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
1701 *password = newpass;
1708 static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
1709 const char *acct_name,
1711 char *newpass, bool allow_password_restriction)
1714 struct samr_ChangePasswordUser2 r;
1716 struct lsa_String server, account;
1717 struct samr_CryptPassword nt_pass, lm_pass;
1718 struct samr_Password nt_verifier, lm_verifier;
1720 uint8_t old_nt_hash[16], new_nt_hash[16];
1721 uint8_t old_lm_hash[16], new_lm_hash[16];
1723 struct samr_GetDomPwInfo dom_pw_info;
1724 struct samr_PwInfo info;
1726 struct lsa_String domain_name;
1728 domain_name.string = "";
1729 dom_pw_info.in.domain_name = &domain_name;
1730 dom_pw_info.out.info = &info;
1732 torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name);
1734 torture_assert(tctx, *password != NULL,
1735 "Failing ChangePasswordUser2 as old password was NULL. Previous test failed?");
1736 oldpass = *password;
1739 int policy_min_pw_len = 0;
1740 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
1741 if (NT_STATUS_IS_OK(status)) {
1742 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
1745 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1748 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1749 init_lsa_String(&account, acct_name);
1751 E_md4hash(oldpass, old_nt_hash);
1752 E_md4hash(newpass, new_nt_hash);
1754 E_deshash(oldpass, old_lm_hash);
1755 E_deshash(newpass, new_lm_hash);
1757 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
1758 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1759 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1761 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1762 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1763 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1765 r.in.server = &server;
1766 r.in.account = &account;
1767 r.in.nt_password = &nt_pass;
1768 r.in.nt_verifier = &nt_verifier;
1770 r.in.lm_password = &lm_pass;
1771 r.in.lm_verifier = &lm_verifier;
1773 status = dcerpc_samr_ChangePasswordUser2(p, tctx, &r);
1774 if (allow_password_restriction && NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1775 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1776 } else if (!NT_STATUS_IS_OK(status)) {
1777 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
1780 *password = newpass;
1787 bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tctx,
1788 const char *account_string,
1789 int policy_min_pw_len,
1791 const char *newpass,
1792 NTTIME last_password_change,
1793 bool handle_reject_reason)
1796 struct samr_ChangePasswordUser3 r;
1798 struct lsa_String server, account, account_bad;
1799 struct samr_CryptPassword nt_pass, lm_pass;
1800 struct samr_Password nt_verifier, lm_verifier;
1802 uint8_t old_nt_hash[16], new_nt_hash[16];
1803 uint8_t old_lm_hash[16], new_lm_hash[16];
1805 struct samr_DomInfo1 *dominfo = NULL;
1806 struct samr_ChangeReject *reject = NULL;
1808 torture_comment(tctx, "Testing ChangePasswordUser3\n");
1810 if (newpass == NULL) {
1812 if (policy_min_pw_len == 0) {
1813 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1815 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len);
1817 } while (check_password_quality(newpass) == false);
1819 torture_comment(tctx, "Using password '%s'\n", newpass);
1822 torture_assert(tctx, *password != NULL,
1823 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
1825 oldpass = *password;
1826 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1827 init_lsa_String(&account, account_string);
1829 E_md4hash(oldpass, old_nt_hash);
1830 E_md4hash(newpass, new_nt_hash);
1832 E_deshash(oldpass, old_lm_hash);
1833 E_deshash(newpass, new_lm_hash);
1835 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1836 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1837 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1839 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1840 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1841 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1843 /* Break the verification */
1844 nt_verifier.hash[0]++;
1846 r.in.server = &server;
1847 r.in.account = &account;
1848 r.in.nt_password = &nt_pass;
1849 r.in.nt_verifier = &nt_verifier;
1851 r.in.lm_password = &lm_pass;
1852 r.in.lm_verifier = &lm_verifier;
1853 r.in.password3 = NULL;
1854 r.out.dominfo = &dominfo;
1855 r.out.reject = &reject;
1857 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1858 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1859 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1860 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1865 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1866 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1867 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1869 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1870 /* Break the NT hash */
1872 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1873 /* Unbreak it again */
1875 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1877 r.in.server = &server;
1878 r.in.account = &account;
1879 r.in.nt_password = &nt_pass;
1880 r.in.nt_verifier = &nt_verifier;
1882 r.in.lm_password = &lm_pass;
1883 r.in.lm_verifier = &lm_verifier;
1884 r.in.password3 = NULL;
1885 r.out.dominfo = &dominfo;
1886 r.out.reject = &reject;
1888 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1889 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1890 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1891 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1896 /* This shouldn't be a valid name */
1897 init_lsa_String(&account_bad, talloc_asprintf(tctx, "%sXX", account_string));
1899 r.in.account = &account_bad;
1900 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1901 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1902 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
1907 E_md4hash(oldpass, old_nt_hash);
1908 E_md4hash(newpass, new_nt_hash);
1910 E_deshash(oldpass, old_lm_hash);
1911 E_deshash(newpass, new_lm_hash);
1913 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1914 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1915 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1917 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1918 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1919 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1921 r.in.server = &server;
1922 r.in.account = &account;
1923 r.in.nt_password = &nt_pass;
1924 r.in.nt_verifier = &nt_verifier;
1926 r.in.lm_password = &lm_pass;
1927 r.in.lm_verifier = &lm_verifier;
1928 r.in.password3 = NULL;
1929 r.out.dominfo = &dominfo;
1930 r.out.reject = &reject;
1932 unix_to_nt_time(&t, time(NULL));
1934 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1936 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1939 && handle_reject_reason
1940 && (!null_nttime(last_password_change) || !dominfo->min_password_age)) {
1941 if (dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
1943 if (reject && (reject->reason != SAMR_REJECT_OTHER)) {
1944 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1945 SAMR_REJECT_OTHER, reject->reason);
1950 /* We tested the order of precendence which is as follows:
1959 if ((dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
1960 (last_password_change + dominfo->min_password_age > t)) {
1962 if (reject->reason != SAMR_REJECT_OTHER) {
1963 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1964 SAMR_REJECT_OTHER, reject->reason);
1968 } else if ((dominfo->min_password_length > 0) &&
1969 (strlen(newpass) < dominfo->min_password_length)) {
1971 if (reject->reason != SAMR_REJECT_TOO_SHORT) {
1972 printf("expected SAMR_REJECT_TOO_SHORT (%d), got %d\n",
1973 SAMR_REJECT_TOO_SHORT, reject->reason);
1977 } else if ((dominfo->password_history_length > 0) &&
1978 strequal(oldpass, newpass)) {
1980 if (reject->reason != SAMR_REJECT_IN_HISTORY) {
1981 printf("expected SAMR_REJECT_IN_HISTORY (%d), got %d\n",
1982 SAMR_REJECT_IN_HISTORY, reject->reason);
1985 } else if (dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
1987 if (reject->reason != SAMR_REJECT_COMPLEXITY) {
1988 printf("expected SAMR_REJECT_COMPLEXITY (%d), got %d\n",
1989 SAMR_REJECT_COMPLEXITY, reject->reason);
1995 if (reject->reason == SAMR_REJECT_TOO_SHORT) {
1996 /* retry with adjusted size */
1997 return test_ChangePasswordUser3(p, tctx, account_string,
1998 dominfo->min_password_length,
1999 password, NULL, 0, false);
2003 } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2004 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2005 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2006 SAMR_REJECT_OTHER, reject->reason);
2009 /* Perhaps the server has a 'min password age' set? */
2012 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3");
2013 *password = talloc_strdup(tctx, newpass);
2019 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_context *tctx,
2020 const char *account_string,
2021 struct policy_handle *handle,
2025 struct samr_ChangePasswordUser3 r;
2026 struct samr_SetUserInfo s;
2027 union samr_UserInfo u;
2028 DATA_BLOB session_key;
2029 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
2030 uint8_t confounder[16];
2031 struct MD5Context ctx;
2034 struct lsa_String server, account;
2035 struct samr_CryptPassword nt_pass;
2036 struct samr_Password nt_verifier;
2037 DATA_BLOB new_random_pass;
2040 uint8_t old_nt_hash[16], new_nt_hash[16];
2042 struct samr_DomInfo1 *dominfo = NULL;
2043 struct samr_ChangeReject *reject = NULL;
2045 new_random_pass = samr_very_rand_pass(tctx, 128);
2047 torture_assert(tctx, *password != NULL,
2048 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2050 oldpass = *password;
2051 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2052 init_lsa_String(&account, account_string);
2054 s.in.user_handle = handle;
2060 u.info25.info.fields_present = SAMR_FIELD_PASSWORD;
2062 set_pw_in_buffer(u.info25.password.data, &new_random_pass);
2064 status = dcerpc_fetch_session_key(p, &session_key);
2065 if (!NT_STATUS_IS_OK(status)) {
2066 printf("SetUserInfo level %u - no session key - %s\n",
2067 s.in.level, nt_errstr(status));
2071 generate_random_buffer((uint8_t *)confounder, 16);
2074 MD5Update(&ctx, confounder, 16);
2075 MD5Update(&ctx, session_key.data, session_key.length);
2076 MD5Final(confounded_session_key.data, &ctx);
2078 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
2079 memcpy(&u.info25.password.data[516], confounder, 16);
2081 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
2083 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
2084 if (!NT_STATUS_IS_OK(status)) {
2085 printf("SetUserInfo level %u failed - %s\n",
2086 s.in.level, nt_errstr(status));
2090 torture_comment(tctx, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
2092 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2094 new_random_pass = samr_very_rand_pass(tctx, 128);
2096 mdfour(new_nt_hash, new_random_pass.data, new_random_pass.length);
2098 set_pw_in_buffer(nt_pass.data, &new_random_pass);
2099 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2100 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2102 r.in.server = &server;
2103 r.in.account = &account;
2104 r.in.nt_password = &nt_pass;
2105 r.in.nt_verifier = &nt_verifier;
2107 r.in.lm_password = NULL;
2108 r.in.lm_verifier = NULL;
2109 r.in.password3 = NULL;
2110 r.out.dominfo = &dominfo;
2111 r.out.reject = &reject;
2113 unix_to_nt_time(&t, time(NULL));
2115 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2117 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2118 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2119 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2120 SAMR_REJECT_OTHER, reject->reason);
2123 /* Perhaps the server has a 'min password age' set? */
2125 } else if (!NT_STATUS_IS_OK(status)) {
2126 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
2130 newpass = samr_rand_pass(tctx, 128);
2132 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2134 E_md4hash(newpass, new_nt_hash);
2136 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2137 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2138 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2140 r.in.server = &server;
2141 r.in.account = &account;
2142 r.in.nt_password = &nt_pass;
2143 r.in.nt_verifier = &nt_verifier;
2145 r.in.lm_password = NULL;
2146 r.in.lm_verifier = NULL;
2147 r.in.password3 = NULL;
2148 r.out.dominfo = &dominfo;
2149 r.out.reject = &reject;
2151 unix_to_nt_time(&t, time(NULL));
2153 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2155 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2156 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2157 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2158 SAMR_REJECT_OTHER, reject->reason);
2161 /* Perhaps the server has a 'min password age' set? */
2164 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3 (on second random password)");
2165 *password = talloc_strdup(tctx, newpass);
2172 static bool test_GetMembersInAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2173 struct policy_handle *alias_handle)
2175 struct samr_GetMembersInAlias r;
2176 struct lsa_SidArray sids;
2179 torture_comment(tctx, "Testing GetMembersInAlias\n");
2181 r.in.alias_handle = alias_handle;
2184 status = dcerpc_samr_GetMembersInAlias(p, tctx, &r);
2185 torture_assert_ntstatus_ok(tctx, status, "GetMembersInAlias");
2190 static bool test_AddMemberToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2191 struct policy_handle *alias_handle,
2192 const struct dom_sid *domain_sid)
2194 struct samr_AddAliasMember r;
2195 struct samr_DeleteAliasMember d;
2197 struct dom_sid *sid;
2199 sid = dom_sid_add_rid(tctx, domain_sid, 512);
2201 torture_comment(tctx, "testing AddAliasMember\n");
2202 r.in.alias_handle = alias_handle;
2205 status = dcerpc_samr_AddAliasMember(p, tctx, &r);
2206 torture_assert_ntstatus_ok(tctx, status, "AddAliasMember");
2208 d.in.alias_handle = alias_handle;
2211 status = dcerpc_samr_DeleteAliasMember(p, tctx, &d);
2212 torture_assert_ntstatus_ok(tctx, status, "DelAliasMember");
2217 static bool test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2218 struct policy_handle *alias_handle)
2220 struct samr_AddMultipleMembersToAlias a;
2221 struct samr_RemoveMultipleMembersFromAlias r;
2223 struct lsa_SidArray sids;
2225 torture_comment(tctx, "testing AddMultipleMembersToAlias\n");
2226 a.in.alias_handle = alias_handle;
2230 sids.sids = talloc_array(tctx, struct lsa_SidPtr, 3);
2232 sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2233 sids.sids[1].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-2");
2234 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-3");
2236 status = dcerpc_samr_AddMultipleMembersToAlias(p, tctx, &a);
2237 torture_assert_ntstatus_ok(tctx, status, "AddMultipleMembersToAlias");
2240 torture_comment(tctx, "testing RemoveMultipleMembersFromAlias\n");
2241 r.in.alias_handle = alias_handle;
2244 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2245 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2247 /* strange! removing twice doesn't give any error */
2248 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2249 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2251 /* but removing an alias that isn't there does */
2252 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-4");
2254 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2255 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, "RemoveMultipleMembersFromAlias");
2260 static bool test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2261 struct policy_handle *user_handle)
2263 struct samr_TestPrivateFunctionsUser r;
2266 torture_comment(tctx, "Testing TestPrivateFunctionsUser\n");
2268 r.in.user_handle = user_handle;
2270 status = dcerpc_samr_TestPrivateFunctionsUser(p, tctx, &r);
2271 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsUser");
2276 static bool test_QueryUserInfo_pwdlastset(struct dcerpc_pipe *p,
2277 struct torture_context *tctx,
2278 struct policy_handle *handle,
2283 uint16_t levels[] = { /* 3, */ 5, 21 };
2285 NTTIME pwdlastset3 = 0;
2286 NTTIME pwdlastset5 = 0;
2287 NTTIME pwdlastset21 = 0;
2289 torture_comment(tctx, "Testing QueryUserInfo%s level 5 and 21 call ",
2290 use_info2 ? "2":"");
2292 for (i=0; i<ARRAY_SIZE(levels); i++) {
2294 struct samr_QueryUserInfo r;
2295 struct samr_QueryUserInfo2 r2;
2296 union samr_UserInfo *info;
2299 r2.in.user_handle = handle;
2300 r2.in.level = levels[i];
2301 r2.out.info = &info;
2302 status = dcerpc_samr_QueryUserInfo2(p, tctx, &r2);
2305 r.in.user_handle = handle;
2306 r.in.level = levels[i];
2308 status = dcerpc_samr_QueryUserInfo(p, tctx, &r);
2311 if (!NT_STATUS_IS_OK(status) &&
2312 !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
2313 printf("QueryUserInfo%s level %u failed - %s\n",
2314 use_info2 ? "2":"", levels[i], nt_errstr(status));
2318 switch (levels[i]) {
2320 pwdlastset3 = info->info3.last_password_change;
2323 pwdlastset5 = info->info5.last_password_change;
2326 pwdlastset21 = info->info21.last_password_change;
2332 /* torture_assert_int_equal(tctx, pwdlastset3, pwdlastset5,
2333 "pwdlastset mixup"); */
2334 torture_assert_int_equal(tctx, pwdlastset5, pwdlastset21,
2335 "pwdlastset mixup");
2337 *pwdlastset = pwdlastset21;
2339 torture_comment(tctx, "(pwdlastset: %lld)\n", *pwdlastset);
2344 static bool test_SetPassword_level(struct dcerpc_pipe *p,
2345 struct torture_context *tctx,
2346 struct policy_handle *handle,
2348 uint32_t fields_present,
2349 uint8_t password_expired,
2350 NTSTATUS expected_error,
2353 bool use_queryinfo2,
2356 const char *fields = NULL;
2363 fields = talloc_asprintf(tctx, "(fields_present: 0x%08x)",
2370 torture_comment(tctx, "Testing SetUserInfo%s level %d call "
2371 "(password_expired: %d) %s\n",
2372 use_setinfo2 ? "2":"", level, password_expired,
2373 fields ? fields : "");
2381 if (!test_SetUserPass_level_ex(p, tctx, handle, level,
2394 if (!test_QueryUserInfo_pwdlastset(p, tctx, handle,
2403 static bool test_SetPassword_pwdlastset(struct dcerpc_pipe *p,
2404 struct torture_context *tctx,
2405 uint32_t acct_flags,
2406 struct policy_handle *handle,
2409 int i, s = 0, q = 0;
2412 bool set_levels[] = { false, true };
2413 bool query_levels[] = { false, true };
2417 uint8_t password_expired_nonzero;
2418 uint32_t fields_present;
2427 .password_expired_nonzero = 1,
2428 .fields_present = SAMR_FIELD_EXPIRED_FLAG
2431 .password_expired_nonzero = 1,
2432 .fields_present = SAMR_FIELD_LAST_PWD_CHANGE,
2433 .set_error = NT_STATUS_ACCESS_DENIED
2438 .password_expired_nonzero = 1,
2439 .fields_present = SAMR_FIELD_PASSWORD |
2440 SAMR_FIELD_PASSWORD2 |
2441 SAMR_FIELD_LAST_PWD_CHANGE,
2442 .query_info2 = false,
2443 .set_error = NT_STATUS_ACCESS_DENIED
2449 .password_expired_nonzero = 1,
2450 .fields_present = SAMR_FIELD_EXPIRED_FLAG
2453 .password_expired_nonzero = 1,
2454 .fields_present = SAMR_FIELD_LAST_PWD_CHANGE,
2455 .set_error = NT_STATUS_ACCESS_DENIED
2458 .password_expired_nonzero = 1,
2459 .fields_present = SAMR_FIELD_LAST_PWD_CHANGE |
2460 SAMR_FIELD_PASSWORD |
2461 SAMR_FIELD_PASSWORD2,
2462 .set_error = NT_STATUS_ACCESS_DENIED
2465 .password_expired_nonzero = 1,
2466 .fields_present = SAMR_FIELD_LAST_PWD_CHANGE |
2467 SAMR_FIELD_PASSWORD |
2468 SAMR_FIELD_PASSWORD2 |
2469 SAMR_FIELD_EXPIRED_FLAG,
2470 .set_error = NT_STATUS_ACCESS_DENIED
2473 .password_expired_nonzero = 1,
2474 .fields_present = SAMR_FIELD_PASSWORD |
2475 SAMR_FIELD_PASSWORD2 |
2476 SAMR_FIELD_EXPIRED_FLAG
2479 .password_expired_nonzero = 1,
2480 .fields_present = SAMR_FIELD_PASSWORD |
2481 SAMR_FIELD_PASSWORD2
2487 .password_expired_nonzero = 1
2490 .password_expired_nonzero = 24
2496 .password_expired_nonzero = 1,
2497 .fields_present = SAMR_FIELD_LAST_PWD_CHANGE,
2498 .set_error = NT_STATUS_ACCESS_DENIED
2501 .password_expired_nonzero = 1,
2502 .fields_present = SAMR_FIELD_EXPIRED_FLAG,
2505 .password_expired_nonzero = 1,
2506 .fields_present = SAMR_FIELD_PASSWORD |
2507 SAMR_FIELD_PASSWORD2 |
2508 SAMR_FIELD_EXPIRED_FLAG
2511 .password_expired_nonzero = 1,
2512 .fields_present = SAMR_FIELD_PASSWORD |
2513 SAMR_FIELD_PASSWORD2
2519 .password_expired_nonzero = 1
2522 .password_expired_nonzero = 24
2526 if (torture_setting_bool(tctx, "samba3", false)) {
2528 printf("Samba3 has second granularity, setting delay to: %d\n",
2532 /* set to 1 to enable testing for all possible opcode
2533 (SetUserInfo, SetUserInfo2, QueryUserInfo, QueryUserInfo2)
2536 #define TEST_SET_LEVELS 1
2537 #define TEST_QUERY_LEVELS 1
2539 for (i=0; i<ARRAY_SIZE(pwd_tests); i++) {
2540 #ifdef TEST_SET_LEVELS
2541 for (s=0; s<ARRAY_SIZE(set_levels); s++) {
2543 #ifdef TEST_QUERY_LEVELS
2544 for (q=0; q<ARRAY_SIZE(query_levels); q++) {
2546 NTTIME pwdlastset_old = 0;
2547 NTTIME pwdlastset_new = 0;
2551 torture_comment(tctx, "------------------------------\n"
2552 "Testing pwdLastSet attribute for flags: 0x%08x "
2553 "(s: %d (l: %d), q: %d)\n",
2554 acct_flags, s, pwd_tests[i].level, q);
2556 if (!test_SetPassword_level(p, tctx, handle,
2558 pwd_tests[i].fields_present,
2559 pwd_tests[i].password_expired_nonzero, /* will set pwdlast to 0 */
2560 pwd_tests[i].set_error,
2568 if (!NT_STATUS_IS_OK(pwd_tests[i].set_error)) {
2569 /* skipping on expected failure */
2573 /* pwdlastset must be 0 afterwards, except for a level 23 and 25
2574 * set without the SAMR_FIELD_EXPIRED_FLAG */
2576 switch (pwd_tests[i].level) {
2579 if ((pwdlastset_new != 0) &&
2580 !(pwd_tests[i].fields_present & SAMR_FIELD_EXPIRED_FLAG)) {
2581 torture_comment(tctx, "not considering a non-0 "
2582 "pwdLastSet as a an error as the "
2583 "SAMR_FIELD_EXPIRED_FLAG has not "
2588 if (pwdlastset_new != 0) {
2589 torture_warning(tctx, "pwdLastSet test failed: "
2590 "expected pwdLastSet 0 but got %lld\n",
2601 if (!test_SetPassword_level(p, tctx, handle, pwd_tests[i].level,
2602 pwd_tests[i].fields_present,
2604 /* will normally update (increase) the pwdlast */
2605 pwd_tests[i].set_error,
2614 /* pwdlastset must not be 0 afterwards and must be larger then
2617 if (pwdlastset_old >= pwdlastset_new) {
2618 torture_warning(tctx, "pwdLastSet test failed: "
2619 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
2620 pwdlastset_old, pwdlastset_new);
2623 if (pwdlastset_new == 0) {
2624 torture_warning(tctx, "pwdLastSet test failed: "
2625 "expected non-0 pwdlastset, got: %lld\n",
2629 pwdlastset_old = pwdlastset_new;
2635 if (!test_SetPassword_level(p, tctx, handle, pwd_tests[i].level,
2636 pwd_tests[i].fields_present,
2637 pwd_tests[i].password_expired_nonzero,
2638 pwd_tests[i].set_error,
2646 if (pwdlastset_old == pwdlastset_new) {
2647 torture_warning(tctx, "pwdLastSet test failed: "
2648 "expected last pwdlastset (%lld) != new pwdlastset (%lld)\n",
2649 pwdlastset_old, pwdlastset_new);
2653 /* pwdlastset must be 0 afterwards, except for a level 23 and 25
2654 * set without the SAMR_FIELD_EXPIRED_FLAG */
2656 switch (pwd_tests[i].level) {
2659 if ((pwdlastset_new != 0) &&
2660 !(pwd_tests[i].fields_present & SAMR_FIELD_EXPIRED_FLAG)) {
2664 if (pwdlastset_new != 0) {
2665 torture_warning(tctx, "pwdLastSet test failed: "
2666 "expected pwdLastSet 0, got %lld\n",
2672 #ifdef TEST_QUERY_LEVELS
2675 #ifdef TEST_SET_LEVELS
2680 #undef TEST_SET_LEVELS
2681 #undef TEST_QUERY_LEVELS
2686 static bool test_user_ops(struct dcerpc_pipe *p,
2687 struct torture_context *tctx,
2688 struct policy_handle *user_handle,
2689 struct policy_handle *domain_handle,
2690 uint32_t base_acct_flags,
2691 const char *base_acct_name, enum torture_samr_choice which_ops)
2693 char *password = NULL;
2694 struct samr_QueryUserInfo q;
2695 union samr_UserInfo *info;
2701 const uint32_t password_fields[] = {
2702 SAMR_FIELD_PASSWORD,
2703 SAMR_FIELD_PASSWORD2,
2704 SAMR_FIELD_PASSWORD | SAMR_FIELD_PASSWORD2,
2708 status = test_LookupName(p, tctx, domain_handle, base_acct_name, &rid);
2709 if (!NT_STATUS_IS_OK(status)) {
2713 switch (which_ops) {
2714 case TORTURE_SAMR_USER_ATTRIBUTES:
2715 if (!test_QuerySecurity(p, tctx, user_handle)) {
2719 if (!test_QueryUserInfo(p, tctx, user_handle)) {
2723 if (!test_QueryUserInfo2(p, tctx, user_handle)) {
2727 if (!test_SetUserInfo(p, tctx, user_handle, base_acct_flags,
2732 if (!test_GetUserPwInfo(p, tctx, user_handle)) {
2736 if (!test_TestPrivateFunctionsUser(p, tctx, user_handle)) {
2740 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
2744 case TORTURE_SAMR_PASSWORDS:
2745 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
2746 char simple_pass[9];
2747 char *v = generate_random_str(tctx, 1);
2749 ZERO_STRUCT(simple_pass);
2750 memset(simple_pass, *v, sizeof(simple_pass) - 1);
2752 printf("Testing machine account password policy rules\n");
2754 /* Workstation trust accounts don't seem to need to honour password quality policy */
2755 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
2759 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
2763 /* reset again, to allow another 'user' password change */
2764 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
2768 /* Try a 'short' password */
2769 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
2773 /* Try a compleatly random password */
2774 if (!test_ChangePasswordRandomBytes(p, tctx, base_acct_name, user_handle, &password)) {
2779 for (i = 0; password_fields[i]; i++) {
2780 if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
2784 /* check it was set right */
2785 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
2790 for (i = 0; password_fields[i]; i++) {
2791 if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
2795 /* check it was set right */
2796 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
2801 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
2805 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
2809 q.in.user_handle = user_handle;
2813 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
2814 if (!NT_STATUS_IS_OK(status)) {
2815 printf("QueryUserInfo level %u failed - %s\n",
2816 q.in.level, nt_errstr(status));
2819 uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
2820 if ((info->info5.acct_flags) != expected_flags) {
2821 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2822 info->info5.acct_flags,
2826 if (info->info5.rid != rid) {
2827 printf("QuerUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
2828 info->info5.rid, rid);
2835 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
2837 /* test last password change timestamp behaviour */
2838 if (!test_SetPassword_pwdlastset(p, tctx, base_acct_flags,
2839 user_handle, &password)) {
2844 torture_comment(tctx, "pwdLastSet test succeeded\n");
2846 torture_warning(tctx, "pwdLastSet test failed\n");
2851 case TORTURE_SAMR_OTHER:
2852 /* We just need the account to exist */
2858 static bool test_alias_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
2859 struct policy_handle *alias_handle,
2860 const struct dom_sid *domain_sid)
2864 if (!test_QuerySecurity(p, tctx, alias_handle)) {
2868 if (!test_QueryAliasInfo(p, tctx, alias_handle)) {
2872 if (!test_SetAliasInfo(p, tctx, alias_handle)) {
2876 if (!test_AddMemberToAlias(p, tctx, alias_handle, domain_sid)) {
2880 if (torture_setting_bool(tctx, "samba4", false)) {
2881 printf("skipping MultipleMembers Alias tests against Samba4\n");
2885 if (!test_AddMultipleMembersToAlias(p, tctx, alias_handle)) {
2893 static bool test_DeleteUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2894 struct policy_handle *user_handle)
2896 struct samr_DeleteUser d;
2898 torture_comment(tctx, "Testing DeleteUser\n");
2900 d.in.user_handle = user_handle;
2901 d.out.user_handle = user_handle;
2903 status = dcerpc_samr_DeleteUser(p, tctx, &d);
2904 torture_assert_ntstatus_ok(tctx, status, "DeleteUser");
2909 bool test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2910 struct policy_handle *handle, const char *name)
2913 struct samr_DeleteUser d;
2914 struct policy_handle user_handle;
2917 status = test_LookupName(p, mem_ctx, handle, name, &rid);
2918 if (!NT_STATUS_IS_OK(status)) {
2922 status = test_OpenUser_byname(p, mem_ctx, handle, name, &user_handle);
2923 if (!NT_STATUS_IS_OK(status)) {
2927 d.in.user_handle = &user_handle;
2928 d.out.user_handle = &user_handle;
2929 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
2930 if (!NT_STATUS_IS_OK(status)) {
2937 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
2942 static bool test_DeleteGroup_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2943 struct policy_handle *handle, const char *name)
2946 struct samr_OpenGroup r;
2947 struct samr_DeleteDomainGroup d;
2948 struct policy_handle group_handle;
2951 status = test_LookupName(p, mem_ctx, handle, name, &rid);
2952 if (!NT_STATUS_IS_OK(status)) {
2956 r.in.domain_handle = handle;
2957 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2959 r.out.group_handle = &group_handle;
2960 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
2961 if (!NT_STATUS_IS_OK(status)) {
2965 d.in.group_handle = &group_handle;
2966 d.out.group_handle = &group_handle;
2967 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
2968 if (!NT_STATUS_IS_OK(status)) {
2975 printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
2980 static bool test_DeleteAlias_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2981 struct policy_handle *domain_handle, const char *name)
2984 struct samr_OpenAlias r;
2985 struct samr_DeleteDomAlias d;
2986 struct policy_handle alias_handle;
2989 printf("testing DeleteAlias_byname\n");
2991 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
2992 if (!NT_STATUS_IS_OK(status)) {
2996 r.in.domain_handle = domain_handle;
2997 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2999 r.out.alias_handle = &alias_handle;
3000 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
3001 if (!NT_STATUS_IS_OK(status)) {
3005 d.in.alias_handle = &alias_handle;
3006 d.out.alias_handle = &alias_handle;
3007 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
3008 if (!NT_STATUS_IS_OK(status)) {
3015 printf("DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
3019 static bool test_DeleteAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3020 struct policy_handle *alias_handle)
3022 struct samr_DeleteDomAlias d;
3025 printf("Testing DeleteAlias\n");
3027 d.in.alias_handle = alias_handle;
3028 d.out.alias_handle = alias_handle;
3030 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
3031 if (!NT_STATUS_IS_OK(status)) {
3032 printf("DeleteAlias failed - %s\n", nt_errstr(status));
3039 static bool test_CreateAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
3040 struct policy_handle *domain_handle,
3041 struct policy_handle *alias_handle,
3042 const struct dom_sid *domain_sid)
3045 struct samr_CreateDomAlias r;
3046 struct lsa_String name;
3050 init_lsa_String(&name, TEST_ALIASNAME);
3051 r.in.domain_handle = domain_handle;
3052 r.in.alias_name = &name;
3053 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3054 r.out.alias_handle = alias_handle;
3057 printf("Testing CreateAlias (%s)\n", r.in.alias_name->string);
3059 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
3061 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
3062 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
3063 printf("Server correctly refused create of '%s'\n", r.in.alias_name->string);
3066 printf("Server should have refused create of '%s', got %s instead\n", r.in.alias_name->string,
3072 if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
3073 if (!test_DeleteAlias_byname(p, tctx, domain_handle, r.in.alias_name->string)) {
3076 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
3079 if (!NT_STATUS_IS_OK(status)) {
3080 printf("CreateAlias failed - %s\n", nt_errstr(status));
3084 if (!test_alias_ops(p, tctx, alias_handle, domain_sid)) {
3091 static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3092 const char *acct_name,
3093 struct policy_handle *domain_handle, char **password)
3101 if (!test_ChangePasswordUser(p, mem_ctx, acct_name, domain_handle, password)) {
3105 if (!test_ChangePasswordUser2(p, mem_ctx, acct_name, password, 0, true)) {
3109 if (!test_OemChangePasswordUser2(p, mem_ctx, acct_name, domain_handle, password)) {
3113 /* test what happens when setting the old password again */
3114 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, *password, 0, true)) {
3119 char simple_pass[9];
3120 char *v = generate_random_str(mem_ctx, 1);
3122 ZERO_STRUCT(simple_pass);
3123 memset(simple_pass, *v, sizeof(simple_pass) - 1);
3125 /* test what happens when picking a simple password */
3126 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, simple_pass, 0, true)) {
3131 /* set samr_SetDomainInfo level 1 with min_length 5 */
3133 struct samr_QueryDomainInfo r;
3134 union samr_DomainInfo *info = NULL;
3135 struct samr_SetDomainInfo s;
3136 uint16_t len_old, len;
3137 uint32_t pwd_prop_old;
3138 int64_t min_pwd_age_old;
3143 r.in.domain_handle = domain_handle;
3147 printf("testing samr_QueryDomainInfo level 1\n");
3148 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
3149 if (!NT_STATUS_IS_OK(status)) {
3153 s.in.domain_handle = domain_handle;
3157 /* remember the old min length, so we can reset it */
3158 len_old = s.in.info->info1.min_password_length;
3159 s.in.info->info1.min_password_length = len;
3160 pwd_prop_old = s.in.info->info1.password_properties;
3161 /* turn off password complexity checks for this test */
3162 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
3164 min_pwd_age_old = s.in.info->info1.min_password_age;
3165 s.in.info->info1.min_password_age = 0;
3167 printf("testing samr_SetDomainInfo level 1\n");
3168 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
3169 if (!NT_STATUS_IS_OK(status)) {
3173 printf("calling test_ChangePasswordUser3 with too short password\n");
3175 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, len - 1, password, NULL, 0, true)) {
3179 s.in.info->info1.min_password_length = len_old;
3180 s.in.info->info1.password_properties = pwd_prop_old;
3181 s.in.info->info1.min_password_age = min_pwd_age_old;
3183 printf("testing samr_SetDomainInfo level 1\n");
3184 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
3185 if (!NT_STATUS_IS_OK(status)) {
3193 struct samr_OpenUser r;
3194 struct samr_QueryUserInfo q;
3195 union samr_UserInfo *info;
3196 struct samr_LookupNames n;
3197 struct policy_handle user_handle;
3198 struct samr_Ids rids, types;
3200 n.in.domain_handle = domain_handle;
3202 n.in.names = talloc_array(mem_ctx, struct lsa_String, 1);
3203 n.in.names[0].string = acct_name;
3205 n.out.types = &types;
3207 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
3208 if (!NT_STATUS_IS_OK(status)) {
3209 printf("LookupNames failed - %s\n", nt_errstr(status));
3213 r.in.domain_handle = domain_handle;
3214 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3215 r.in.rid = n.out.rids->ids[0];
3216 r.out.user_handle = &user_handle;
3218 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3219 if (!NT_STATUS_IS_OK(status)) {
3220 printf("OpenUser(%u) failed - %s\n", n.out.rids->ids[0], nt_errstr(status));
3224 q.in.user_handle = &user_handle;
3228 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
3229 if (!NT_STATUS_IS_OK(status)) {
3230 printf("QueryUserInfo failed - %s\n", nt_errstr(status));
3234 printf("calling test_ChangePasswordUser3 with too early password change\n");
3236 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL,
3237 info->info5.last_password_change, true)) {
3242 /* we change passwords twice - this has the effect of verifying
3243 they were changed correctly for the final call */
3244 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, true)) {
3248 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, true)) {
3255 static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
3256 struct policy_handle *domain_handle,
3257 struct policy_handle *user_handle_out,
3258 struct dom_sid *domain_sid,
3259 enum torture_samr_choice which_ops)
3262 TALLOC_CTX *user_ctx;
3265 struct samr_CreateUser r;
3266 struct samr_QueryUserInfo q;
3267 union samr_UserInfo *info;
3268 struct samr_DeleteUser d;
3271 /* This call creates a 'normal' account - check that it really does */
3272 const uint32_t acct_flags = ACB_NORMAL;
3273 struct lsa_String name;
3276 struct policy_handle user_handle;
3277 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
3278 init_lsa_String(&name, TEST_ACCOUNT_NAME);
3280 r.in.domain_handle = domain_handle;
3281 r.in.account_name = &name;
3282 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3283 r.out.user_handle = &user_handle;
3286 printf("Testing CreateUser(%s)\n", r.in.account_name->string);
3288 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
3290 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
3291 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
3292 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
3295 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
3301 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
3302 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
3303 talloc_free(user_ctx);
3306 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
3308 if (!NT_STATUS_IS_OK(status)) {
3309 talloc_free(user_ctx);
3310 printf("CreateUser failed - %s\n", nt_errstr(status));
3313 q.in.user_handle = &user_handle;
3317 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
3318 if (!NT_STATUS_IS_OK(status)) {
3319 printf("QueryUserInfo level %u failed - %s\n",
3320 q.in.level, nt_errstr(status));
3323 if ((info->info16.acct_flags & acct_flags) != acct_flags) {
3324 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
3325 info->info16.acct_flags,
3331 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
3332 acct_flags, name.string, which_ops)) {
3336 if (user_handle_out) {
3337 *user_handle_out = user_handle;
3339 printf("Testing DeleteUser (createuser test)\n");
3341 d.in.user_handle = &user_handle;
3342 d.out.user_handle = &user_handle;
3344 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
3345 if (!NT_STATUS_IS_OK(status)) {
3346 printf("DeleteUser failed - %s\n", nt_errstr(status));
3353 talloc_free(user_ctx);
3359 static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
3360 struct policy_handle *domain_handle,
3361 struct dom_sid *domain_sid,
3362 enum torture_samr_choice which_ops)
3365 struct samr_CreateUser2 r;
3366 struct samr_QueryUserInfo q;
3367 union samr_UserInfo *info;
3368 struct samr_DeleteUser d;
3369 struct policy_handle user_handle;
3371 struct lsa_String name;
3376 uint32_t acct_flags;
3377 const char *account_name;
3379 } account_types[] = {
3380 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
3381 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
3382 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
3383 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
3384 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
3385 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
3386 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
3387 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
3388 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
3389 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
3390 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
3391 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
3392 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
3393 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
3394 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
3397 for (i = 0; account_types[i].account_name; i++) {
3398 TALLOC_CTX *user_ctx;
3399 uint32_t acct_flags = account_types[i].acct_flags;
3400 uint32_t access_granted;
3401 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
3402 init_lsa_String(&name, account_types[i].account_name);
3404 r.in.domain_handle = domain_handle;
3405 r.in.account_name = &name;
3406 r.in.acct_flags = acct_flags;
3407 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3408 r.out.user_handle = &user_handle;
3409 r.out.access_granted = &access_granted;
3412 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
3414 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
3416 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
3417 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
3418 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
3421 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
3428 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
3429 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
3430 talloc_free(user_ctx);
3434 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
3437 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
3438 printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
3439 nt_errstr(status), nt_errstr(account_types[i].nt_status));
3443 if (NT_STATUS_IS_OK(status)) {
3444 q.in.user_handle = &user_handle;
3448 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
3449 if (!NT_STATUS_IS_OK(status)) {
3450 printf("QueryUserInfo level %u failed - %s\n",
3451 q.in.level, nt_errstr(status));
3454 uint32_t expected_flags = (acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
3455 if (acct_flags == ACB_NORMAL) {
3456 expected_flags |= ACB_PW_EXPIRED;
3458 if ((info->info5.acct_flags) != expected_flags) {
3459 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
3460 info->info5.acct_flags,
3464 switch (acct_flags) {
3466 if (info->info5.primary_gid != DOMAIN_RID_DCS) {
3467 printf("QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n",
3468 DOMAIN_RID_DCS, info->info5.primary_gid);
3473 if (info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
3474 printf("QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
3475 DOMAIN_RID_DOMAIN_MEMBERS, info->info5.primary_gid);
3480 if (info->info5.primary_gid != DOMAIN_RID_USERS) {
3481 printf("QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n",
3482 DOMAIN_RID_USERS, info->info5.primary_gid);
3489 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
3490 acct_flags, name.string, which_ops)) {
3494 printf("Testing DeleteUser (createuser2 test)\n");
3496 d.in.user_handle = &user_handle;
3497 d.out.user_handle = &user_handle;
3499 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
3500 if (!NT_STATUS_IS_OK(status)) {
3501 printf("DeleteUser failed - %s\n", nt_errstr(status));
3505 talloc_free(user_ctx);
3511 static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3512 struct policy_handle *handle)
3515 struct samr_QueryAliasInfo r;
3516 union samr_AliasInfo *info;
3517 uint16_t levels[] = {1, 2, 3};
3521 for (i=0;i<ARRAY_SIZE(levels);i++) {
3522 printf("Testing QueryAliasInfo level %u\n", levels[i]);
3524 r.in.alias_handle = handle;
3525 r.in.level = levels[i];
3528 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
3529 if (!NT_STATUS_IS_OK(status)) {
3530 printf("QueryAliasInfo level %u failed - %s\n",
3531 levels[i], nt_errstr(status));
3539 static bool test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3540 struct policy_handle *handle)
3543 struct samr_QueryGroupInfo r;
3544 union samr_GroupInfo *info;
3545 uint16_t levels[] = {1, 2, 3, 4, 5};
3549 for (i=0;i<ARRAY_SIZE(levels);i++) {
3550 printf("Testing QueryGroupInfo level %u\n", levels[i]);
3552 r.in.group_handle = handle;
3553 r.in.level = levels[i];
3556 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
3557 if (!NT_STATUS_IS_OK(status)) {
3558 printf("QueryGroupInfo level %u failed - %s\n",
3559 levels[i], nt_errstr(status));
3567 static bool test_QueryGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3568 struct policy_handle *handle)
3571 struct samr_QueryGroupMember r;
3572 struct samr_RidTypeArray *rids = NULL;
3575 printf("Testing QueryGroupMember\n");
3577 r.in.group_handle = handle;
3580 status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &r);
3581 if (!NT_STATUS_IS_OK(status)) {
3582 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
3590 static bool test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3591 struct policy_handle *handle)
3594 struct samr_QueryGroupInfo r;
3595 union samr_GroupInfo *info;
3596 struct samr_SetGroupInfo s;
3597 uint16_t levels[] = {1, 2, 3, 4};
3598 uint16_t set_ok[] = {0, 1, 1, 1};
3602 for (i=0;i<ARRAY_SIZE(levels);i++) {
3603 printf("Testing QueryGroupInfo level %u\n", levels[i]);
3605 r.in.group_handle = handle;
3606 r.in.level = levels[i];
3609 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
3610 if (!NT_STATUS_IS_OK(status)) {
3611 printf("QueryGroupInfo level %u failed - %s\n",
3612 levels[i], nt_errstr(status));
3616 printf("Testing SetGroupInfo level %u\n", levels[i]);
3618 s.in.group_handle = handle;
3619 s.in.level = levels[i];
3620 s.in.info = *r.out.info;
3623 /* disabled this, as it changes the name only from the point of view of samr,
3624 but leaves the name from the point of view of w2k3 internals (and ldap). This means
3625 the name is still reserved, so creating the old name fails, but deleting by the old name
3627 if (s.in.level == 2) {
3628 init_lsa_String(&s.in.info->string, "NewName");
3632 if (s.in.level == 4) {
3633 init_lsa_String(&s.in.info->description, "test description");
3636 status = dcerpc_samr_SetGroupInfo(p, mem_ctx, &s);
3638 if (!NT_STATUS_IS_OK(status)) {
3639 printf("SetGroupInfo level %u failed - %s\n",
3640 r.in.level, nt_errstr(status));
3645 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
3646 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
3647 r.in.level, nt_errstr(status));
3657 static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3658 struct policy_handle *handle)
3661 struct samr_QueryUserInfo 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 QueryUserInfo level %u\n", levels[i]);
3671 r.in.user_handle = handle;
3672 r.in.level = levels[i];
3675 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
3676 if (!NT_STATUS_IS_OK(status)) {
3677 printf("QueryUserInfo level %u failed - %s\n",
3678 levels[i], nt_errstr(status));
3686 static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3687 struct policy_handle *handle)
3690 struct samr_QueryUserInfo2 r;
3691 union samr_UserInfo *info;
3692 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
3693 11, 12, 13, 14, 16, 17, 20, 21};
3697 for (i=0;i<ARRAY_SIZE(levels);i++) {
3698 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
3700 r.in.user_handle = handle;
3701 r.in.level = levels[i];
3704 status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r);
3705 if (!NT_STATUS_IS_OK(status)) {
3706 printf("QueryUserInfo2 level %u failed - %s\n",
3707 levels[i], nt_errstr(status));
3715 static bool test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3716 struct policy_handle *handle, uint32_t rid)
3719 struct samr_OpenUser r;
3720 struct policy_handle user_handle;
3723 printf("Testing OpenUser(%u)\n", rid);
3725 r.in.domain_handle = handle;
3726 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3728 r.out.user_handle = &user_handle;
3730 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3731 if (!NT_STATUS_IS_OK(status)) {
3732 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
3736 if (!test_QuerySecurity(p, mem_ctx, &user_handle)) {
3740 if (!test_QueryUserInfo(p, mem_ctx, &user_handle)) {
3744 if (!test_QueryUserInfo2(p, mem_ctx, &user_handle)) {
3748 if (!test_GetUserPwInfo(p, mem_ctx, &user_handle)) {
3752 if (!test_GetGroupsForUser(p,mem_ctx, &user_handle)) {
3756 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
3763 static bool test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3764 struct policy_handle *handle, uint32_t rid)
3767 struct samr_OpenGroup r;
3768 struct policy_handle group_handle;
3771 printf("Testing OpenGroup(%u)\n", rid);
3773 r.in.domain_handle = handle;
3774 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3776 r.out.group_handle = &group_handle;
3778 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
3779 if (!NT_STATUS_IS_OK(status)) {
3780 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
3784 if (!test_QuerySecurity(p, mem_ctx, &group_handle)) {
3788 if (!test_QueryGroupInfo(p, mem_ctx, &group_handle)) {
3792 if (!test_QueryGroupMember(p, mem_ctx, &group_handle)) {
3796 if (!test_samr_handle_Close(p, mem_ctx, &group_handle)) {
3803 static bool test_OpenAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
3804 struct policy_handle *handle, uint32_t rid)
3807 struct samr_OpenAlias r;
3808 struct policy_handle alias_handle;
3811 torture_comment(tctx, "Testing OpenAlias(%u)\n", rid);
3813 r.in.domain_handle = handle;
3814 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3816 r.out.alias_handle = &alias_handle;
3818 status = dcerpc_samr_OpenAlias(p, tctx, &r);
3819 if (!NT_STATUS_IS_OK(status)) {
3820 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
3824 if (!test_QuerySecurity(p, tctx, &alias_handle)) {
3828 if (!test_QueryAliasInfo(p, tctx, &alias_handle)) {
3832 if (!test_GetMembersInAlias(p, tctx, &alias_handle)) {
3836 if (!test_samr_handle_Close(p, tctx, &alias_handle)) {
3843 static bool check_mask(struct dcerpc_pipe *p, struct torture_context *tctx,
3844 struct policy_handle *handle, uint32_t rid,
3845 uint32_t acct_flag_mask)
3848 struct samr_OpenUser r;
3849 struct samr_QueryUserInfo q;
3850 union samr_UserInfo *info;
3851 struct policy_handle user_handle;
3854 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
3856 r.in.domain_handle = handle;
3857 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3859 r.out.user_handle = &user_handle;
3861 status = dcerpc_samr_OpenUser(p, tctx, &r);
3862 if (!NT_STATUS_IS_OK(status)) {
3863 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
3867 q.in.user_handle = &user_handle;
3871 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
3872 if (!NT_STATUS_IS_OK(status)) {
3873 printf("QueryUserInfo level 16 failed - %s\n",
3877 if ((acct_flag_mask & info->info16.acct_flags) == 0) {
3878 printf("Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
3879 acct_flag_mask, info->info16.acct_flags, rid);
3884 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
3891 static bool test_EnumDomainUsers(struct dcerpc_pipe *p, struct torture_context *tctx,
3892 struct policy_handle *handle)
3894 NTSTATUS status = STATUS_MORE_ENTRIES;
3895 struct samr_EnumDomainUsers r;
3896 uint32_t mask, resume_handle=0;
3899 struct samr_LookupNames n;
3900 struct samr_LookupRids lr ;
3901 struct lsa_Strings names;
3902 struct samr_Ids rids, types;
3903 struct samr_SamArray *sam = NULL;
3904 uint32_t num_entries = 0;
3906 uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
3907 ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
3908 ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
3911 printf("Testing EnumDomainUsers\n");
3913 for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
3914 r.in.domain_handle = handle;
3915 r.in.resume_handle = &resume_handle;
3916 r.in.acct_flags = mask = masks[mask_idx];
3917 r.in.max_size = (uint32_t)-1;
3918 r.out.resume_handle = &resume_handle;
3919 r.out.num_entries = &num_entries;
3922 status = dcerpc_samr_EnumDomainUsers(p, tctx, &r);
3923 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
3924 !NT_STATUS_IS_OK(status)) {
3925 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
3929 torture_assert(tctx, sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
3931 if (sam->count == 0) {
3935 for (i=0;i<sam->count;i++) {
3937 if (!check_mask(p, tctx, handle, sam->entries[i].idx, mask)) {
3940 } else if (!test_OpenUser(p, tctx, handle, sam->entries[i].idx)) {
3946 printf("Testing LookupNames\n");
3947 n.in.domain_handle = handle;
3948 n.in.num_names = sam->count;
3949 n.in.names = talloc_array(tctx, struct lsa_String, sam->count);
3951 n.out.types = &types;
3952 for (i=0;i<sam->count;i++) {
3953 n.in.names[i].string = sam->entries[i].name.string;
3955 status = dcerpc_samr_LookupNames(p, tctx, &n);
3956 if (!NT_STATUS_IS_OK(status)) {
3957 printf("LookupNames failed - %s\n", nt_errstr(status));
3962 printf("Testing LookupRids\n");
3963 lr.in.domain_handle = handle;
3964 lr.in.num_rids = sam->count;
3965 lr.in.rids = talloc_array(tctx, uint32_t, sam->count);
3966 lr.out.names = &names;
3967 lr.out.types = &types;
3968 for (i=0;i<sam->count;i++) {
3969 lr.in.rids[i] = sam->entries[i].idx;
3971 status = dcerpc_samr_LookupRids(p, tctx, &lr);
3972 torture_assert_ntstatus_ok(tctx, status, "LookupRids");
3978 try blasting the server with a bunch of sync requests
3980 static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, struct torture_context *tctx,
3981 struct policy_handle *handle)
3984 struct samr_EnumDomainUsers r;
3985 uint32_t resume_handle=0;
3987 #define ASYNC_COUNT 100
3988 struct rpc_request *req[ASYNC_COUNT];
3990 if (!torture_setting_bool(tctx, "dangerous", false)) {
3991 torture_skip(tctx, "samr async test disabled - enable dangerous tests to use\n");
3994 torture_comment(tctx, "Testing EnumDomainUsers_async\n");
3996 r.in.domain_handle = handle;
3997 r.in.resume_handle = &resume_handle;
3998 r.in.acct_flags = 0;
3999 r.in.max_size = (uint32_t)-1;
4000 r.out.resume_handle = &resume_handle;
4002 for (i=0;i<ASYNC_COUNT;i++) {
4003 req[i] = dcerpc_samr_EnumDomainUsers_send(p, tctx, &r);
4006 for (i=0;i<ASYNC_COUNT;i++) {
4007 status = dcerpc_ndr_request_recv(req[i]);
4008 if (!NT_STATUS_IS_OK(status)) {
4009 printf("EnumDomainUsers[%d] failed - %s\n",
4010 i, nt_errstr(status));
4015 torture_comment(tctx, "%d async requests OK\n", i);
4020 static bool test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4021 struct policy_handle *handle)
4024 struct samr_EnumDomainGroups r;
4025 uint32_t resume_handle=0;
4026 struct samr_SamArray *sam = NULL;
4027 uint32_t num_entries = 0;
4031 printf("Testing EnumDomainGroups\n");
4033 r.in.domain_handle = handle;
4034 r.in.resume_handle = &resume_handle;
4035 r.in.max_size = (uint32_t)-1;
4036 r.out.resume_handle = &resume_handle;
4037 r.out.num_entries = &num_entries;
4040 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
4041 if (!NT_STATUS_IS_OK(status)) {
4042 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
4050 for (i=0;i<sam->count;i++) {
4051 if (!test_OpenGroup(p, mem_ctx, handle, sam->entries[i].idx)) {
4059 static bool test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4060 struct policy_handle *handle)
4063 struct samr_EnumDomainAliases r;
4064 uint32_t resume_handle=0;
4065 struct samr_SamArray *sam = NULL;
4066 uint32_t num_entries = 0;
4070 printf("Testing EnumDomainAliases\n");
4072 r.in.domain_handle = handle;
4073 r.in.resume_handle = &resume_handle;
4074 r.in.max_size = (uint32_t)-1;
4076 r.out.num_entries = &num_entries;
4077 r.out.resume_handle = &resume_handle;
4079 status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
4080 if (!NT_STATUS_IS_OK(status)) {
4081 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
4089 for (i=0;i<sam->count;i++) {
4090 if (!test_OpenAlias(p, mem_ctx, handle, sam->entries[i].idx)) {
4098 static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4099 struct policy_handle *handle)
4102 struct samr_GetDisplayEnumerationIndex r;
4104 uint16_t levels[] = {1, 2, 3, 4, 5};
4105 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
4106 struct lsa_String name;
4110 for (i=0;i<ARRAY_SIZE(levels);i++) {
4111 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
4113 init_lsa_String(&name, TEST_ACCOUNT_NAME);
4115 r.in.domain_handle = handle;
4116 r.in.level = levels[i];
4120 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
4123 !NT_STATUS_IS_OK(status) &&
4124 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
4125 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
4126 levels[i], nt_errstr(status));
4130 init_lsa_String(&name, "zzzzzzzz");
4132 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
4134 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
4135 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
4136 levels[i], nt_errstr(status));
4144 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4145 struct policy_handle *handle)
4148 struct samr_GetDisplayEnumerationIndex2 r;
4150 uint16_t levels[] = {1, 2, 3, 4, 5};
4151 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
4152 struct lsa_String name;
4156 for (i=0;i<ARRAY_SIZE(levels);i++) {
4157 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
4159 init_lsa_String(&name, TEST_ACCOUNT_NAME);
4161 r.in.domain_handle = handle;
4162 r.in.level = levels[i];
4166 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
4168 !NT_STATUS_IS_OK(status) &&
4169 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
4170 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
4171 levels[i], nt_errstr(status));
4175 init_lsa_String(&name, "zzzzzzzz");
4177 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
4178 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
4179 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
4180 levels[i], nt_errstr(status));
4188 #define STRING_EQUAL_QUERY(s1, s2, user) \
4189 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
4190 /* odd, but valid */ \
4191 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
4192 printf("%s mismatch for %s: %s != %s (%s)\n", \
4193 #s1, user.string, s1.string, s2.string, __location__); \
4196 #define INT_EQUAL_QUERY(s1, s2, user) \
4198 printf("%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
4199 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
4203 static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4204 struct samr_QueryDisplayInfo *querydisplayinfo,
4205 bool *seen_testuser)
4207 struct samr_OpenUser r;
4208 struct samr_QueryUserInfo q;
4209 union samr_UserInfo *info;
4210 struct policy_handle user_handle;
4213 r.in.domain_handle = querydisplayinfo->in.domain_handle;
4214 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4215 for (i = 0; ; i++) {
4216 switch (querydisplayinfo->in.level) {
4218 if (i >= querydisplayinfo->out.info->info1.count) {
4221 r.in.rid = querydisplayinfo->out.info->info1.entries[i].rid;
4224 if (i >= querydisplayinfo->out.info->info2.count) {
4227 r.in.rid = querydisplayinfo->out.info->info2.entries[i].rid;
4233 /* Not interested in validating just the account name */
4237 r.out.user_handle = &user_handle;
4239 switch (querydisplayinfo->in.level) {
4242 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
4243 if (!NT_STATUS_IS_OK(status)) {
4244 printf("OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(status));
4249 q.in.user_handle = &user_handle;
4252 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
4253 if (!NT_STATUS_IS_OK(status)) {
4254 printf("QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(status));
4258 switch (querydisplayinfo->in.level) {
4260 if (seen_testuser && strcmp(info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
4261 *seen_testuser = true;
4263 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].full_name,
4264 info->info21.full_name, info->info21.account_name);
4265 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].account_name,
4266 info->info21.account_name, info->info21.account_name);
4267 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].description,
4268 info->info21.description, info->info21.account_name);
4269 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].rid,
4270 info->info21.rid, info->info21.account_name);
4271 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].acct_flags,
4272 info->info21.acct_flags, info->info21.account_name);
4276 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].account_name,
4277 info->info21.account_name, info->info21.account_name);
4278 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].description,
4279 info->info21.description, info->info21.account_name);
4280 INT_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].rid,
4281 info->info21.rid, info->info21.account_name);
4282 INT_EQUAL_QUERY((querydisplayinfo->out.info->info2.entries[i].acct_flags & ~ACB_NORMAL),
4283 info->info21.acct_flags, info->info21.account_name);
4285 if (!(querydisplayinfo->out.info->info2.entries[i].acct_flags & ACB_NORMAL)) {
4286 printf("Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
4287 info->info21.account_name.string);
4290 if (!(info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
4291 printf("Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
4292 info->info21.account_name.string,
4293 querydisplayinfo->out.info->info2.entries[i].acct_flags,
4294 info->info21.acct_flags);
4301 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
4308 static bool test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4309 struct policy_handle *handle)
4312 struct samr_QueryDisplayInfo r;
4313 struct samr_QueryDomainInfo dom_info;
4314 union samr_DomainInfo *info = NULL;
4316 uint16_t levels[] = {1, 2, 3, 4, 5};
4318 bool seen_testuser = false;
4319 uint32_t total_size;
4320 uint32_t returned_size;
4321 union samr_DispInfo disp_info;
4324 for (i=0;i<ARRAY_SIZE(levels);i++) {
4325 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
4328 status = STATUS_MORE_ENTRIES;
4329 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
4330 r.in.domain_handle = handle;
4331 r.in.level = levels[i];
4332 r.in.max_entries = 2;
4333 r.in.buf_size = (uint32_t)-1;
4334 r.out.total_size = &total_size;
4335 r.out.returned_size = &returned_size;
4336 r.out.info = &disp_info;
4338 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
4339 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(status)) {
4340 printf("QueryDisplayInfo level %u failed - %s\n",
4341 levels[i], nt_errstr(status));
4344 switch (r.in.level) {
4346 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, &seen_testuser)) {
4349 r.in.start_idx += r.out.info->info1.count;
4352 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, NULL)) {
4355 r.in.start_idx += r.out.info->info2.count;
4358 r.in.start_idx += r.out.info->info3.count;
4361 r.in.start_idx += r.out.info->info4.count;
4364 r.in.start_idx += r.out.info->info5.count;
4368 dom_info.in.domain_handle = handle;
4369 dom_info.in.level = 2;
4370 dom_info.out.info = &info;
4372 /* Check number of users returned is correct */
4373 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &dom_info);
4374 if (!NT_STATUS_IS_OK(status)) {
4375 printf("QueryDomainInfo level %u failed - %s\n",
4376 r.in.level, nt_errstr(status));
4380 switch (r.in.level) {
4383 if (info->general.num_users < r.in.start_idx) {
4384 printf("QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
4385 r.in.start_idx, info->general.num_groups,
4386 info->general.domain_name.string);
4389 if (!seen_testuser) {
4390 struct policy_handle user_handle;
4391 if (NT_STATUS_IS_OK(test_OpenUser_byname(p, mem_ctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
4392 printf("Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
4393 info->general.domain_name.string);
4395 test_samr_handle_Close(p, mem_ctx, &user_handle);
4401 if (info->general.num_groups != r.in.start_idx) {
4402 printf("QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
4403 r.in.start_idx, info->general.num_groups,
4404 info->general.domain_name.string);
4416 static bool test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4417 struct policy_handle *handle)
4420 struct samr_QueryDisplayInfo2 r;
4422 uint16_t levels[] = {1, 2, 3, 4, 5};
4424 uint32_t total_size;
4425 uint32_t returned_size;
4426 union samr_DispInfo info;
4428 for (i=0;i<ARRAY_SIZE(levels);i++) {
4429 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
4431 r.in.domain_handle = handle;
4432 r.in.level = levels[i];
4434 r.in.max_entries = 1000;
4435 r.in.buf_size = (uint32_t)-1;
4436 r.out.total_size = &total_size;
4437 r.out.returned_size = &returned_size;
4440 status = dcerpc_samr_QueryDisplayInfo2(p, mem_ctx, &r);
4441 if (!NT_STATUS_IS_OK(status)) {
4442 printf("QueryDisplayInfo2 level %u failed - %s\n",
4443 levels[i], nt_errstr(status));
4451 static bool test_QueryDisplayInfo3(struct dcerpc_pipe *p, struct torture_context *tctx,
4452 struct policy_handle *handle)
4455 struct samr_QueryDisplayInfo3 r;
4457 uint16_t levels[] = {1, 2, 3, 4, 5};
4459 uint32_t total_size;
4460 uint32_t returned_size;
4461 union samr_DispInfo info;
4463 for (i=0;i<ARRAY_SIZE(levels);i++) {
4464 torture_comment(tctx, "Testing QueryDisplayInfo3 level %u\n", levels[i]);
4466 r.in.domain_handle = handle;
4467 r.in.level = levels[i];
4469 r.in.max_entries = 1000;
4470 r.in.buf_size = (uint32_t)-1;
4471 r.out.total_size = &total_size;
4472 r.out.returned_size = &returned_size;
4475 status = dcerpc_samr_QueryDisplayInfo3(p, tctx, &r);
4476 if (!NT_STATUS_IS_OK(status)) {
4477 printf("QueryDisplayInfo3 level %u failed - %s\n",
4478 levels[i], nt_errstr(status));
4487 static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4488 struct policy_handle *handle)
4491 struct samr_QueryDisplayInfo r;
4493 uint32_t total_size;
4494 uint32_t returned_size;
4495 union samr_DispInfo info;
4497 printf("Testing QueryDisplayInfo continuation\n");
4499 r.in.domain_handle = handle;
4502 r.in.max_entries = 1;
4503 r.in.buf_size = (uint32_t)-1;
4504 r.out.total_size = &total_size;
4505 r.out.returned_size = &returned_size;
4509 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
4510 if (NT_STATUS_IS_OK(status) && *r.out.returned_size != 0) {
4511 if (r.out.info->info1.entries[0].idx != r.in.start_idx + 1) {
4512 printf("expected idx %d but got %d\n",
4514 r.out.info->info1.entries[0].idx);
4518 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
4519 !NT_STATUS_IS_OK(status)) {
4520 printf("QueryDisplayInfo level %u failed - %s\n",
4521 r.in.level, nt_errstr(status));
4526 } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
4527 NT_STATUS_IS_OK(status)) &&
4528 *r.out.returned_size != 0);
4533 static bool test_QueryDomainInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
4534 struct policy_handle *handle)
4537 struct samr_QueryDomainInfo r;
4538 union samr_DomainInfo *info = NULL;
4539 struct samr_SetDomainInfo s;
4540 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
4541 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
4544 const char *domain_comment = talloc_asprintf(tctx,
4545 "Tortured by Samba4 RPC-SAMR: %s",
4546 timestring(tctx, time(NULL)));
4548 s.in.domain_handle = handle;
4550 s.in.info = talloc(tctx, union samr_DomainInfo);
4552 s.in.info->oem.oem_information.string = domain_comment;
4553 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
4554 if (!NT_STATUS_IS_OK(status)) {
4555 printf("SetDomainInfo level %u (set comment) failed - %s\n",
4556 r.in.level, nt_errstr(status));
4560 for (i=0;i<ARRAY_SIZE(levels);i++) {
4561 torture_comment(tctx, "Testing QueryDomainInfo level %u\n", levels[i]);
4563 r.in.domain_handle = handle;
4564 r.in.level = levels[i];
4567 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
4568 if (!NT_STATUS_IS_OK(status)) {
4569 printf("QueryDomainInfo level %u failed - %s\n",
4570 r.in.level, nt_errstr(status));
4575 switch (levels[i]) {
4577 if (strcmp(info->general.oem_information.string, domain_comment) != 0) {
4578 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
4579 levels[i], info->general.oem_information.string, domain_comment);
4582 if (!info->general.primary.string) {
4583 printf("QueryDomainInfo level %u returned no PDC name\n",
4586 } else if (info->general.role == SAMR_ROLE_DOMAIN_PDC) {
4587 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), info->general.primary.string) != 0) {
4588 printf("QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
4589 levels[i], info->general.primary.string, dcerpc_server_name(p));
4594 if (strcmp(info->oem.oem_information.string, domain_comment) != 0) {
4595 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
4596 levels[i], info->oem.oem_information.string, domain_comment);
4601 if (!info->info6.primary.string) {
4602 printf("QueryDomainInfo level %u returned no PDC name\n",
4608 if (strcmp(info->general2.general.oem_information.string, domain_comment) != 0) {
4609 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
4610 levels[i], info->general2.general.oem_information.string, domain_comment);
4616 torture_comment(tctx, "Testing SetDomainInfo level %u\n", levels[i]);
4618 s.in.domain_handle = handle;
4619 s.in.level = levels[i];
4622 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
4624 if (!NT_STATUS_IS_OK(status)) {
4625 printf("SetDomainInfo level %u failed - %s\n",
4626 r.in.level, nt_errstr(status));
4631 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
4632 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
4633 r.in.level, nt_errstr(status));
4639 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
4640 if (!NT_STATUS_IS_OK(status)) {
4641 printf("QueryDomainInfo level %u failed - %s\n",
4642 r.in.level, nt_errstr(status));
4652 static bool test_QueryDomainInfo2(struct dcerpc_pipe *p, struct torture_context *tctx,
4653 struct policy_handle *handle)
4656 struct samr_QueryDomainInfo2 r;
4657 union samr_DomainInfo *info = NULL;
4658 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
4662 for (i=0;i<ARRAY_SIZE(levels);i++) {
4663 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
4665 r.in.domain_handle = handle;
4666 r.in.level = levels[i];
4669 status = dcerpc_samr_QueryDomainInfo2(p, tctx, &r);
4670 if (!NT_STATUS_IS_OK(status)) {
4671 printf("QueryDomainInfo2 level %u failed - %s\n",
4672 r.in.level, nt_errstr(status));
4681 /* Test whether querydispinfo level 5 and enumdomgroups return the same
4682 set of group names. */
4683 static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx,
4684 struct policy_handle *handle)
4686 struct samr_EnumDomainGroups q1;
4687 struct samr_QueryDisplayInfo q2;
4689 uint32_t resume_handle=0;
4690 struct samr_SamArray *sam = NULL;
4691 uint32_t num_entries = 0;
4694 uint32_t total_size;
4695 uint32_t returned_size;
4696 union samr_DispInfo info;
4699 const char **names = NULL;
4701 torture_comment(tctx, "Testing coherency of querydispinfo vs enumdomgroups\n");
4703 q1.in.domain_handle = handle;
4704 q1.in.resume_handle = &resume_handle;
4706 q1.out.resume_handle = &resume_handle;
4707 q1.out.num_entries = &num_entries;
4710 status = STATUS_MORE_ENTRIES;
4711 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
4712 status = dcerpc_samr_EnumDomainGroups(p, tctx, &q1);
4714 if (!NT_STATUS_IS_OK(status) &&
4715 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
4718 for (i=0; i<*q1.out.num_entries; i++) {
4719 add_string_to_array(tctx,
4720 sam->entries[i].name.string,
4721 &names, &num_names);
4725 torture_assert_ntstatus_ok(tctx, status, "EnumDomainGroups");
4727 torture_assert(tctx, sam, "EnumDomainGroups failed to return sam");
4729 q2.in.domain_handle = handle;
4731 q2.in.start_idx = 0;
4732 q2.in.max_entries = 5;
4733 q2.in.buf_size = (uint32_t)-1;
4734 q2.out.total_size = &total_size;
4735 q2.out.returned_size = &returned_size;
4736 q2.out.info = &info;
4738 status = STATUS_MORE_ENTRIES;
4739 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
4740 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &q2);
4742 if (!NT_STATUS_IS_OK(status) &&
4743 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
4746 for (i=0; i<q2.out.info->info5.count; i++) {
4748 const char *name = q2.out.info->info5.entries[i].account_name.string;
4750 for (j=0; j<num_names; j++) {
4751 if (names[j] == NULL)
4753 if (strequal(names[j], name)) {
4761 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
4766 q2.in.start_idx += q2.out.info->info5.count;
4769 if (!NT_STATUS_IS_OK(status)) {
4770 printf("QueryDisplayInfo level 5 failed - %s\n",
4775 for (i=0; i<num_names; i++) {
4776 if (names[i] != NULL) {
4777 printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
4786 static bool test_DeleteDomainGroup(struct dcerpc_pipe *p, struct torture_context *tctx,
4787 struct policy_handle *group_handle)
4789 struct samr_DeleteDomainGroup d;
4792 torture_comment(tctx, "Testing DeleteDomainGroup\n");
4794 d.in.group_handle = group_handle;
4795 d.out.group_handle = group_handle;
4797 status = dcerpc_samr_DeleteDomainGroup(p, tctx, &d);
4798 torture_assert_ntstatus_ok(tctx, status, "DeleteDomainGroup");
4803 static bool test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
4804 struct policy_handle *domain_handle)
4806 struct samr_TestPrivateFunctionsDomain r;
4810 torture_comment(tctx, "Testing TestPrivateFunctionsDomain\n");
4812 r.in.domain_handle = domain_handle;
4814 status = dcerpc_samr_TestPrivateFunctionsDomain(p, tctx, &r);
4815 torture_assert_ntstatus_equal(tctx, NT_STATUS_NOT_IMPLEMENTED, status, "TestPrivateFunctionsDomain");
4820 static bool test_RidToSid(struct dcerpc_pipe *p, struct torture_context *tctx,
4821 struct dom_sid *domain_sid,
4822 struct policy_handle *domain_handle)
4824 struct samr_RidToSid r;
4827 struct dom_sid *calc_sid, *out_sid;
4828 int rids[] = { 0, 42, 512, 10200 };
4831 for (i=0;i<ARRAY_SIZE(rids);i++) {
4832 torture_comment(tctx, "Testing RidToSid\n");
4834 calc_sid = dom_sid_dup(tctx, domain_sid);
4835 r.in.domain_handle = domain_handle;
4837 r.out.sid = &out_sid;
4839 status = dcerpc_samr_RidToSid(p, tctx, &r);
4840 if (!NT_STATUS_IS_OK(status)) {
4841 printf("RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
4844 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
4846 if (!dom_sid_equal(calc_sid, out_sid)) {
4847 printf("RidToSid for %d failed - got %s, expected %s\n", rids[i],
4848 dom_sid_string(tctx, out_sid),
4849 dom_sid_string(tctx, calc_sid));
4858 static bool test_GetBootKeyInformation(struct dcerpc_pipe *p, struct torture_context *tctx,
4859 struct policy_handle *domain_handle)
4861 struct samr_GetBootKeyInformation r;
4864 uint32_t unknown = 0;
4866 torture_comment(tctx, "Testing GetBootKeyInformation\n");
4868 r.in.domain_handle = domain_handle;
4869 r.out.unknown = &unknown;
4871 status = dcerpc_samr_GetBootKeyInformation(p, tctx, &r);
4872 if (!NT_STATUS_IS_OK(status)) {
4873 /* w2k3 seems to fail this sometimes and pass it sometimes */
4874 torture_comment(tctx, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
4880 static bool test_AddGroupMember(struct dcerpc_pipe *p, struct torture_context *tctx,
4881 struct policy_handle *domain_handle,
4882 struct policy_handle *group_handle)
4885 struct samr_AddGroupMember r;
4886 struct samr_DeleteGroupMember d;
4887 struct samr_QueryGroupMember q;
4888 struct samr_RidTypeArray *rids = NULL;
4889 struct samr_SetMemberAttributesOfGroup s;
4892 status = test_LookupName(p, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
4893 torture_assert_ntstatus_ok(tctx, status, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME);
4895 r.in.group_handle = group_handle;
4897 r.in.flags = 0; /* ??? */
4899 torture_comment(tctx, "Testing AddGroupMember and DeleteGroupMember\n");
4901 d.in.group_handle = group_handle;
4904 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
4905 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_NOT_IN_GROUP, status, "DeleteGroupMember");
4907 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4908 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
4910 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4911 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_IN_GROUP, status, "AddGroupMember");
4913 if (torture_setting_bool(tctx, "samba4", false)) {
4914 torture_comment(tctx, "skipping SetMemberAttributesOfGroup test against Samba4\n");
4916 /* this one is quite strange. I am using random inputs in the
4917 hope of triggering an error that might give us a clue */
4919 s.in.group_handle = group_handle;
4920 s.in.unknown1 = random();
4921 s.in.unknown2 = random();
4923 status = dcerpc_samr_SetMemberAttributesOfGroup(p, tctx, &s);
4924 torture_assert_ntstatus_ok(tctx, status, "SetMemberAttributesOfGroup");
4927 q.in.group_handle = group_handle;
4930 status = dcerpc_samr_QueryGroupMember(p, tctx, &q);
4931 torture_assert_ntstatus_ok(tctx, status, "QueryGroupMember");
4933 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
4934 torture_assert_ntstatus_ok(tctx, status, "DeleteGroupMember");
4936 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4937 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
4943 static bool test_CreateDomainGroup(struct dcerpc_pipe *p,
4944 struct torture_context *tctx,
4945 struct policy_handle *domain_handle,
4946 struct policy_handle *group_handle,
4947 struct dom_sid *domain_sid)
4950 struct samr_CreateDomainGroup r;
4952 struct lsa_String name;
4955 init_lsa_String(&name, TEST_GROUPNAME);
4957 r.in.domain_handle = domain_handle;
4959 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4960 r.out.group_handle = group_handle;
4963 printf("Testing CreateDomainGroup(%s)\n", r.in.name->string);
4965 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
4967 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
4968 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
4969 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.name->string);
4972 printf("Server should have refused create of '%s', got %s instead\n", r.in.name->string,
4978 if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS)) {
4979 if (!test_DeleteGroup_byname(p, tctx, domain_handle, r.in.name->string)) {
4980 printf("CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
4984 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
4986 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
4987 if (!test_DeleteUser_byname(p, tctx, domain_handle, r.in.name->string)) {
4989 printf("CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
4993 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
4995 torture_assert_ntstatus_ok(tctx, status, "CreateDomainGroup");
4997 if (!test_AddGroupMember(p, tctx, domain_handle, group_handle)) {
4998 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
5002 if (!test_SetGroupInfo(p, tctx, group_handle)) {
5011 its not totally clear what this does. It seems to accept any sid you like.
5013 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p,
5014 struct torture_context *tctx,
5015 struct policy_handle *domain_handle)
5018 struct samr_RemoveMemberFromForeignDomain r;
5020 r.in.domain_handle = domain_handle;
5021 r.in.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-12-34-56-78");
5023 status = dcerpc_samr_RemoveMemberFromForeignDomain(p, tctx, &r);
5024 torture_assert_ntstatus_ok(tctx, status, "RemoveMemberFromForeignDomain");
5031 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
5032 struct policy_handle *handle);
5034 static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
5035 struct policy_handle *handle, struct dom_sid *sid,
5036 enum torture_samr_choice which_ops)
5039 struct samr_OpenDomain r;
5040 struct policy_handle domain_handle;
5041 struct policy_handle alias_handle;
5042 struct policy_handle user_handle;
5043 struct policy_handle group_handle;
5046 ZERO_STRUCT(alias_handle);
5047 ZERO_STRUCT(user_handle);
5048 ZERO_STRUCT(group_handle);
5049 ZERO_STRUCT(domain_handle);
5051 torture_comment(tctx, "Testing OpenDomain of %s\n", dom_sid_string(tctx, sid));
5053 r.in.connect_handle = handle;
5054 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5056 r.out.domain_handle = &domain_handle;
5058 status = dcerpc_samr_OpenDomain(p, tctx, &r);
5059 torture_assert_ntstatus_ok(tctx, status, "OpenDomain");
5061 /* run the domain tests with the main handle closed - this tests
5062 the servers reference counting */
5063 ret &= test_samr_handle_Close(p, tctx, handle);
5065 switch (which_ops) {
5066 case TORTURE_SAMR_USER_ATTRIBUTES:
5067 case TORTURE_SAMR_PASSWORDS:
5068 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
5069 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops);
5070 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops);
5071 /* This test needs 'complex' users to validate */
5072 ret &= test_QueryDisplayInfo(p, tctx, &domain_handle);
5074 printf("Testing PASSWORDS or ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
5077 case TORTURE_SAMR_OTHER:
5078 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops);
5080 printf("Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid));
5082 ret &= test_QuerySecurity(p, tctx, &domain_handle);
5083 ret &= test_RemoveMemberFromForeignDomain(p, tctx, &domain_handle);
5084 ret &= test_CreateAlias(p, tctx, &domain_handle, &alias_handle, sid);
5085 ret &= test_CreateDomainGroup(p, tctx, &domain_handle, &group_handle, sid);
5086 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
5087 ret &= test_QueryDomainInfo2(p, tctx, &domain_handle);
5088 ret &= test_EnumDomainUsers(p, tctx, &domain_handle);
5089 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
5090 ret &= test_EnumDomainGroups(p, tctx, &domain_handle);
5091 ret &= test_EnumDomainAliases(p, tctx, &domain_handle);
5092 ret &= test_QueryDisplayInfo2(p, tctx, &domain_handle);
5093 ret &= test_QueryDisplayInfo3(p, tctx, &domain_handle);
5094 ret &= test_QueryDisplayInfo_continue(p, tctx, &domain_handle);
5096 if (torture_setting_bool(tctx, "samba4", false)) {
5097 torture_comment(tctx, "skipping GetDisplayEnumerationIndex test against Samba4\n");
5099 ret &= test_GetDisplayEnumerationIndex(p, tctx, &domain_handle);
5100 ret &= test_GetDisplayEnumerationIndex2(p, tctx, &domain_handle);
5102 ret &= test_GroupList(p, tctx, &domain_handle);
5103 ret &= test_TestPrivateFunctionsDomain(p, tctx, &domain_handle);
5104 ret &= test_RidToSid(p, tctx, sid, &domain_handle);
5105 ret &= test_GetBootKeyInformation(p, tctx, &domain_handle);
5107 torture_comment(tctx, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx, sid));
5112 if (!policy_handle_empty(&user_handle) &&
5113 !test_DeleteUser(p, tctx, &user_handle)) {
5117 if (!policy_handle_empty(&alias_handle) &&
5118 !test_DeleteAlias(p, tctx, &alias_handle)) {
5122 if (!policy_handle_empty(&group_handle) &&
5123 !test_DeleteDomainGroup(p, tctx, &group_handle)) {
5127 ret &= test_samr_handle_Close(p, tctx, &domain_handle);
5129 /* reconnect the main handle */
5130 ret &= test_Connect(p, tctx, handle);
5133 printf("Testing domain %s failed!\n", dom_sid_string(tctx, sid));
5139 static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
5140 struct policy_handle *handle, const char *domain,
5141 enum torture_samr_choice which_ops)
5144 struct samr_LookupDomain r;
5145 struct dom_sid2 *sid = NULL;
5146 struct lsa_String n1;
5147 struct lsa_String n2;
5150 torture_comment(tctx, "Testing LookupDomain(%s)\n", domain);
5152 /* check for correct error codes */
5153 r.in.connect_handle = handle;
5154 r.in.domain_name = &n2;
5158 status = dcerpc_samr_LookupDomain(p, tctx, &r);
5159 torture_assert_ntstatus_equal(tctx, NT_STATUS_INVALID_PARAMETER, status, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
5161 init_lsa_String(&n2, "xxNODOMAINxx");
5163 status = dcerpc_samr_LookupDomain(p, tctx, &r);
5164 torture_assert_ntstatus_equal(tctx, NT_STATUS_NO_SUCH_DOMAIN, status, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
5166 r.in.connect_handle = handle;
5168 init_lsa_String(&n1, domain);
5169 r.in.domain_name = &n1;
5171 status = dcerpc_samr_LookupDomain(p, tctx, &r);
5172 torture_assert_ntstatus_ok(tctx, status, "LookupDomain");
5174 if (!test_GetDomPwInfo(p, tctx, &n1)) {
5178 if (!test_OpenDomain(p, tctx, handle, *r.out.sid, which_ops)) {
5186 static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
5187 struct policy_handle *handle, enum torture_samr_choice which_ops)
5190 struct samr_EnumDomains r;
5191 uint32_t resume_handle = 0;
5192 uint32_t num_entries = 0;
5193 struct samr_SamArray *sam = NULL;
5197 r.in.connect_handle = handle;
5198 r.in.resume_handle = &resume_handle;
5199 r.in.buf_size = (uint32_t)-1;
5200 r.out.resume_handle = &resume_handle;
5201 r.out.num_entries = &num_entries;
5204 status = dcerpc_samr_EnumDomains(p, tctx, &r);
5205 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
5211 for (i=0;i<sam->count;i++) {
5212 if (!test_LookupDomain(p, tctx, handle,
5213 sam->entries[i].name.string, which_ops)) {
5218 status = dcerpc_samr_EnumDomains(p, tctx, &r);
5219 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
5225 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
5226 struct policy_handle *handle)
5229 struct samr_Connect r;
5230 struct samr_Connect2 r2;
5231 struct samr_Connect3 r3;
5232 struct samr_Connect4 r4;
5233 struct samr_Connect5 r5;
5234 union samr_ConnectInfo info;
5235 struct policy_handle h;
5236 uint32_t level_out = 0;
5237 bool ret = true, got_handle = false;
5239 torture_comment(tctx, "testing samr_Connect\n");
5241 r.in.system_name = 0;
5242 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5243 r.out.connect_handle = &h;
5245 status = dcerpc_samr_Connect(p, tctx, &r);
5246 if (!NT_STATUS_IS_OK(status)) {
5247 torture_comment(tctx, "Connect failed - %s\n", nt_errstr(status));
5254 torture_comment(tctx, "testing samr_Connect2\n");
5256 r2.in.system_name = NULL;
5257 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5258 r2.out.connect_handle = &h;
5260 status = dcerpc_samr_Connect2(p, tctx, &r2);
5261 if (!NT_STATUS_IS_OK(status)) {
5262 torture_comment(tctx, "Connect2 failed - %s\n", nt_errstr(status));
5266 test_samr_handle_Close(p, tctx, handle);
5272 torture_comment(tctx, "testing samr_Connect3\n");
5274 r3.in.system_name = NULL;
5276 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5277 r3.out.connect_handle = &h;
5279 status = dcerpc_samr_Connect3(p, tctx, &r3);
5280 if (!NT_STATUS_IS_OK(status)) {
5281 printf("Connect3 failed - %s\n", nt_errstr(status));
5285 test_samr_handle_Close(p, tctx, handle);
5291 torture_comment(tctx, "testing samr_Connect4\n");
5293 r4.in.system_name = "";
5294 r4.in.client_version = 0;
5295 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5296 r4.out.connect_handle = &h;
5298 status = dcerpc_samr_Connect4(p, tctx, &r4);
5299 if (!NT_STATUS_IS_OK(status)) {
5300 printf("Connect4 failed - %s\n", nt_errstr(status));
5304 test_samr_handle_Close(p, tctx, handle);
5310 torture_comment(tctx, "testing samr_Connect5\n");
5312 info.info1.client_version = 0;
5313 info.info1.unknown2 = 0;
5315 r5.in.system_name = "";
5316 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5318 r5.out.level_out = &level_out;
5319 r5.in.info_in = &info;
5320 r5.out.info_out = &info;
5321 r5.out.connect_handle = &h;
5323 status = dcerpc_samr_Connect5(p, tctx, &r5);
5324 if (!NT_STATUS_IS_OK(status)) {
5325 printf("Connect5 failed - %s\n", nt_errstr(status));
5329 test_samr_handle_Close(p, tctx, handle);
5339 bool torture_rpc_samr(struct torture_context *torture)
5342 struct dcerpc_pipe *p;
5344 struct policy_handle handle;
5346 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
5347 if (!NT_STATUS_IS_OK(status)) {
5351 ret &= test_Connect(p, torture, &handle);
5353 ret &= test_QuerySecurity(p, torture, &handle);
5355 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_OTHER);
5357 ret &= test_SetDsrmPassword(p, torture, &handle);
5359 ret &= test_Shutdown(p, torture, &handle);
5361 ret &= test_samr_handle_Close(p, torture, &handle);
5367 bool torture_rpc_samr_users(struct torture_context *torture)
5370 struct dcerpc_pipe *p;
5372 struct policy_handle handle;
5374 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
5375 if (!NT_STATUS_IS_OK(status)) {
5379 ret &= test_Connect(p, torture, &handle);
5381 ret &= test_QuerySecurity(p, torture, &handle);
5383 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_USER_ATTRIBUTES);
5385 ret &= test_SetDsrmPassword(p, torture, &handle);
5387 ret &= test_Shutdown(p, torture, &handle);
5389 ret &= test_samr_handle_Close(p, torture, &handle);
5395 bool torture_rpc_samr_passwords(struct torture_context *torture)
5398 struct dcerpc_pipe *p;
5400 struct policy_handle handle;
5402 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
5403 if (!NT_STATUS_IS_OK(status)) {
5407 ret &= test_Connect(p, torture, &handle);
5409 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_PASSWORDS);
5411 ret &= test_samr_handle_Close(p, torture, &handle);
5416 bool torture_rpc_samr_passwords_pwdlastset(struct torture_context *torture)
5419 struct dcerpc_pipe *p;
5421 struct policy_handle handle;
5423 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
5424 if (!NT_STATUS_IS_OK(status)) {
5428 ret &= test_Connect(p, torture, &handle);
5430 ret &= test_EnumDomains(p, torture, &handle,
5431 TORTURE_SAMR_PASSWORDS_PWDLASTSET);
5433 ret &= test_samr_handle_Close(p, torture, &handle);