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 const char *comment = NULL;
875 pwp.in.user_handle = handle;
876 pwp.out.info = &info;
878 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
879 if (NT_STATUS_IS_OK(status)) {
880 policy_min_pw_len = pwp.out.info->min_password_length;
882 newpass = samr_rand_pass_silent(tctx, policy_min_pw_len);
885 s2.in.user_handle = handle;
889 s.in.user_handle = handle;
894 if (fields_present & SAMR_FIELD_COMMENT) {
895 comment = talloc_asprintf(tctx, "comment: %d\n", time(NULL));
902 u.info21.fields_present = fields_present;
903 u.info21.password_expired = password_expired;
904 u.info21.comment.string = comment;
908 u.info23.info.fields_present = fields_present;
909 u.info23.info.password_expired = password_expired;
910 u.info23.info.comment.string = comment;
912 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
916 u.info24.password_expired = password_expired;
918 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
922 u.info25.info.fields_present = fields_present;
923 u.info25.info.password_expired = password_expired;
924 u.info25.info.comment.string = comment;
926 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
930 u.info26.password_expired = password_expired;
932 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
937 status = dcerpc_fetch_session_key(p, &session_key);
938 if (!NT_STATUS_IS_OK(status)) {
939 printf("SetUserInfo level %u - no session key - %s\n",
940 s.in.level, nt_errstr(status));
944 generate_random_buffer((uint8_t *)confounder, 16);
947 MD5Update(&ctx, confounder, 16);
948 MD5Update(&ctx, session_key.data, session_key.length);
949 MD5Final(confounded_session_key.data, &ctx);
953 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
956 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
959 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
960 memcpy(&u.info25.password.data[516], confounder, 16);
963 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
964 memcpy(&u.info26.password.data[516], confounder, 16);
969 status = dcerpc_samr_SetUserInfo2(p, tctx, &s2);
971 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
974 if (!NT_STATUS_IS_OK(expected_error)) {
976 torture_assert_ntstatus_equal(tctx,
978 expected_error, "SetUserInfo2 failed");
980 torture_assert_ntstatus_equal(tctx,
982 expected_error, "SetUserInfo failed");
987 if (!NT_STATUS_IS_OK(status)) {
988 printf("SetUserInfo%s level %u failed - %s\n",
989 use_setinfo2 ? "2":"", level, nt_errstr(status));
1000 static bool test_SetAliasInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1001 struct policy_handle *handle)
1004 struct samr_SetAliasInfo r;
1005 struct samr_QueryAliasInfo q;
1006 union samr_AliasInfo *info;
1007 uint16_t levels[] = {2, 3};
1011 /* Ignoring switch level 1, as that includes the number of members for the alias
1012 * and setting this to a wrong value might have negative consequences
1015 for (i=0;i<ARRAY_SIZE(levels);i++) {
1016 torture_comment(tctx, "Testing SetAliasInfo level %u\n", levels[i]);
1018 r.in.alias_handle = handle;
1019 r.in.level = levels[i];
1020 r.in.info = talloc(tctx, union samr_AliasInfo);
1021 switch (r.in.level) {
1022 case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
1023 case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
1024 "Test Description, should test I18N as well"); break;
1025 case ALIASINFOALL: printf("ALIASINFOALL ignored\n"); break;
1028 status = dcerpc_samr_SetAliasInfo(p, tctx, &r);
1029 if (!NT_STATUS_IS_OK(status)) {
1030 printf("SetAliasInfo level %u failed - %s\n",
1031 levels[i], nt_errstr(status));
1035 q.in.alias_handle = handle;
1036 q.in.level = levels[i];
1039 status = dcerpc_samr_QueryAliasInfo(p, tctx, &q);
1040 if (!NT_STATUS_IS_OK(status)) {
1041 printf("QueryAliasInfo level %u failed - %s\n",
1042 levels[i], nt_errstr(status));
1050 static bool test_GetGroupsForUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1051 struct policy_handle *user_handle)
1053 struct samr_GetGroupsForUser r;
1054 struct samr_RidWithAttributeArray *rids = NULL;
1057 torture_comment(tctx, "testing GetGroupsForUser\n");
1059 r.in.user_handle = user_handle;
1062 status = dcerpc_samr_GetGroupsForUser(p, tctx, &r);
1063 torture_assert_ntstatus_ok(tctx, status, "GetGroupsForUser");
1069 static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1070 struct lsa_String *domain_name)
1073 struct samr_GetDomPwInfo r;
1074 struct samr_PwInfo info;
1076 r.in.domain_name = domain_name;
1079 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1081 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1082 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1084 r.in.domain_name->string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1085 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1087 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1088 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1090 r.in.domain_name->string = "\\\\__NONAME__";
1091 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1093 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1094 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1096 r.in.domain_name->string = "\\\\Builtin";
1097 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1099 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1100 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1105 static bool test_GetUserPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1106 struct policy_handle *handle)
1109 struct samr_GetUserPwInfo r;
1110 struct samr_PwInfo info;
1112 torture_comment(tctx, "Testing GetUserPwInfo\n");
1114 r.in.user_handle = handle;
1117 status = dcerpc_samr_GetUserPwInfo(p, tctx, &r);
1118 torture_assert_ntstatus_ok(tctx, status, "GetUserPwInfo");
1123 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, struct torture_context *tctx,
1124 struct policy_handle *domain_handle, const char *name,
1128 struct samr_LookupNames n;
1129 struct lsa_String sname[2];
1130 struct samr_Ids rids, types;
1132 init_lsa_String(&sname[0], name);
1134 n.in.domain_handle = domain_handle;
1138 n.out.types = &types;
1139 status = dcerpc_samr_LookupNames(p, tctx, &n);
1140 if (NT_STATUS_IS_OK(status)) {
1141 *rid = n.out.rids->ids[0];
1146 init_lsa_String(&sname[1], "xxNONAMExx");
1148 status = dcerpc_samr_LookupNames(p, tctx, &n);
1149 if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
1150 printf("LookupNames[2] failed - %s\n", nt_errstr(status));
1151 if (NT_STATUS_IS_OK(status)) {
1152 return NT_STATUS_UNSUCCESSFUL;
1158 status = dcerpc_samr_LookupNames(p, tctx, &n);
1159 if (!NT_STATUS_IS_OK(status)) {
1160 printf("LookupNames[0] failed - %s\n", nt_errstr(status));
1164 init_lsa_String(&sname[0], "xxNONAMExx");
1166 status = dcerpc_samr_LookupNames(p, tctx, &n);
1167 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1168 printf("LookupNames[1 bad name] failed - %s\n", nt_errstr(status));
1169 if (NT_STATUS_IS_OK(status)) {
1170 return NT_STATUS_UNSUCCESSFUL;
1175 init_lsa_String(&sname[0], "xxNONAMExx");
1176 init_lsa_String(&sname[1], "xxNONAME2xx");
1178 status = dcerpc_samr_LookupNames(p, tctx, &n);
1179 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1180 printf("LookupNames[2 bad names] failed - %s\n", nt_errstr(status));
1181 if (NT_STATUS_IS_OK(status)) {
1182 return NT_STATUS_UNSUCCESSFUL;
1187 return NT_STATUS_OK;
1190 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1191 struct policy_handle *domain_handle,
1192 const char *name, struct policy_handle *user_handle)
1195 struct samr_OpenUser r;
1198 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
1199 if (!NT_STATUS_IS_OK(status)) {
1203 r.in.domain_handle = domain_handle;
1204 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1206 r.out.user_handle = user_handle;
1207 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
1208 if (!NT_STATUS_IS_OK(status)) {
1209 printf("OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(status));
1216 static bool test_ChangePasswordNT3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1217 struct policy_handle *handle)
1220 struct samr_ChangePasswordUser r;
1222 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1223 struct policy_handle user_handle;
1224 char *oldpass = "test";
1225 char *newpass = "test2";
1226 uint8_t old_nt_hash[16], new_nt_hash[16];
1227 uint8_t old_lm_hash[16], new_lm_hash[16];
1229 status = test_OpenUser_byname(p, mem_ctx, handle, "testuser", &user_handle);
1230 if (!NT_STATUS_IS_OK(status)) {
1234 printf("Testing ChangePasswordUser for user 'testuser'\n");
1236 printf("old password: %s\n", oldpass);
1237 printf("new password: %s\n", newpass);
1239 E_md4hash(oldpass, old_nt_hash);
1240 E_md4hash(newpass, new_nt_hash);
1241 E_deshash(oldpass, old_lm_hash);
1242 E_deshash(newpass, new_lm_hash);
1244 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1245 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1246 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1247 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1248 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1249 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1251 r.in.handle = &user_handle;
1252 r.in.lm_present = 1;
1253 r.in.old_lm_crypted = &hash1;
1254 r.in.new_lm_crypted = &hash2;
1255 r.in.nt_present = 1;
1256 r.in.old_nt_crypted = &hash3;
1257 r.in.new_nt_crypted = &hash4;
1258 r.in.cross1_present = 1;
1259 r.in.nt_cross = &hash5;
1260 r.in.cross2_present = 1;
1261 r.in.lm_cross = &hash6;
1263 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1264 if (!NT_STATUS_IS_OK(status)) {
1265 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1269 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1277 static bool test_ChangePasswordUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1278 const char *acct_name,
1279 struct policy_handle *handle, char **password)
1282 struct samr_ChangePasswordUser r;
1284 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1285 struct policy_handle user_handle;
1287 uint8_t old_nt_hash[16], new_nt_hash[16];
1288 uint8_t old_lm_hash[16], new_lm_hash[16];
1289 bool changed = true;
1292 struct samr_GetUserPwInfo pwp;
1293 struct samr_PwInfo info;
1294 int policy_min_pw_len = 0;
1296 status = test_OpenUser_byname(p, tctx, handle, acct_name, &user_handle);
1297 if (!NT_STATUS_IS_OK(status)) {
1300 pwp.in.user_handle = &user_handle;
1301 pwp.out.info = &info;
1303 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1304 if (NT_STATUS_IS_OK(status)) {
1305 policy_min_pw_len = pwp.out.info->min_password_length;
1307 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1309 torture_comment(tctx, "Testing ChangePasswordUser\n");
1311 torture_assert(tctx, *password != NULL,
1312 "Failing ChangePasswordUser as old password was NULL. Previous test failed?");
1314 oldpass = *password;
1316 E_md4hash(oldpass, old_nt_hash);
1317 E_md4hash(newpass, new_nt_hash);
1318 E_deshash(oldpass, old_lm_hash);
1319 E_deshash(newpass, new_lm_hash);
1321 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1322 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1323 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1324 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1325 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1326 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1328 r.in.user_handle = &user_handle;
1329 r.in.lm_present = 1;
1330 /* Break the LM hash */
1332 r.in.old_lm_crypted = &hash1;
1333 r.in.new_lm_crypted = &hash2;
1334 r.in.nt_present = 1;
1335 r.in.old_nt_crypted = &hash3;
1336 r.in.new_nt_crypted = &hash4;
1337 r.in.cross1_present = 1;
1338 r.in.nt_cross = &hash5;
1339 r.in.cross2_present = 1;
1340 r.in.lm_cross = &hash6;
1342 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1343 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1344 "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash");
1346 /* Unbreak the LM hash */
1349 r.in.user_handle = &user_handle;
1350 r.in.lm_present = 1;
1351 r.in.old_lm_crypted = &hash1;
1352 r.in.new_lm_crypted = &hash2;
1353 /* Break the NT hash */
1355 r.in.nt_present = 1;
1356 r.in.old_nt_crypted = &hash3;
1357 r.in.new_nt_crypted = &hash4;
1358 r.in.cross1_present = 1;
1359 r.in.nt_cross = &hash5;
1360 r.in.cross2_present = 1;
1361 r.in.lm_cross = &hash6;
1363 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1364 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1365 "expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash");
1367 /* Unbreak the NT hash */
1370 r.in.user_handle = &user_handle;
1371 r.in.lm_present = 1;
1372 r.in.old_lm_crypted = &hash1;
1373 r.in.new_lm_crypted = &hash2;
1374 r.in.nt_present = 1;
1375 r.in.old_nt_crypted = &hash3;
1376 r.in.new_nt_crypted = &hash4;
1377 r.in.cross1_present = 1;
1378 r.in.nt_cross = &hash5;
1379 r.in.cross2_present = 1;
1380 /* Break the LM cross */
1382 r.in.lm_cross = &hash6;
1384 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1385 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1386 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status));
1390 /* Unbreak the LM cross */
1393 r.in.user_handle = &user_handle;
1394 r.in.lm_present = 1;
1395 r.in.old_lm_crypted = &hash1;
1396 r.in.new_lm_crypted = &hash2;
1397 r.in.nt_present = 1;
1398 r.in.old_nt_crypted = &hash3;
1399 r.in.new_nt_crypted = &hash4;
1400 r.in.cross1_present = 1;
1401 /* Break the NT cross */
1403 r.in.nt_cross = &hash5;
1404 r.in.cross2_present = 1;
1405 r.in.lm_cross = &hash6;
1407 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1408 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1409 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status));
1413 /* Unbreak the NT cross */
1417 /* Reset the hashes to not broken values */
1418 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1419 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1420 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1421 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1422 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1423 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1425 r.in.user_handle = &user_handle;
1426 r.in.lm_present = 1;
1427 r.in.old_lm_crypted = &hash1;
1428 r.in.new_lm_crypted = &hash2;
1429 r.in.nt_present = 1;
1430 r.in.old_nt_crypted = &hash3;
1431 r.in.new_nt_crypted = &hash4;
1432 r.in.cross1_present = 1;
1433 r.in.nt_cross = &hash5;
1434 r.in.cross2_present = 0;
1435 r.in.lm_cross = NULL;
1437 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1438 if (NT_STATUS_IS_OK(status)) {
1440 *password = newpass;
1441 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1442 printf("ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(status));
1447 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1449 E_md4hash(oldpass, old_nt_hash);
1450 E_md4hash(newpass, new_nt_hash);
1451 E_deshash(oldpass, old_lm_hash);
1452 E_deshash(newpass, new_lm_hash);
1455 /* Reset the hashes to not broken values */
1456 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1457 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1458 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1459 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1460 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1461 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1463 r.in.user_handle = &user_handle;
1464 r.in.lm_present = 1;
1465 r.in.old_lm_crypted = &hash1;
1466 r.in.new_lm_crypted = &hash2;
1467 r.in.nt_present = 1;
1468 r.in.old_nt_crypted = &hash3;
1469 r.in.new_nt_crypted = &hash4;
1470 r.in.cross1_present = 0;
1471 r.in.nt_cross = NULL;
1472 r.in.cross2_present = 1;
1473 r.in.lm_cross = &hash6;
1475 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1476 if (NT_STATUS_IS_OK(status)) {
1478 *password = newpass;
1479 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1480 printf("ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status));
1485 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1487 E_md4hash(oldpass, old_nt_hash);
1488 E_md4hash(newpass, new_nt_hash);
1489 E_deshash(oldpass, old_lm_hash);
1490 E_deshash(newpass, new_lm_hash);
1493 /* Reset the hashes to not broken values */
1494 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1495 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1496 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1497 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1498 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1499 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1501 r.in.user_handle = &user_handle;
1502 r.in.lm_present = 1;
1503 r.in.old_lm_crypted = &hash1;
1504 r.in.new_lm_crypted = &hash2;
1505 r.in.nt_present = 1;
1506 r.in.old_nt_crypted = &hash3;
1507 r.in.new_nt_crypted = &hash4;
1508 r.in.cross1_present = 1;
1509 r.in.nt_cross = &hash5;
1510 r.in.cross2_present = 1;
1511 r.in.lm_cross = &hash6;
1513 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1514 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1515 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1516 } else if (!NT_STATUS_IS_OK(status)) {
1517 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1521 *password = newpass;
1524 r.in.user_handle = &user_handle;
1525 r.in.lm_present = 1;
1526 r.in.old_lm_crypted = &hash1;
1527 r.in.new_lm_crypted = &hash2;
1528 r.in.nt_present = 1;
1529 r.in.old_nt_crypted = &hash3;
1530 r.in.new_nt_crypted = &hash4;
1531 r.in.cross1_present = 1;
1532 r.in.nt_cross = &hash5;
1533 r.in.cross2_present = 1;
1534 r.in.lm_cross = &hash6;
1537 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1538 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1539 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1540 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1541 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status));
1547 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
1555 static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
1556 const char *acct_name,
1557 struct policy_handle *handle, char **password)
1560 struct samr_OemChangePasswordUser2 r;
1562 struct samr_Password lm_verifier;
1563 struct samr_CryptPassword lm_pass;
1564 struct lsa_AsciiString server, account, account_bad;
1567 uint8_t old_lm_hash[16], new_lm_hash[16];
1569 struct samr_GetDomPwInfo dom_pw_info;
1570 struct samr_PwInfo info;
1571 int policy_min_pw_len = 0;
1573 struct lsa_String domain_name;
1575 domain_name.string = "";
1576 dom_pw_info.in.domain_name = &domain_name;
1577 dom_pw_info.out.info = &info;
1579 torture_comment(tctx, "Testing OemChangePasswordUser2\n");
1581 torture_assert(tctx, *password != NULL,
1582 "Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?");
1584 oldpass = *password;
1586 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
1587 if (NT_STATUS_IS_OK(status)) {
1588 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
1591 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1593 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1594 account.string = acct_name;
1596 E_deshash(oldpass, old_lm_hash);
1597 E_deshash(newpass, new_lm_hash);
1599 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1600 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1601 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1603 r.in.server = &server;
1604 r.in.account = &account;
1605 r.in.password = &lm_pass;
1606 r.in.hash = &lm_verifier;
1608 /* Break the verification */
1609 lm_verifier.hash[0]++;
1611 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1613 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1614 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1615 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1620 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1621 /* Break the old password */
1623 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1624 /* unbreak it for the next operation */
1626 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1628 r.in.server = &server;
1629 r.in.account = &account;
1630 r.in.password = &lm_pass;
1631 r.in.hash = &lm_verifier;
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_WRONG_PASSWORD)) {
1637 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1642 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1643 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1645 r.in.server = &server;
1646 r.in.account = &account;
1647 r.in.password = &lm_pass;
1650 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1652 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1653 && !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1654 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
1659 /* This shouldn't be a valid name */
1660 account_bad.string = TEST_ACCOUNT_NAME "XX";
1661 r.in.account = &account_bad;
1663 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1665 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1666 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
1671 /* This shouldn't be a valid name */
1672 account_bad.string = TEST_ACCOUNT_NAME "XX";
1673 r.in.account = &account_bad;
1674 r.in.password = &lm_pass;
1675 r.in.hash = &lm_verifier;
1677 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1679 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1680 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1685 /* This shouldn't be a valid name */
1686 account_bad.string = TEST_ACCOUNT_NAME "XX";
1687 r.in.account = &account_bad;
1688 r.in.password = NULL;
1689 r.in.hash = &lm_verifier;
1691 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1693 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1694 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
1699 E_deshash(oldpass, old_lm_hash);
1700 E_deshash(newpass, new_lm_hash);
1702 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1703 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1704 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1706 r.in.server = &server;
1707 r.in.account = &account;
1708 r.in.password = &lm_pass;
1709 r.in.hash = &lm_verifier;
1711 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1712 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1713 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1714 } else if (!NT_STATUS_IS_OK(status)) {
1715 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
1718 *password = newpass;
1725 static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
1726 const char *acct_name,
1728 char *newpass, bool allow_password_restriction)
1731 struct samr_ChangePasswordUser2 r;
1733 struct lsa_String server, account;
1734 struct samr_CryptPassword nt_pass, lm_pass;
1735 struct samr_Password nt_verifier, lm_verifier;
1737 uint8_t old_nt_hash[16], new_nt_hash[16];
1738 uint8_t old_lm_hash[16], new_lm_hash[16];
1740 struct samr_GetDomPwInfo dom_pw_info;
1741 struct samr_PwInfo info;
1743 struct lsa_String domain_name;
1745 domain_name.string = "";
1746 dom_pw_info.in.domain_name = &domain_name;
1747 dom_pw_info.out.info = &info;
1749 torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name);
1751 torture_assert(tctx, *password != NULL,
1752 "Failing ChangePasswordUser2 as old password was NULL. Previous test failed?");
1753 oldpass = *password;
1756 int policy_min_pw_len = 0;
1757 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
1758 if (NT_STATUS_IS_OK(status)) {
1759 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
1762 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1765 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1766 init_lsa_String(&account, acct_name);
1768 E_md4hash(oldpass, old_nt_hash);
1769 E_md4hash(newpass, new_nt_hash);
1771 E_deshash(oldpass, old_lm_hash);
1772 E_deshash(newpass, new_lm_hash);
1774 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
1775 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1776 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1778 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1779 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1780 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1782 r.in.server = &server;
1783 r.in.account = &account;
1784 r.in.nt_password = &nt_pass;
1785 r.in.nt_verifier = &nt_verifier;
1787 r.in.lm_password = &lm_pass;
1788 r.in.lm_verifier = &lm_verifier;
1790 status = dcerpc_samr_ChangePasswordUser2(p, tctx, &r);
1791 if (allow_password_restriction && NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1792 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1793 } else if (!NT_STATUS_IS_OK(status)) {
1794 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
1797 *password = newpass;
1804 bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tctx,
1805 const char *account_string,
1806 int policy_min_pw_len,
1808 const char *newpass,
1809 NTTIME last_password_change,
1810 bool handle_reject_reason)
1813 struct samr_ChangePasswordUser3 r;
1815 struct lsa_String server, account, account_bad;
1816 struct samr_CryptPassword nt_pass, lm_pass;
1817 struct samr_Password nt_verifier, lm_verifier;
1819 uint8_t old_nt_hash[16], new_nt_hash[16];
1820 uint8_t old_lm_hash[16], new_lm_hash[16];
1822 struct samr_DomInfo1 *dominfo = NULL;
1823 struct samr_ChangeReject *reject = NULL;
1825 torture_comment(tctx, "Testing ChangePasswordUser3\n");
1827 if (newpass == NULL) {
1829 if (policy_min_pw_len == 0) {
1830 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1832 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len);
1834 } while (check_password_quality(newpass) == false);
1836 torture_comment(tctx, "Using password '%s'\n", newpass);
1839 torture_assert(tctx, *password != NULL,
1840 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
1842 oldpass = *password;
1843 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1844 init_lsa_String(&account, account_string);
1846 E_md4hash(oldpass, old_nt_hash);
1847 E_md4hash(newpass, new_nt_hash);
1849 E_deshash(oldpass, old_lm_hash);
1850 E_deshash(newpass, new_lm_hash);
1852 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1853 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1854 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1856 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1857 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1858 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1860 /* Break the verification */
1861 nt_verifier.hash[0]++;
1863 r.in.server = &server;
1864 r.in.account = &account;
1865 r.in.nt_password = &nt_pass;
1866 r.in.nt_verifier = &nt_verifier;
1868 r.in.lm_password = &lm_pass;
1869 r.in.lm_verifier = &lm_verifier;
1870 r.in.password3 = NULL;
1871 r.out.dominfo = &dominfo;
1872 r.out.reject = &reject;
1874 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1875 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1876 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1877 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1882 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1883 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1884 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1886 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1887 /* Break the NT hash */
1889 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1890 /* Unbreak it again */
1892 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1894 r.in.server = &server;
1895 r.in.account = &account;
1896 r.in.nt_password = &nt_pass;
1897 r.in.nt_verifier = &nt_verifier;
1899 r.in.lm_password = &lm_pass;
1900 r.in.lm_verifier = &lm_verifier;
1901 r.in.password3 = NULL;
1902 r.out.dominfo = &dominfo;
1903 r.out.reject = &reject;
1905 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1906 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1907 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1908 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1913 /* This shouldn't be a valid name */
1914 init_lsa_String(&account_bad, talloc_asprintf(tctx, "%sXX", account_string));
1916 r.in.account = &account_bad;
1917 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1918 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1919 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
1924 E_md4hash(oldpass, old_nt_hash);
1925 E_md4hash(newpass, new_nt_hash);
1927 E_deshash(oldpass, old_lm_hash);
1928 E_deshash(newpass, new_lm_hash);
1930 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1931 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1932 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1934 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1935 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1936 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1938 r.in.server = &server;
1939 r.in.account = &account;
1940 r.in.nt_password = &nt_pass;
1941 r.in.nt_verifier = &nt_verifier;
1943 r.in.lm_password = &lm_pass;
1944 r.in.lm_verifier = &lm_verifier;
1945 r.in.password3 = NULL;
1946 r.out.dominfo = &dominfo;
1947 r.out.reject = &reject;
1949 unix_to_nt_time(&t, time(NULL));
1951 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1953 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1956 && handle_reject_reason
1957 && (!null_nttime(last_password_change) || !dominfo->min_password_age)) {
1958 if (dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
1960 if (reject && (reject->reason != SAMR_REJECT_OTHER)) {
1961 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1962 SAMR_REJECT_OTHER, reject->reason);
1967 /* We tested the order of precendence which is as follows:
1976 if ((dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
1977 (last_password_change + dominfo->min_password_age > t)) {
1979 if (reject->reason != SAMR_REJECT_OTHER) {
1980 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1981 SAMR_REJECT_OTHER, reject->reason);
1985 } else if ((dominfo->min_password_length > 0) &&
1986 (strlen(newpass) < dominfo->min_password_length)) {
1988 if (reject->reason != SAMR_REJECT_TOO_SHORT) {
1989 printf("expected SAMR_REJECT_TOO_SHORT (%d), got %d\n",
1990 SAMR_REJECT_TOO_SHORT, reject->reason);
1994 } else if ((dominfo->password_history_length > 0) &&
1995 strequal(oldpass, newpass)) {
1997 if (reject->reason != SAMR_REJECT_IN_HISTORY) {
1998 printf("expected SAMR_REJECT_IN_HISTORY (%d), got %d\n",
1999 SAMR_REJECT_IN_HISTORY, reject->reason);
2002 } else if (dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
2004 if (reject->reason != SAMR_REJECT_COMPLEXITY) {
2005 printf("expected SAMR_REJECT_COMPLEXITY (%d), got %d\n",
2006 SAMR_REJECT_COMPLEXITY, reject->reason);
2012 if (reject->reason == SAMR_REJECT_TOO_SHORT) {
2013 /* retry with adjusted size */
2014 return test_ChangePasswordUser3(p, tctx, account_string,
2015 dominfo->min_password_length,
2016 password, NULL, 0, false);
2020 } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2021 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2022 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2023 SAMR_REJECT_OTHER, reject->reason);
2026 /* Perhaps the server has a 'min password age' set? */
2029 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3");
2030 *password = talloc_strdup(tctx, newpass);
2036 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_context *tctx,
2037 const char *account_string,
2038 struct policy_handle *handle,
2042 struct samr_ChangePasswordUser3 r;
2043 struct samr_SetUserInfo s;
2044 union samr_UserInfo u;
2045 DATA_BLOB session_key;
2046 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
2047 uint8_t confounder[16];
2048 struct MD5Context ctx;
2051 struct lsa_String server, account;
2052 struct samr_CryptPassword nt_pass;
2053 struct samr_Password nt_verifier;
2054 DATA_BLOB new_random_pass;
2057 uint8_t old_nt_hash[16], new_nt_hash[16];
2059 struct samr_DomInfo1 *dominfo = NULL;
2060 struct samr_ChangeReject *reject = NULL;
2062 new_random_pass = samr_very_rand_pass(tctx, 128);
2064 torture_assert(tctx, *password != NULL,
2065 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2067 oldpass = *password;
2068 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2069 init_lsa_String(&account, account_string);
2071 s.in.user_handle = handle;
2077 u.info25.info.fields_present = SAMR_FIELD_PASSWORD;
2079 set_pw_in_buffer(u.info25.password.data, &new_random_pass);
2081 status = dcerpc_fetch_session_key(p, &session_key);
2082 if (!NT_STATUS_IS_OK(status)) {
2083 printf("SetUserInfo level %u - no session key - %s\n",
2084 s.in.level, nt_errstr(status));
2088 generate_random_buffer((uint8_t *)confounder, 16);
2091 MD5Update(&ctx, confounder, 16);
2092 MD5Update(&ctx, session_key.data, session_key.length);
2093 MD5Final(confounded_session_key.data, &ctx);
2095 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
2096 memcpy(&u.info25.password.data[516], confounder, 16);
2098 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
2100 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
2101 if (!NT_STATUS_IS_OK(status)) {
2102 printf("SetUserInfo level %u failed - %s\n",
2103 s.in.level, nt_errstr(status));
2107 torture_comment(tctx, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
2109 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2111 new_random_pass = samr_very_rand_pass(tctx, 128);
2113 mdfour(new_nt_hash, new_random_pass.data, new_random_pass.length);
2115 set_pw_in_buffer(nt_pass.data, &new_random_pass);
2116 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2117 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2119 r.in.server = &server;
2120 r.in.account = &account;
2121 r.in.nt_password = &nt_pass;
2122 r.in.nt_verifier = &nt_verifier;
2124 r.in.lm_password = NULL;
2125 r.in.lm_verifier = NULL;
2126 r.in.password3 = NULL;
2127 r.out.dominfo = &dominfo;
2128 r.out.reject = &reject;
2130 unix_to_nt_time(&t, time(NULL));
2132 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2134 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2135 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2136 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2137 SAMR_REJECT_OTHER, reject->reason);
2140 /* Perhaps the server has a 'min password age' set? */
2142 } else if (!NT_STATUS_IS_OK(status)) {
2143 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
2147 newpass = samr_rand_pass(tctx, 128);
2149 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2151 E_md4hash(newpass, new_nt_hash);
2153 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2154 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2155 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2157 r.in.server = &server;
2158 r.in.account = &account;
2159 r.in.nt_password = &nt_pass;
2160 r.in.nt_verifier = &nt_verifier;
2162 r.in.lm_password = NULL;
2163 r.in.lm_verifier = NULL;
2164 r.in.password3 = NULL;
2165 r.out.dominfo = &dominfo;
2166 r.out.reject = &reject;
2168 unix_to_nt_time(&t, time(NULL));
2170 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2172 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2173 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2174 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2175 SAMR_REJECT_OTHER, reject->reason);
2178 /* Perhaps the server has a 'min password age' set? */
2181 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3 (on second random password)");
2182 *password = talloc_strdup(tctx, newpass);
2189 static bool test_GetMembersInAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2190 struct policy_handle *alias_handle)
2192 struct samr_GetMembersInAlias r;
2193 struct lsa_SidArray sids;
2196 torture_comment(tctx, "Testing GetMembersInAlias\n");
2198 r.in.alias_handle = alias_handle;
2201 status = dcerpc_samr_GetMembersInAlias(p, tctx, &r);
2202 torture_assert_ntstatus_ok(tctx, status, "GetMembersInAlias");
2207 static bool test_AddMemberToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2208 struct policy_handle *alias_handle,
2209 const struct dom_sid *domain_sid)
2211 struct samr_AddAliasMember r;
2212 struct samr_DeleteAliasMember d;
2214 struct dom_sid *sid;
2216 sid = dom_sid_add_rid(tctx, domain_sid, 512);
2218 torture_comment(tctx, "testing AddAliasMember\n");
2219 r.in.alias_handle = alias_handle;
2222 status = dcerpc_samr_AddAliasMember(p, tctx, &r);
2223 torture_assert_ntstatus_ok(tctx, status, "AddAliasMember");
2225 d.in.alias_handle = alias_handle;
2228 status = dcerpc_samr_DeleteAliasMember(p, tctx, &d);
2229 torture_assert_ntstatus_ok(tctx, status, "DelAliasMember");
2234 static bool test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2235 struct policy_handle *alias_handle)
2237 struct samr_AddMultipleMembersToAlias a;
2238 struct samr_RemoveMultipleMembersFromAlias r;
2240 struct lsa_SidArray sids;
2242 torture_comment(tctx, "testing AddMultipleMembersToAlias\n");
2243 a.in.alias_handle = alias_handle;
2247 sids.sids = talloc_array(tctx, struct lsa_SidPtr, 3);
2249 sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2250 sids.sids[1].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-2");
2251 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-3");
2253 status = dcerpc_samr_AddMultipleMembersToAlias(p, tctx, &a);
2254 torture_assert_ntstatus_ok(tctx, status, "AddMultipleMembersToAlias");
2257 torture_comment(tctx, "testing RemoveMultipleMembersFromAlias\n");
2258 r.in.alias_handle = alias_handle;
2261 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2262 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2264 /* strange! removing twice doesn't give any error */
2265 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2266 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2268 /* but removing an alias that isn't there does */
2269 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-4");
2271 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2272 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, "RemoveMultipleMembersFromAlias");
2277 static bool test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2278 struct policy_handle *user_handle)
2280 struct samr_TestPrivateFunctionsUser r;
2283 torture_comment(tctx, "Testing TestPrivateFunctionsUser\n");
2285 r.in.user_handle = user_handle;
2287 status = dcerpc_samr_TestPrivateFunctionsUser(p, tctx, &r);
2288 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsUser");
2293 static bool test_QueryUserInfo_pwdlastset(struct dcerpc_pipe *p,
2294 struct torture_context *tctx,
2295 struct policy_handle *handle,
2300 uint16_t levels[] = { /* 3, */ 5, 21 };
2302 NTTIME pwdlastset3 = 0;
2303 NTTIME pwdlastset5 = 0;
2304 NTTIME pwdlastset21 = 0;
2306 torture_comment(tctx, "Testing QueryUserInfo%s level 5 and 21 call ",
2307 use_info2 ? "2":"");
2309 for (i=0; i<ARRAY_SIZE(levels); i++) {
2311 struct samr_QueryUserInfo r;
2312 struct samr_QueryUserInfo2 r2;
2313 union samr_UserInfo *info;
2316 r2.in.user_handle = handle;
2317 r2.in.level = levels[i];
2318 r2.out.info = &info;
2319 status = dcerpc_samr_QueryUserInfo2(p, tctx, &r2);
2322 r.in.user_handle = handle;
2323 r.in.level = levels[i];
2325 status = dcerpc_samr_QueryUserInfo(p, tctx, &r);
2328 if (!NT_STATUS_IS_OK(status) &&
2329 !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
2330 printf("QueryUserInfo%s level %u failed - %s\n",
2331 use_info2 ? "2":"", levels[i], nt_errstr(status));
2335 switch (levels[i]) {
2337 pwdlastset3 = info->info3.last_password_change;
2340 pwdlastset5 = info->info5.last_password_change;
2343 pwdlastset21 = info->info21.last_password_change;
2349 /* torture_assert_int_equal(tctx, pwdlastset3, pwdlastset5,
2350 "pwdlastset mixup"); */
2351 torture_assert_int_equal(tctx, pwdlastset5, pwdlastset21,
2352 "pwdlastset mixup");
2354 *pwdlastset = pwdlastset21;
2356 torture_comment(tctx, "(pwdlastset: %lld)\n", *pwdlastset);
2361 static bool test_SetPassword_level(struct dcerpc_pipe *p,
2362 struct torture_context *tctx,
2363 struct policy_handle *handle,
2365 uint32_t fields_present,
2366 uint8_t password_expired,
2367 NTSTATUS expected_error,
2370 bool use_queryinfo2,
2373 const char *fields = NULL;
2380 fields = talloc_asprintf(tctx, "(fields_present: 0x%08x)",
2387 torture_comment(tctx, "Testing SetUserInfo%s level %d call "
2388 "(password_expired: %d) %s\n",
2389 use_setinfo2 ? "2":"", level, password_expired,
2390 fields ? fields : "");
2398 if (!test_SetUserPass_level_ex(p, tctx, handle, level,
2411 if (!test_QueryUserInfo_pwdlastset(p, tctx, handle,
2420 static bool test_SetPassword_pwdlastset(struct dcerpc_pipe *p,
2421 struct torture_context *tctx,
2422 uint32_t acct_flags,
2423 struct policy_handle *handle,
2426 int i, s = 0, q = 0;
2429 bool set_levels[] = { false, true };
2430 bool query_levels[] = { false, true };
2434 uint8_t password_expired_nonzero;
2435 uint32_t fields_present;
2444 .password_expired_nonzero = 1,
2445 .fields_present = SAMR_FIELD_EXPIRED_FLAG
2448 .password_expired_nonzero = 1,
2449 .fields_present = SAMR_FIELD_LAST_PWD_CHANGE,
2450 .set_error = NT_STATUS_ACCESS_DENIED
2453 .password_expired_nonzero = 1,
2454 .fields_present = 0,
2455 .set_error = NT_STATUS_INVALID_PARAMETER
2458 .password_expired_nonzero = 1,
2459 .fields_present = SAMR_FIELD_COMMENT,
2465 .password_expired_nonzero = 1,
2466 .fields_present = SAMR_FIELD_PASSWORD |
2467 SAMR_FIELD_PASSWORD2 |
2468 SAMR_FIELD_LAST_PWD_CHANGE,
2469 .query_info2 = false,
2470 .set_error = NT_STATUS_ACCESS_DENIED
2476 .password_expired_nonzero = 1,
2477 .fields_present = SAMR_FIELD_EXPIRED_FLAG
2480 .password_expired_nonzero = 1,
2481 .fields_present = SAMR_FIELD_LAST_PWD_CHANGE,
2482 .set_error = NT_STATUS_ACCESS_DENIED
2485 .password_expired_nonzero = 1,
2486 .fields_present = SAMR_FIELD_LAST_PWD_CHANGE |
2487 SAMR_FIELD_PASSWORD |
2488 SAMR_FIELD_PASSWORD2,
2489 .set_error = NT_STATUS_ACCESS_DENIED
2492 .password_expired_nonzero = 1,
2493 .fields_present = SAMR_FIELD_LAST_PWD_CHANGE |
2494 SAMR_FIELD_PASSWORD |
2495 SAMR_FIELD_PASSWORD2 |
2496 SAMR_FIELD_EXPIRED_FLAG,
2497 .set_error = NT_STATUS_ACCESS_DENIED
2500 .password_expired_nonzero = 1,
2501 .fields_present = SAMR_FIELD_PASSWORD |
2502 SAMR_FIELD_PASSWORD2 |
2503 SAMR_FIELD_EXPIRED_FLAG
2506 .password_expired_nonzero = 1,
2507 .fields_present = SAMR_FIELD_PASSWORD |
2508 SAMR_FIELD_PASSWORD2,
2511 .password_expired_nonzero = 1,
2512 .fields_present = SAMR_FIELD_COMMENT,
2515 .password_expired_nonzero = 1,
2516 .fields_present = 0,
2517 .set_error = NT_STATUS_INVALID_PARAMETER
2523 .password_expired_nonzero = 1
2526 .password_expired_nonzero = 24
2532 .password_expired_nonzero = 1,
2533 .fields_present = SAMR_FIELD_LAST_PWD_CHANGE,
2534 .set_error = NT_STATUS_ACCESS_DENIED
2537 .password_expired_nonzero = 1,
2538 .fields_present = SAMR_FIELD_EXPIRED_FLAG,
2541 .password_expired_nonzero = 1,
2542 .fields_present = SAMR_FIELD_PASSWORD |
2543 SAMR_FIELD_PASSWORD2 |
2544 SAMR_FIELD_EXPIRED_FLAG
2547 .password_expired_nonzero = 1,
2548 .fields_present = SAMR_FIELD_PASSWORD |
2549 SAMR_FIELD_PASSWORD2,
2552 .password_expired_nonzero = 1,
2553 .fields_present = SAMR_FIELD_COMMENT,
2559 .password_expired_nonzero = 1
2562 .password_expired_nonzero = 24
2566 if (torture_setting_bool(tctx, "samba3", false)) {
2568 printf("Samba3 has second granularity, setting delay to: %d\n",
2572 /* set to 1 to enable testing for all possible opcode
2573 (SetUserInfo, SetUserInfo2, QueryUserInfo, QueryUserInfo2)
2576 #define TEST_SET_LEVELS 1
2577 #define TEST_QUERY_LEVELS 1
2579 for (i=0; i<ARRAY_SIZE(pwd_tests); i++) {
2580 #ifdef TEST_SET_LEVELS
2581 for (s=0; s<ARRAY_SIZE(set_levels); s++) {
2583 #ifdef TEST_QUERY_LEVELS
2584 for (q=0; q<ARRAY_SIZE(query_levels); q++) {
2586 NTTIME pwdlastset_old = 0;
2587 NTTIME pwdlastset_new = 0;
2589 torture_comment(tctx, "------------------------------\n"
2590 "Testing pwdLastSet attribute for flags: 0x%08x "
2591 "(s: %d (l: %d), q: %d)\n",
2592 acct_flags, s, pwd_tests[i].level, q);
2596 /* set a password and force password change (pwdlastset 0) by
2597 * setting the password expired flag to a non-0 value */
2599 if (!test_SetPassword_level(p, tctx, handle,
2601 pwd_tests[i].fields_present,
2602 pwd_tests[i].password_expired_nonzero,
2603 pwd_tests[i].set_error,
2611 if (!NT_STATUS_IS_OK(pwd_tests[i].set_error)) {
2612 /* skipping on expected failure */
2616 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
2617 * set without the SAMR_FIELD_EXPIRED_FLAG */
2619 switch (pwd_tests[i].level) {
2623 if ((pwdlastset_new != 0) &&
2624 !(pwd_tests[i].fields_present & SAMR_FIELD_EXPIRED_FLAG)) {
2625 torture_comment(tctx, "not considering a non-0 "
2626 "pwdLastSet as a an error as the "
2627 "SAMR_FIELD_EXPIRED_FLAG has not "
2632 if (pwdlastset_new != 0) {
2633 torture_warning(tctx, "pwdLastSet test failed: "
2634 "expected pwdLastSet 0 but got %lld\n",
2645 /* set a password, pwdlastset needs to get updated (increased
2646 * value), password_expired value used here is 0 */
2648 if (!test_SetPassword_level(p, tctx, handle, pwd_tests[i].level,
2649 pwd_tests[i].fields_present,
2651 pwd_tests[i].set_error,
2660 /* when a password has been changed, pwdlastset must not be 0 afterwards
2661 * and must be larger then the old value */
2663 switch (pwd_tests[i].level) {
2668 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
2669 * password has been changed, old and new pwdlastset
2670 * need to be the same value */
2672 if (!(pwd_tests[i].fields_present & SAMR_FIELD_EXPIRED_FLAG) &&
2673 !((pwd_tests[i].fields_present & SAMR_FIELD_PASSWORD) ||
2674 (pwd_tests[i].fields_present & SAMR_FIELD_PASSWORD2)))
2676 torture_assert_int_equal(tctx, pwdlastset_old,
2677 pwdlastset_new, "pwdlastset must be equal");
2681 if (pwdlastset_old >= pwdlastset_new) {
2682 torture_warning(tctx, "pwdLastSet test failed: "
2683 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
2684 pwdlastset_old, pwdlastset_new);
2687 if (pwdlastset_new == 0) {
2688 torture_warning(tctx, "pwdLastSet test failed: "
2689 "expected non-0 pwdlastset, got: %lld\n",
2695 pwdlastset_old = pwdlastset_new;
2701 /* set a password and force password change (pwdlastset 0) by
2702 * setting the password expired flag to a non-0 value */
2704 if (!test_SetPassword_level(p, tctx, handle, pwd_tests[i].level,
2705 pwd_tests[i].fields_present,
2706 pwd_tests[i].password_expired_nonzero,
2707 pwd_tests[i].set_error,
2715 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
2716 * set without the SAMR_FIELD_EXPIRED_FLAG */
2718 switch (pwd_tests[i].level) {
2722 if ((pwdlastset_new != 0) &&
2723 !(pwd_tests[i].fields_present & SAMR_FIELD_EXPIRED_FLAG)) {
2724 torture_comment(tctx, "not considering a non-0 "
2725 "pwdLastSet as a an error as the "
2726 "SAMR_FIELD_EXPIRED_FLAG has not "
2731 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
2732 * password has been changed, old and new pwdlastset
2733 * need to be the same value */
2735 if (!(pwd_tests[i].fields_present & SAMR_FIELD_EXPIRED_FLAG) &&
2736 !((pwd_tests[i].fields_present & SAMR_FIELD_PASSWORD) ||
2737 (pwd_tests[i].fields_present & SAMR_FIELD_PASSWORD2)))
2739 torture_assert_int_equal(tctx, pwdlastset_old,
2740 pwdlastset_new, "pwdlastset must be equal");
2745 if (pwdlastset_old == pwdlastset_new) {
2746 torture_warning(tctx, "pwdLastSet test failed: "
2747 "expected last pwdlastset (%lld) != new pwdlastset (%lld)\n",
2748 pwdlastset_old, pwdlastset_new);
2752 if (pwdlastset_new != 0) {
2753 torture_warning(tctx, "pwdLastSet test failed: "
2754 "expected pwdLastSet 0, got %lld\n",
2760 #ifdef TEST_QUERY_LEVELS
2763 #ifdef TEST_SET_LEVELS
2768 #undef TEST_SET_LEVELS
2769 #undef TEST_QUERY_LEVELS
2774 static bool test_user_ops(struct dcerpc_pipe *p,
2775 struct torture_context *tctx,
2776 struct policy_handle *user_handle,
2777 struct policy_handle *domain_handle,
2778 uint32_t base_acct_flags,
2779 const char *base_acct_name, enum torture_samr_choice which_ops)
2781 char *password = NULL;
2782 struct samr_QueryUserInfo q;
2783 union samr_UserInfo *info;
2789 const uint32_t password_fields[] = {
2790 SAMR_FIELD_PASSWORD,
2791 SAMR_FIELD_PASSWORD2,
2792 SAMR_FIELD_PASSWORD | SAMR_FIELD_PASSWORD2,
2796 status = test_LookupName(p, tctx, domain_handle, base_acct_name, &rid);
2797 if (!NT_STATUS_IS_OK(status)) {
2801 switch (which_ops) {
2802 case TORTURE_SAMR_USER_ATTRIBUTES:
2803 if (!test_QuerySecurity(p, tctx, user_handle)) {
2807 if (!test_QueryUserInfo(p, tctx, user_handle)) {
2811 if (!test_QueryUserInfo2(p, tctx, user_handle)) {
2815 if (!test_SetUserInfo(p, tctx, user_handle, base_acct_flags,
2820 if (!test_GetUserPwInfo(p, tctx, user_handle)) {
2824 if (!test_TestPrivateFunctionsUser(p, tctx, user_handle)) {
2828 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
2832 case TORTURE_SAMR_PASSWORDS:
2833 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
2834 char simple_pass[9];
2835 char *v = generate_random_str(tctx, 1);
2837 ZERO_STRUCT(simple_pass);
2838 memset(simple_pass, *v, sizeof(simple_pass) - 1);
2840 printf("Testing machine account password policy rules\n");
2842 /* Workstation trust accounts don't seem to need to honour password quality policy */
2843 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
2847 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
2851 /* reset again, to allow another 'user' password change */
2852 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
2856 /* Try a 'short' password */
2857 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
2861 /* Try a compleatly random password */
2862 if (!test_ChangePasswordRandomBytes(p, tctx, base_acct_name, user_handle, &password)) {
2867 for (i = 0; password_fields[i]; i++) {
2868 if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
2872 /* check it was set right */
2873 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
2878 for (i = 0; password_fields[i]; i++) {
2879 if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
2883 /* check it was set right */
2884 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
2889 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
2893 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
2897 q.in.user_handle = user_handle;
2901 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
2902 if (!NT_STATUS_IS_OK(status)) {
2903 printf("QueryUserInfo level %u failed - %s\n",
2904 q.in.level, nt_errstr(status));
2907 uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
2908 if ((info->info5.acct_flags) != expected_flags) {
2909 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2910 info->info5.acct_flags,
2914 if (info->info5.rid != rid) {
2915 printf("QuerUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
2916 info->info5.rid, rid);
2923 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
2925 /* test last password change timestamp behaviour */
2926 if (!test_SetPassword_pwdlastset(p, tctx, base_acct_flags,
2927 user_handle, &password)) {
2932 torture_comment(tctx, "pwdLastSet test succeeded\n");
2934 torture_warning(tctx, "pwdLastSet test failed\n");
2939 case TORTURE_SAMR_OTHER:
2940 /* We just need the account to exist */
2946 static bool test_alias_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
2947 struct policy_handle *alias_handle,
2948 const struct dom_sid *domain_sid)
2952 if (!test_QuerySecurity(p, tctx, alias_handle)) {
2956 if (!test_QueryAliasInfo(p, tctx, alias_handle)) {
2960 if (!test_SetAliasInfo(p, tctx, alias_handle)) {
2964 if (!test_AddMemberToAlias(p, tctx, alias_handle, domain_sid)) {
2968 if (torture_setting_bool(tctx, "samba4", false)) {
2969 printf("skipping MultipleMembers Alias tests against Samba4\n");
2973 if (!test_AddMultipleMembersToAlias(p, tctx, alias_handle)) {
2981 static bool test_DeleteUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2982 struct policy_handle *user_handle)
2984 struct samr_DeleteUser d;
2986 torture_comment(tctx, "Testing DeleteUser\n");
2988 d.in.user_handle = user_handle;
2989 d.out.user_handle = user_handle;
2991 status = dcerpc_samr_DeleteUser(p, tctx, &d);
2992 torture_assert_ntstatus_ok(tctx, status, "DeleteUser");
2997 bool test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2998 struct policy_handle *handle, const char *name)
3001 struct samr_DeleteUser d;
3002 struct policy_handle user_handle;
3005 status = test_LookupName(p, mem_ctx, handle, name, &rid);
3006 if (!NT_STATUS_IS_OK(status)) {
3010 status = test_OpenUser_byname(p, mem_ctx, handle, name, &user_handle);
3011 if (!NT_STATUS_IS_OK(status)) {
3015 d.in.user_handle = &user_handle;
3016 d.out.user_handle = &user_handle;
3017 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
3018 if (!NT_STATUS_IS_OK(status)) {
3025 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
3030 static bool test_DeleteGroup_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3031 struct policy_handle *handle, const char *name)
3034 struct samr_OpenGroup r;
3035 struct samr_DeleteDomainGroup d;
3036 struct policy_handle group_handle;
3039 status = test_LookupName(p, mem_ctx, handle, name, &rid);
3040 if (!NT_STATUS_IS_OK(status)) {
3044 r.in.domain_handle = handle;
3045 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3047 r.out.group_handle = &group_handle;
3048 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
3049 if (!NT_STATUS_IS_OK(status)) {
3053 d.in.group_handle = &group_handle;
3054 d.out.group_handle = &group_handle;
3055 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
3056 if (!NT_STATUS_IS_OK(status)) {
3063 printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
3068 static bool test_DeleteAlias_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3069 struct policy_handle *domain_handle, const char *name)
3072 struct samr_OpenAlias r;
3073 struct samr_DeleteDomAlias d;
3074 struct policy_handle alias_handle;
3077 printf("testing DeleteAlias_byname\n");
3079 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
3080 if (!NT_STATUS_IS_OK(status)) {
3084 r.in.domain_handle = domain_handle;
3085 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3087 r.out.alias_handle = &alias_handle;
3088 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
3089 if (!NT_STATUS_IS_OK(status)) {
3093 d.in.alias_handle = &alias_handle;
3094 d.out.alias_handle = &alias_handle;
3095 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
3096 if (!NT_STATUS_IS_OK(status)) {
3103 printf("DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
3107 static bool test_DeleteAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3108 struct policy_handle *alias_handle)
3110 struct samr_DeleteDomAlias d;
3113 printf("Testing DeleteAlias\n");
3115 d.in.alias_handle = alias_handle;
3116 d.out.alias_handle = alias_handle;
3118 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
3119 if (!NT_STATUS_IS_OK(status)) {
3120 printf("DeleteAlias failed - %s\n", nt_errstr(status));
3127 static bool test_CreateAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
3128 struct policy_handle *domain_handle,
3129 struct policy_handle *alias_handle,
3130 const struct dom_sid *domain_sid)
3133 struct samr_CreateDomAlias r;
3134 struct lsa_String name;
3138 init_lsa_String(&name, TEST_ALIASNAME);
3139 r.in.domain_handle = domain_handle;
3140 r.in.alias_name = &name;
3141 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3142 r.out.alias_handle = alias_handle;
3145 printf("Testing CreateAlias (%s)\n", r.in.alias_name->string);
3147 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
3149 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
3150 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
3151 printf("Server correctly refused create of '%s'\n", r.in.alias_name->string);
3154 printf("Server should have refused create of '%s', got %s instead\n", r.in.alias_name->string,
3160 if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
3161 if (!test_DeleteAlias_byname(p, tctx, domain_handle, r.in.alias_name->string)) {
3164 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
3167 if (!NT_STATUS_IS_OK(status)) {
3168 printf("CreateAlias failed - %s\n", nt_errstr(status));
3172 if (!test_alias_ops(p, tctx, alias_handle, domain_sid)) {
3179 static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3180 const char *acct_name,
3181 struct policy_handle *domain_handle, char **password)
3189 if (!test_ChangePasswordUser(p, mem_ctx, acct_name, domain_handle, password)) {
3193 if (!test_ChangePasswordUser2(p, mem_ctx, acct_name, password, 0, true)) {
3197 if (!test_OemChangePasswordUser2(p, mem_ctx, acct_name, domain_handle, password)) {
3201 /* test what happens when setting the old password again */
3202 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, *password, 0, true)) {
3207 char simple_pass[9];
3208 char *v = generate_random_str(mem_ctx, 1);
3210 ZERO_STRUCT(simple_pass);
3211 memset(simple_pass, *v, sizeof(simple_pass) - 1);
3213 /* test what happens when picking a simple password */
3214 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, simple_pass, 0, true)) {
3219 /* set samr_SetDomainInfo level 1 with min_length 5 */
3221 struct samr_QueryDomainInfo r;
3222 union samr_DomainInfo *info = NULL;
3223 struct samr_SetDomainInfo s;
3224 uint16_t len_old, len;
3225 uint32_t pwd_prop_old;
3226 int64_t min_pwd_age_old;
3231 r.in.domain_handle = domain_handle;
3235 printf("testing samr_QueryDomainInfo level 1\n");
3236 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
3237 if (!NT_STATUS_IS_OK(status)) {
3241 s.in.domain_handle = domain_handle;
3245 /* remember the old min length, so we can reset it */
3246 len_old = s.in.info->info1.min_password_length;
3247 s.in.info->info1.min_password_length = len;
3248 pwd_prop_old = s.in.info->info1.password_properties;
3249 /* turn off password complexity checks for this test */
3250 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
3252 min_pwd_age_old = s.in.info->info1.min_password_age;
3253 s.in.info->info1.min_password_age = 0;
3255 printf("testing samr_SetDomainInfo level 1\n");
3256 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
3257 if (!NT_STATUS_IS_OK(status)) {
3261 printf("calling test_ChangePasswordUser3 with too short password\n");
3263 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, len - 1, password, NULL, 0, true)) {
3267 s.in.info->info1.min_password_length = len_old;
3268 s.in.info->info1.password_properties = pwd_prop_old;
3269 s.in.info->info1.min_password_age = min_pwd_age_old;
3271 printf("testing samr_SetDomainInfo level 1\n");
3272 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
3273 if (!NT_STATUS_IS_OK(status)) {
3281 struct samr_OpenUser r;
3282 struct samr_QueryUserInfo q;
3283 union samr_UserInfo *info;
3284 struct samr_LookupNames n;
3285 struct policy_handle user_handle;
3286 struct samr_Ids rids, types;
3288 n.in.domain_handle = domain_handle;
3290 n.in.names = talloc_array(mem_ctx, struct lsa_String, 1);
3291 n.in.names[0].string = acct_name;
3293 n.out.types = &types;
3295 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
3296 if (!NT_STATUS_IS_OK(status)) {
3297 printf("LookupNames failed - %s\n", nt_errstr(status));
3301 r.in.domain_handle = domain_handle;
3302 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3303 r.in.rid = n.out.rids->ids[0];
3304 r.out.user_handle = &user_handle;
3306 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3307 if (!NT_STATUS_IS_OK(status)) {
3308 printf("OpenUser(%u) failed - %s\n", n.out.rids->ids[0], nt_errstr(status));
3312 q.in.user_handle = &user_handle;
3316 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
3317 if (!NT_STATUS_IS_OK(status)) {
3318 printf("QueryUserInfo failed - %s\n", nt_errstr(status));
3322 printf("calling test_ChangePasswordUser3 with too early password change\n");
3324 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL,
3325 info->info5.last_password_change, true)) {
3330 /* we change passwords twice - this has the effect of verifying
3331 they were changed correctly for the final call */
3332 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, true)) {
3336 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, true)) {
3343 static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
3344 struct policy_handle *domain_handle,
3345 struct policy_handle *user_handle_out,
3346 struct dom_sid *domain_sid,
3347 enum torture_samr_choice which_ops)
3350 TALLOC_CTX *user_ctx;
3353 struct samr_CreateUser r;
3354 struct samr_QueryUserInfo q;
3355 union samr_UserInfo *info;
3356 struct samr_DeleteUser d;
3359 /* This call creates a 'normal' account - check that it really does */
3360 const uint32_t acct_flags = ACB_NORMAL;
3361 struct lsa_String name;
3364 struct policy_handle user_handle;
3365 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
3366 init_lsa_String(&name, TEST_ACCOUNT_NAME);
3368 r.in.domain_handle = domain_handle;
3369 r.in.account_name = &name;
3370 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3371 r.out.user_handle = &user_handle;
3374 printf("Testing CreateUser(%s)\n", r.in.account_name->string);
3376 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
3378 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
3379 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
3380 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
3383 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
3389 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
3390 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
3391 talloc_free(user_ctx);
3394 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
3396 if (!NT_STATUS_IS_OK(status)) {
3397 talloc_free(user_ctx);
3398 printf("CreateUser failed - %s\n", nt_errstr(status));
3401 q.in.user_handle = &user_handle;
3405 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
3406 if (!NT_STATUS_IS_OK(status)) {
3407 printf("QueryUserInfo level %u failed - %s\n",
3408 q.in.level, nt_errstr(status));
3411 if ((info->info16.acct_flags & acct_flags) != acct_flags) {
3412 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
3413 info->info16.acct_flags,
3419 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
3420 acct_flags, name.string, which_ops)) {
3424 if (user_handle_out) {
3425 *user_handle_out = user_handle;
3427 printf("Testing DeleteUser (createuser test)\n");
3429 d.in.user_handle = &user_handle;
3430 d.out.user_handle = &user_handle;
3432 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
3433 if (!NT_STATUS_IS_OK(status)) {
3434 printf("DeleteUser failed - %s\n", nt_errstr(status));
3441 talloc_free(user_ctx);
3447 static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
3448 struct policy_handle *domain_handle,
3449 struct dom_sid *domain_sid,
3450 enum torture_samr_choice which_ops)
3453 struct samr_CreateUser2 r;
3454 struct samr_QueryUserInfo q;
3455 union samr_UserInfo *info;
3456 struct samr_DeleteUser d;
3457 struct policy_handle user_handle;
3459 struct lsa_String name;
3464 uint32_t acct_flags;
3465 const char *account_name;
3467 } account_types[] = {
3468 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
3469 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
3470 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
3471 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
3472 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
3473 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
3474 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
3475 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
3476 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
3477 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
3478 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
3479 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
3480 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
3481 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
3482 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
3485 for (i = 0; account_types[i].account_name; i++) {
3486 TALLOC_CTX *user_ctx;
3487 uint32_t acct_flags = account_types[i].acct_flags;
3488 uint32_t access_granted;
3489 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
3490 init_lsa_String(&name, account_types[i].account_name);
3492 r.in.domain_handle = domain_handle;
3493 r.in.account_name = &name;
3494 r.in.acct_flags = acct_flags;
3495 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3496 r.out.user_handle = &user_handle;
3497 r.out.access_granted = &access_granted;
3500 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
3502 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
3504 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
3505 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
3506 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
3509 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
3516 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
3517 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
3518 talloc_free(user_ctx);
3522 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
3525 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
3526 printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
3527 nt_errstr(status), nt_errstr(account_types[i].nt_status));
3531 if (NT_STATUS_IS_OK(status)) {
3532 q.in.user_handle = &user_handle;
3536 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
3537 if (!NT_STATUS_IS_OK(status)) {
3538 printf("QueryUserInfo level %u failed - %s\n",
3539 q.in.level, nt_errstr(status));
3542 uint32_t expected_flags = (acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
3543 if (acct_flags == ACB_NORMAL) {
3544 expected_flags |= ACB_PW_EXPIRED;
3546 if ((info->info5.acct_flags) != expected_flags) {
3547 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
3548 info->info5.acct_flags,
3552 switch (acct_flags) {
3554 if (info->info5.primary_gid != DOMAIN_RID_DCS) {
3555 printf("QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n",
3556 DOMAIN_RID_DCS, info->info5.primary_gid);
3561 if (info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
3562 printf("QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
3563 DOMAIN_RID_DOMAIN_MEMBERS, info->info5.primary_gid);
3568 if (info->info5.primary_gid != DOMAIN_RID_USERS) {
3569 printf("QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n",
3570 DOMAIN_RID_USERS, info->info5.primary_gid);
3577 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
3578 acct_flags, name.string, which_ops)) {
3582 printf("Testing DeleteUser (createuser2 test)\n");
3584 d.in.user_handle = &user_handle;
3585 d.out.user_handle = &user_handle;
3587 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
3588 if (!NT_STATUS_IS_OK(status)) {
3589 printf("DeleteUser failed - %s\n", nt_errstr(status));
3593 talloc_free(user_ctx);
3599 static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3600 struct policy_handle *handle)
3603 struct samr_QueryAliasInfo r;
3604 union samr_AliasInfo *info;
3605 uint16_t levels[] = {1, 2, 3};
3609 for (i=0;i<ARRAY_SIZE(levels);i++) {
3610 printf("Testing QueryAliasInfo level %u\n", levels[i]);
3612 r.in.alias_handle = handle;
3613 r.in.level = levels[i];
3616 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
3617 if (!NT_STATUS_IS_OK(status)) {
3618 printf("QueryAliasInfo level %u failed - %s\n",
3619 levels[i], nt_errstr(status));
3627 static bool test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3628 struct policy_handle *handle)
3631 struct samr_QueryGroupInfo r;
3632 union samr_GroupInfo *info;
3633 uint16_t levels[] = {1, 2, 3, 4, 5};
3637 for (i=0;i<ARRAY_SIZE(levels);i++) {
3638 printf("Testing QueryGroupInfo level %u\n", levels[i]);
3640 r.in.group_handle = handle;
3641 r.in.level = levels[i];
3644 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
3645 if (!NT_STATUS_IS_OK(status)) {
3646 printf("QueryGroupInfo level %u failed - %s\n",
3647 levels[i], nt_errstr(status));
3655 static bool test_QueryGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3656 struct policy_handle *handle)
3659 struct samr_QueryGroupMember r;
3660 struct samr_RidTypeArray *rids = NULL;
3663 printf("Testing QueryGroupMember\n");
3665 r.in.group_handle = handle;
3668 status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &r);
3669 if (!NT_STATUS_IS_OK(status)) {
3670 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
3678 static bool test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3679 struct policy_handle *handle)
3682 struct samr_QueryGroupInfo r;
3683 union samr_GroupInfo *info;
3684 struct samr_SetGroupInfo s;
3685 uint16_t levels[] = {1, 2, 3, 4};
3686 uint16_t set_ok[] = {0, 1, 1, 1};
3690 for (i=0;i<ARRAY_SIZE(levels);i++) {
3691 printf("Testing QueryGroupInfo level %u\n", levels[i]);
3693 r.in.group_handle = handle;
3694 r.in.level = levels[i];
3697 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
3698 if (!NT_STATUS_IS_OK(status)) {
3699 printf("QueryGroupInfo level %u failed - %s\n",
3700 levels[i], nt_errstr(status));
3704 printf("Testing SetGroupInfo level %u\n", levels[i]);
3706 s.in.group_handle = handle;
3707 s.in.level = levels[i];
3708 s.in.info = *r.out.info;
3711 /* disabled this, as it changes the name only from the point of view of samr,
3712 but leaves the name from the point of view of w2k3 internals (and ldap). This means
3713 the name is still reserved, so creating the old name fails, but deleting by the old name
3715 if (s.in.level == 2) {
3716 init_lsa_String(&s.in.info->string, "NewName");
3720 if (s.in.level == 4) {
3721 init_lsa_String(&s.in.info->description, "test description");
3724 status = dcerpc_samr_SetGroupInfo(p, mem_ctx, &s);
3726 if (!NT_STATUS_IS_OK(status)) {
3727 printf("SetGroupInfo level %u failed - %s\n",
3728 r.in.level, nt_errstr(status));
3733 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
3734 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
3735 r.in.level, nt_errstr(status));
3745 static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3746 struct policy_handle *handle)
3749 struct samr_QueryUserInfo r;
3750 union samr_UserInfo *info;
3751 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
3752 11, 12, 13, 14, 16, 17, 20, 21};
3756 for (i=0;i<ARRAY_SIZE(levels);i++) {
3757 printf("Testing QueryUserInfo level %u\n", levels[i]);
3759 r.in.user_handle = handle;
3760 r.in.level = levels[i];
3763 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
3764 if (!NT_STATUS_IS_OK(status)) {
3765 printf("QueryUserInfo level %u failed - %s\n",
3766 levels[i], nt_errstr(status));
3774 static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3775 struct policy_handle *handle)
3778 struct samr_QueryUserInfo2 r;
3779 union samr_UserInfo *info;
3780 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
3781 11, 12, 13, 14, 16, 17, 20, 21};
3785 for (i=0;i<ARRAY_SIZE(levels);i++) {
3786 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
3788 r.in.user_handle = handle;
3789 r.in.level = levels[i];
3792 status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r);
3793 if (!NT_STATUS_IS_OK(status)) {
3794 printf("QueryUserInfo2 level %u failed - %s\n",
3795 levels[i], nt_errstr(status));
3803 static bool test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3804 struct policy_handle *handle, uint32_t rid)
3807 struct samr_OpenUser r;
3808 struct policy_handle user_handle;
3811 printf("Testing OpenUser(%u)\n", rid);
3813 r.in.domain_handle = handle;
3814 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3816 r.out.user_handle = &user_handle;
3818 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3819 if (!NT_STATUS_IS_OK(status)) {
3820 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
3824 if (!test_QuerySecurity(p, mem_ctx, &user_handle)) {
3828 if (!test_QueryUserInfo(p, mem_ctx, &user_handle)) {
3832 if (!test_QueryUserInfo2(p, mem_ctx, &user_handle)) {
3836 if (!test_GetUserPwInfo(p, mem_ctx, &user_handle)) {
3840 if (!test_GetGroupsForUser(p,mem_ctx, &user_handle)) {
3844 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
3851 static bool test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3852 struct policy_handle *handle, uint32_t rid)
3855 struct samr_OpenGroup r;
3856 struct policy_handle group_handle;
3859 printf("Testing OpenGroup(%u)\n", rid);
3861 r.in.domain_handle = handle;
3862 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3864 r.out.group_handle = &group_handle;
3866 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
3867 if (!NT_STATUS_IS_OK(status)) {
3868 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
3872 if (!test_QuerySecurity(p, mem_ctx, &group_handle)) {
3876 if (!test_QueryGroupInfo(p, mem_ctx, &group_handle)) {
3880 if (!test_QueryGroupMember(p, mem_ctx, &group_handle)) {
3884 if (!test_samr_handle_Close(p, mem_ctx, &group_handle)) {
3891 static bool test_OpenAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
3892 struct policy_handle *handle, uint32_t rid)
3895 struct samr_OpenAlias r;
3896 struct policy_handle alias_handle;
3899 torture_comment(tctx, "Testing OpenAlias(%u)\n", rid);
3901 r.in.domain_handle = handle;
3902 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3904 r.out.alias_handle = &alias_handle;
3906 status = dcerpc_samr_OpenAlias(p, tctx, &r);
3907 if (!NT_STATUS_IS_OK(status)) {
3908 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
3912 if (!test_QuerySecurity(p, tctx, &alias_handle)) {
3916 if (!test_QueryAliasInfo(p, tctx, &alias_handle)) {
3920 if (!test_GetMembersInAlias(p, tctx, &alias_handle)) {
3924 if (!test_samr_handle_Close(p, tctx, &alias_handle)) {
3931 static bool check_mask(struct dcerpc_pipe *p, struct torture_context *tctx,
3932 struct policy_handle *handle, uint32_t rid,
3933 uint32_t acct_flag_mask)
3936 struct samr_OpenUser r;
3937 struct samr_QueryUserInfo q;
3938 union samr_UserInfo *info;
3939 struct policy_handle user_handle;
3942 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
3944 r.in.domain_handle = handle;
3945 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3947 r.out.user_handle = &user_handle;
3949 status = dcerpc_samr_OpenUser(p, tctx, &r);
3950 if (!NT_STATUS_IS_OK(status)) {
3951 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
3955 q.in.user_handle = &user_handle;
3959 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
3960 if (!NT_STATUS_IS_OK(status)) {
3961 printf("QueryUserInfo level 16 failed - %s\n",
3965 if ((acct_flag_mask & info->info16.acct_flags) == 0) {
3966 printf("Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
3967 acct_flag_mask, info->info16.acct_flags, rid);
3972 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
3979 static bool test_EnumDomainUsers(struct dcerpc_pipe *p, struct torture_context *tctx,
3980 struct policy_handle *handle)
3982 NTSTATUS status = STATUS_MORE_ENTRIES;
3983 struct samr_EnumDomainUsers r;
3984 uint32_t mask, resume_handle=0;
3987 struct samr_LookupNames n;
3988 struct samr_LookupRids lr ;
3989 struct lsa_Strings names;
3990 struct samr_Ids rids, types;
3991 struct samr_SamArray *sam = NULL;
3992 uint32_t num_entries = 0;
3994 uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
3995 ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
3996 ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
3999 printf("Testing EnumDomainUsers\n");
4001 for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
4002 r.in.domain_handle = handle;
4003 r.in.resume_handle = &resume_handle;
4004 r.in.acct_flags = mask = masks[mask_idx];
4005 r.in.max_size = (uint32_t)-1;
4006 r.out.resume_handle = &resume_handle;
4007 r.out.num_entries = &num_entries;
4010 status = dcerpc_samr_EnumDomainUsers(p, tctx, &r);
4011 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
4012 !NT_STATUS_IS_OK(status)) {
4013 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
4017 torture_assert(tctx, sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
4019 if (sam->count == 0) {
4023 for (i=0;i<sam->count;i++) {
4025 if (!check_mask(p, tctx, handle, sam->entries[i].idx, mask)) {
4028 } else if (!test_OpenUser(p, tctx, handle, sam->entries[i].idx)) {
4034 printf("Testing LookupNames\n");
4035 n.in.domain_handle = handle;
4036 n.in.num_names = sam->count;
4037 n.in.names = talloc_array(tctx, struct lsa_String, sam->count);
4039 n.out.types = &types;
4040 for (i=0;i<sam->count;i++) {
4041 n.in.names[i].string = sam->entries[i].name.string;
4043 status = dcerpc_samr_LookupNames(p, tctx, &n);
4044 if (!NT_STATUS_IS_OK(status)) {
4045 printf("LookupNames failed - %s\n", nt_errstr(status));
4050 printf("Testing LookupRids\n");
4051 lr.in.domain_handle = handle;
4052 lr.in.num_rids = sam->count;
4053 lr.in.rids = talloc_array(tctx, uint32_t, sam->count);
4054 lr.out.names = &names;
4055 lr.out.types = &types;
4056 for (i=0;i<sam->count;i++) {
4057 lr.in.rids[i] = sam->entries[i].idx;
4059 status = dcerpc_samr_LookupRids(p, tctx, &lr);
4060 torture_assert_ntstatus_ok(tctx, status, "LookupRids");
4066 try blasting the server with a bunch of sync requests
4068 static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, struct torture_context *tctx,
4069 struct policy_handle *handle)
4072 struct samr_EnumDomainUsers r;
4073 uint32_t resume_handle=0;
4075 #define ASYNC_COUNT 100
4076 struct rpc_request *req[ASYNC_COUNT];
4078 if (!torture_setting_bool(tctx, "dangerous", false)) {
4079 torture_skip(tctx, "samr async test disabled - enable dangerous tests to use\n");
4082 torture_comment(tctx, "Testing EnumDomainUsers_async\n");
4084 r.in.domain_handle = handle;
4085 r.in.resume_handle = &resume_handle;
4086 r.in.acct_flags = 0;
4087 r.in.max_size = (uint32_t)-1;
4088 r.out.resume_handle = &resume_handle;
4090 for (i=0;i<ASYNC_COUNT;i++) {
4091 req[i] = dcerpc_samr_EnumDomainUsers_send(p, tctx, &r);
4094 for (i=0;i<ASYNC_COUNT;i++) {
4095 status = dcerpc_ndr_request_recv(req[i]);
4096 if (!NT_STATUS_IS_OK(status)) {
4097 printf("EnumDomainUsers[%d] failed - %s\n",
4098 i, nt_errstr(status));
4103 torture_comment(tctx, "%d async requests OK\n", i);
4108 static bool test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4109 struct policy_handle *handle)
4112 struct samr_EnumDomainGroups r;
4113 uint32_t resume_handle=0;
4114 struct samr_SamArray *sam = NULL;
4115 uint32_t num_entries = 0;
4119 printf("Testing EnumDomainGroups\n");
4121 r.in.domain_handle = handle;
4122 r.in.resume_handle = &resume_handle;
4123 r.in.max_size = (uint32_t)-1;
4124 r.out.resume_handle = &resume_handle;
4125 r.out.num_entries = &num_entries;
4128 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
4129 if (!NT_STATUS_IS_OK(status)) {
4130 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
4138 for (i=0;i<sam->count;i++) {
4139 if (!test_OpenGroup(p, mem_ctx, handle, sam->entries[i].idx)) {
4147 static bool test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4148 struct policy_handle *handle)
4151 struct samr_EnumDomainAliases r;
4152 uint32_t resume_handle=0;
4153 struct samr_SamArray *sam = NULL;
4154 uint32_t num_entries = 0;
4158 printf("Testing EnumDomainAliases\n");
4160 r.in.domain_handle = handle;
4161 r.in.resume_handle = &resume_handle;
4162 r.in.max_size = (uint32_t)-1;
4164 r.out.num_entries = &num_entries;
4165 r.out.resume_handle = &resume_handle;
4167 status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
4168 if (!NT_STATUS_IS_OK(status)) {
4169 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
4177 for (i=0;i<sam->count;i++) {
4178 if (!test_OpenAlias(p, mem_ctx, handle, sam->entries[i].idx)) {
4186 static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4187 struct policy_handle *handle)
4190 struct samr_GetDisplayEnumerationIndex r;
4192 uint16_t levels[] = {1, 2, 3, 4, 5};
4193 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
4194 struct lsa_String name;
4198 for (i=0;i<ARRAY_SIZE(levels);i++) {
4199 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
4201 init_lsa_String(&name, TEST_ACCOUNT_NAME);
4203 r.in.domain_handle = handle;
4204 r.in.level = levels[i];
4208 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
4211 !NT_STATUS_IS_OK(status) &&
4212 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
4213 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
4214 levels[i], nt_errstr(status));
4218 init_lsa_String(&name, "zzzzzzzz");
4220 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
4222 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
4223 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
4224 levels[i], nt_errstr(status));
4232 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4233 struct policy_handle *handle)
4236 struct samr_GetDisplayEnumerationIndex2 r;
4238 uint16_t levels[] = {1, 2, 3, 4, 5};
4239 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
4240 struct lsa_String name;
4244 for (i=0;i<ARRAY_SIZE(levels);i++) {
4245 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
4247 init_lsa_String(&name, TEST_ACCOUNT_NAME);
4249 r.in.domain_handle = handle;
4250 r.in.level = levels[i];
4254 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
4256 !NT_STATUS_IS_OK(status) &&
4257 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
4258 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
4259 levels[i], nt_errstr(status));
4263 init_lsa_String(&name, "zzzzzzzz");
4265 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
4266 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
4267 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
4268 levels[i], nt_errstr(status));
4276 #define STRING_EQUAL_QUERY(s1, s2, user) \
4277 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
4278 /* odd, but valid */ \
4279 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
4280 printf("%s mismatch for %s: %s != %s (%s)\n", \
4281 #s1, user.string, s1.string, s2.string, __location__); \
4284 #define INT_EQUAL_QUERY(s1, s2, user) \
4286 printf("%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
4287 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
4291 static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4292 struct samr_QueryDisplayInfo *querydisplayinfo,
4293 bool *seen_testuser)
4295 struct samr_OpenUser r;
4296 struct samr_QueryUserInfo q;
4297 union samr_UserInfo *info;
4298 struct policy_handle user_handle;
4301 r.in.domain_handle = querydisplayinfo->in.domain_handle;
4302 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4303 for (i = 0; ; i++) {
4304 switch (querydisplayinfo->in.level) {
4306 if (i >= querydisplayinfo->out.info->info1.count) {
4309 r.in.rid = querydisplayinfo->out.info->info1.entries[i].rid;
4312 if (i >= querydisplayinfo->out.info->info2.count) {
4315 r.in.rid = querydisplayinfo->out.info->info2.entries[i].rid;
4321 /* Not interested in validating just the account name */
4325 r.out.user_handle = &user_handle;
4327 switch (querydisplayinfo->in.level) {
4330 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
4331 if (!NT_STATUS_IS_OK(status)) {
4332 printf("OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(status));
4337 q.in.user_handle = &user_handle;
4340 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
4341 if (!NT_STATUS_IS_OK(status)) {
4342 printf("QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(status));
4346 switch (querydisplayinfo->in.level) {
4348 if (seen_testuser && strcmp(info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
4349 *seen_testuser = true;
4351 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].full_name,
4352 info->info21.full_name, info->info21.account_name);
4353 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].account_name,
4354 info->info21.account_name, info->info21.account_name);
4355 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].description,
4356 info->info21.description, info->info21.account_name);
4357 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].rid,
4358 info->info21.rid, info->info21.account_name);
4359 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].acct_flags,
4360 info->info21.acct_flags, info->info21.account_name);
4364 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].account_name,
4365 info->info21.account_name, info->info21.account_name);
4366 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].description,
4367 info->info21.description, info->info21.account_name);
4368 INT_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].rid,
4369 info->info21.rid, info->info21.account_name);
4370 INT_EQUAL_QUERY((querydisplayinfo->out.info->info2.entries[i].acct_flags & ~ACB_NORMAL),
4371 info->info21.acct_flags, info->info21.account_name);
4373 if (!(querydisplayinfo->out.info->info2.entries[i].acct_flags & ACB_NORMAL)) {
4374 printf("Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
4375 info->info21.account_name.string);
4378 if (!(info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
4379 printf("Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
4380 info->info21.account_name.string,
4381 querydisplayinfo->out.info->info2.entries[i].acct_flags,
4382 info->info21.acct_flags);
4389 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
4396 static bool test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4397 struct policy_handle *handle)
4400 struct samr_QueryDisplayInfo r;
4401 struct samr_QueryDomainInfo dom_info;
4402 union samr_DomainInfo *info = NULL;
4404 uint16_t levels[] = {1, 2, 3, 4, 5};
4406 bool seen_testuser = false;
4407 uint32_t total_size;
4408 uint32_t returned_size;
4409 union samr_DispInfo disp_info;
4412 for (i=0;i<ARRAY_SIZE(levels);i++) {
4413 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
4416 status = STATUS_MORE_ENTRIES;
4417 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
4418 r.in.domain_handle = handle;
4419 r.in.level = levels[i];
4420 r.in.max_entries = 2;
4421 r.in.buf_size = (uint32_t)-1;
4422 r.out.total_size = &total_size;
4423 r.out.returned_size = &returned_size;
4424 r.out.info = &disp_info;
4426 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
4427 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(status)) {
4428 printf("QueryDisplayInfo level %u failed - %s\n",
4429 levels[i], nt_errstr(status));
4432 switch (r.in.level) {
4434 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, &seen_testuser)) {
4437 r.in.start_idx += r.out.info->info1.count;
4440 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, NULL)) {
4443 r.in.start_idx += r.out.info->info2.count;
4446 r.in.start_idx += r.out.info->info3.count;
4449 r.in.start_idx += r.out.info->info4.count;
4452 r.in.start_idx += r.out.info->info5.count;
4456 dom_info.in.domain_handle = handle;
4457 dom_info.in.level = 2;
4458 dom_info.out.info = &info;
4460 /* Check number of users returned is correct */
4461 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &dom_info);
4462 if (!NT_STATUS_IS_OK(status)) {
4463 printf("QueryDomainInfo level %u failed - %s\n",
4464 r.in.level, nt_errstr(status));
4468 switch (r.in.level) {
4471 if (info->general.num_users < r.in.start_idx) {
4472 printf("QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
4473 r.in.start_idx, info->general.num_groups,
4474 info->general.domain_name.string);
4477 if (!seen_testuser) {
4478 struct policy_handle user_handle;
4479 if (NT_STATUS_IS_OK(test_OpenUser_byname(p, mem_ctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
4480 printf("Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
4481 info->general.domain_name.string);
4483 test_samr_handle_Close(p, mem_ctx, &user_handle);
4489 if (info->general.num_groups != r.in.start_idx) {
4490 printf("QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
4491 r.in.start_idx, info->general.num_groups,
4492 info->general.domain_name.string);
4504 static bool test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4505 struct policy_handle *handle)
4508 struct samr_QueryDisplayInfo2 r;
4510 uint16_t levels[] = {1, 2, 3, 4, 5};
4512 uint32_t total_size;
4513 uint32_t returned_size;
4514 union samr_DispInfo info;
4516 for (i=0;i<ARRAY_SIZE(levels);i++) {
4517 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
4519 r.in.domain_handle = handle;
4520 r.in.level = levels[i];
4522 r.in.max_entries = 1000;
4523 r.in.buf_size = (uint32_t)-1;
4524 r.out.total_size = &total_size;
4525 r.out.returned_size = &returned_size;
4528 status = dcerpc_samr_QueryDisplayInfo2(p, mem_ctx, &r);
4529 if (!NT_STATUS_IS_OK(status)) {
4530 printf("QueryDisplayInfo2 level %u failed - %s\n",
4531 levels[i], nt_errstr(status));
4539 static bool test_QueryDisplayInfo3(struct dcerpc_pipe *p, struct torture_context *tctx,
4540 struct policy_handle *handle)
4543 struct samr_QueryDisplayInfo3 r;
4545 uint16_t levels[] = {1, 2, 3, 4, 5};
4547 uint32_t total_size;
4548 uint32_t returned_size;
4549 union samr_DispInfo info;
4551 for (i=0;i<ARRAY_SIZE(levels);i++) {
4552 torture_comment(tctx, "Testing QueryDisplayInfo3 level %u\n", levels[i]);
4554 r.in.domain_handle = handle;
4555 r.in.level = levels[i];
4557 r.in.max_entries = 1000;
4558 r.in.buf_size = (uint32_t)-1;
4559 r.out.total_size = &total_size;
4560 r.out.returned_size = &returned_size;
4563 status = dcerpc_samr_QueryDisplayInfo3(p, tctx, &r);
4564 if (!NT_STATUS_IS_OK(status)) {
4565 printf("QueryDisplayInfo3 level %u failed - %s\n",
4566 levels[i], nt_errstr(status));
4575 static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4576 struct policy_handle *handle)
4579 struct samr_QueryDisplayInfo r;
4581 uint32_t total_size;
4582 uint32_t returned_size;
4583 union samr_DispInfo info;
4585 printf("Testing QueryDisplayInfo continuation\n");
4587 r.in.domain_handle = handle;
4590 r.in.max_entries = 1;
4591 r.in.buf_size = (uint32_t)-1;
4592 r.out.total_size = &total_size;
4593 r.out.returned_size = &returned_size;
4597 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
4598 if (NT_STATUS_IS_OK(status) && *r.out.returned_size != 0) {
4599 if (r.out.info->info1.entries[0].idx != r.in.start_idx + 1) {
4600 printf("expected idx %d but got %d\n",
4602 r.out.info->info1.entries[0].idx);
4606 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
4607 !NT_STATUS_IS_OK(status)) {
4608 printf("QueryDisplayInfo level %u failed - %s\n",
4609 r.in.level, nt_errstr(status));
4614 } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
4615 NT_STATUS_IS_OK(status)) &&
4616 *r.out.returned_size != 0);
4621 static bool test_QueryDomainInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
4622 struct policy_handle *handle)
4625 struct samr_QueryDomainInfo r;
4626 union samr_DomainInfo *info = NULL;
4627 struct samr_SetDomainInfo s;
4628 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
4629 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
4632 const char *domain_comment = talloc_asprintf(tctx,
4633 "Tortured by Samba4 RPC-SAMR: %s",
4634 timestring(tctx, time(NULL)));
4636 s.in.domain_handle = handle;
4638 s.in.info = talloc(tctx, union samr_DomainInfo);
4640 s.in.info->oem.oem_information.string = domain_comment;
4641 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
4642 if (!NT_STATUS_IS_OK(status)) {
4643 printf("SetDomainInfo level %u (set comment) failed - %s\n",
4644 r.in.level, nt_errstr(status));
4648 for (i=0;i<ARRAY_SIZE(levels);i++) {
4649 torture_comment(tctx, "Testing QueryDomainInfo level %u\n", levels[i]);
4651 r.in.domain_handle = handle;
4652 r.in.level = levels[i];
4655 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
4656 if (!NT_STATUS_IS_OK(status)) {
4657 printf("QueryDomainInfo level %u failed - %s\n",
4658 r.in.level, nt_errstr(status));
4663 switch (levels[i]) {
4665 if (strcmp(info->general.oem_information.string, domain_comment) != 0) {
4666 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
4667 levels[i], info->general.oem_information.string, domain_comment);
4670 if (!info->general.primary.string) {
4671 printf("QueryDomainInfo level %u returned no PDC name\n",
4674 } else if (info->general.role == SAMR_ROLE_DOMAIN_PDC) {
4675 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), info->general.primary.string) != 0) {
4676 printf("QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
4677 levels[i], info->general.primary.string, dcerpc_server_name(p));
4682 if (strcmp(info->oem.oem_information.string, domain_comment) != 0) {
4683 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
4684 levels[i], info->oem.oem_information.string, domain_comment);
4689 if (!info->info6.primary.string) {
4690 printf("QueryDomainInfo level %u returned no PDC name\n",
4696 if (strcmp(info->general2.general.oem_information.string, domain_comment) != 0) {
4697 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
4698 levels[i], info->general2.general.oem_information.string, domain_comment);
4704 torture_comment(tctx, "Testing SetDomainInfo level %u\n", levels[i]);
4706 s.in.domain_handle = handle;
4707 s.in.level = levels[i];
4710 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
4712 if (!NT_STATUS_IS_OK(status)) {
4713 printf("SetDomainInfo level %u failed - %s\n",
4714 r.in.level, nt_errstr(status));
4719 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
4720 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
4721 r.in.level, nt_errstr(status));
4727 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
4728 if (!NT_STATUS_IS_OK(status)) {
4729 printf("QueryDomainInfo level %u failed - %s\n",
4730 r.in.level, nt_errstr(status));
4740 static bool test_QueryDomainInfo2(struct dcerpc_pipe *p, struct torture_context *tctx,
4741 struct policy_handle *handle)
4744 struct samr_QueryDomainInfo2 r;
4745 union samr_DomainInfo *info = NULL;
4746 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
4750 for (i=0;i<ARRAY_SIZE(levels);i++) {
4751 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
4753 r.in.domain_handle = handle;
4754 r.in.level = levels[i];
4757 status = dcerpc_samr_QueryDomainInfo2(p, tctx, &r);
4758 if (!NT_STATUS_IS_OK(status)) {
4759 printf("QueryDomainInfo2 level %u failed - %s\n",
4760 r.in.level, nt_errstr(status));
4769 /* Test whether querydispinfo level 5 and enumdomgroups return the same
4770 set of group names. */
4771 static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx,
4772 struct policy_handle *handle)
4774 struct samr_EnumDomainGroups q1;
4775 struct samr_QueryDisplayInfo q2;
4777 uint32_t resume_handle=0;
4778 struct samr_SamArray *sam = NULL;
4779 uint32_t num_entries = 0;
4782 uint32_t total_size;
4783 uint32_t returned_size;
4784 union samr_DispInfo info;
4787 const char **names = NULL;
4789 torture_comment(tctx, "Testing coherency of querydispinfo vs enumdomgroups\n");
4791 q1.in.domain_handle = handle;
4792 q1.in.resume_handle = &resume_handle;
4794 q1.out.resume_handle = &resume_handle;
4795 q1.out.num_entries = &num_entries;
4798 status = STATUS_MORE_ENTRIES;
4799 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
4800 status = dcerpc_samr_EnumDomainGroups(p, tctx, &q1);
4802 if (!NT_STATUS_IS_OK(status) &&
4803 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
4806 for (i=0; i<*q1.out.num_entries; i++) {
4807 add_string_to_array(tctx,
4808 sam->entries[i].name.string,
4809 &names, &num_names);
4813 torture_assert_ntstatus_ok(tctx, status, "EnumDomainGroups");
4815 torture_assert(tctx, sam, "EnumDomainGroups failed to return sam");
4817 q2.in.domain_handle = handle;
4819 q2.in.start_idx = 0;
4820 q2.in.max_entries = 5;
4821 q2.in.buf_size = (uint32_t)-1;
4822 q2.out.total_size = &total_size;
4823 q2.out.returned_size = &returned_size;
4824 q2.out.info = &info;
4826 status = STATUS_MORE_ENTRIES;
4827 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
4828 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &q2);
4830 if (!NT_STATUS_IS_OK(status) &&
4831 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
4834 for (i=0; i<q2.out.info->info5.count; i++) {
4836 const char *name = q2.out.info->info5.entries[i].account_name.string;
4838 for (j=0; j<num_names; j++) {
4839 if (names[j] == NULL)
4841 if (strequal(names[j], name)) {
4849 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
4854 q2.in.start_idx += q2.out.info->info5.count;
4857 if (!NT_STATUS_IS_OK(status)) {
4858 printf("QueryDisplayInfo level 5 failed - %s\n",
4863 for (i=0; i<num_names; i++) {
4864 if (names[i] != NULL) {
4865 printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
4874 static bool test_DeleteDomainGroup(struct dcerpc_pipe *p, struct torture_context *tctx,
4875 struct policy_handle *group_handle)
4877 struct samr_DeleteDomainGroup d;
4880 torture_comment(tctx, "Testing DeleteDomainGroup\n");
4882 d.in.group_handle = group_handle;
4883 d.out.group_handle = group_handle;
4885 status = dcerpc_samr_DeleteDomainGroup(p, tctx, &d);
4886 torture_assert_ntstatus_ok(tctx, status, "DeleteDomainGroup");
4891 static bool test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
4892 struct policy_handle *domain_handle)
4894 struct samr_TestPrivateFunctionsDomain r;
4898 torture_comment(tctx, "Testing TestPrivateFunctionsDomain\n");
4900 r.in.domain_handle = domain_handle;
4902 status = dcerpc_samr_TestPrivateFunctionsDomain(p, tctx, &r);
4903 torture_assert_ntstatus_equal(tctx, NT_STATUS_NOT_IMPLEMENTED, status, "TestPrivateFunctionsDomain");
4908 static bool test_RidToSid(struct dcerpc_pipe *p, struct torture_context *tctx,
4909 struct dom_sid *domain_sid,
4910 struct policy_handle *domain_handle)
4912 struct samr_RidToSid r;
4915 struct dom_sid *calc_sid, *out_sid;
4916 int rids[] = { 0, 42, 512, 10200 };
4919 for (i=0;i<ARRAY_SIZE(rids);i++) {
4920 torture_comment(tctx, "Testing RidToSid\n");
4922 calc_sid = dom_sid_dup(tctx, domain_sid);
4923 r.in.domain_handle = domain_handle;
4925 r.out.sid = &out_sid;
4927 status = dcerpc_samr_RidToSid(p, tctx, &r);
4928 if (!NT_STATUS_IS_OK(status)) {
4929 printf("RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
4932 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
4934 if (!dom_sid_equal(calc_sid, out_sid)) {
4935 printf("RidToSid for %d failed - got %s, expected %s\n", rids[i],
4936 dom_sid_string(tctx, out_sid),
4937 dom_sid_string(tctx, calc_sid));
4946 static bool test_GetBootKeyInformation(struct dcerpc_pipe *p, struct torture_context *tctx,
4947 struct policy_handle *domain_handle)
4949 struct samr_GetBootKeyInformation r;
4952 uint32_t unknown = 0;
4954 torture_comment(tctx, "Testing GetBootKeyInformation\n");
4956 r.in.domain_handle = domain_handle;
4957 r.out.unknown = &unknown;
4959 status = dcerpc_samr_GetBootKeyInformation(p, tctx, &r);
4960 if (!NT_STATUS_IS_OK(status)) {
4961 /* w2k3 seems to fail this sometimes and pass it sometimes */
4962 torture_comment(tctx, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
4968 static bool test_AddGroupMember(struct dcerpc_pipe *p, struct torture_context *tctx,
4969 struct policy_handle *domain_handle,
4970 struct policy_handle *group_handle)
4973 struct samr_AddGroupMember r;
4974 struct samr_DeleteGroupMember d;
4975 struct samr_QueryGroupMember q;
4976 struct samr_RidTypeArray *rids = NULL;
4977 struct samr_SetMemberAttributesOfGroup s;
4980 status = test_LookupName(p, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
4981 torture_assert_ntstatus_ok(tctx, status, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME);
4983 r.in.group_handle = group_handle;
4985 r.in.flags = 0; /* ??? */
4987 torture_comment(tctx, "Testing AddGroupMember and DeleteGroupMember\n");
4989 d.in.group_handle = group_handle;
4992 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
4993 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_NOT_IN_GROUP, status, "DeleteGroupMember");
4995 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4996 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
4998 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4999 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_IN_GROUP, status, "AddGroupMember");
5001 if (torture_setting_bool(tctx, "samba4", false)) {
5002 torture_comment(tctx, "skipping SetMemberAttributesOfGroup test against Samba4\n");
5004 /* this one is quite strange. I am using random inputs in the
5005 hope of triggering an error that might give us a clue */
5007 s.in.group_handle = group_handle;
5008 s.in.unknown1 = random();
5009 s.in.unknown2 = random();
5011 status = dcerpc_samr_SetMemberAttributesOfGroup(p, tctx, &s);
5012 torture_assert_ntstatus_ok(tctx, status, "SetMemberAttributesOfGroup");
5015 q.in.group_handle = group_handle;
5018 status = dcerpc_samr_QueryGroupMember(p, tctx, &q);
5019 torture_assert_ntstatus_ok(tctx, status, "QueryGroupMember");
5021 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
5022 torture_assert_ntstatus_ok(tctx, status, "DeleteGroupMember");
5024 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5025 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
5031 static bool test_CreateDomainGroup(struct dcerpc_pipe *p,
5032 struct torture_context *tctx,
5033 struct policy_handle *domain_handle,
5034 struct policy_handle *group_handle,
5035 struct dom_sid *domain_sid)
5038 struct samr_CreateDomainGroup r;
5040 struct lsa_String name;
5043 init_lsa_String(&name, TEST_GROUPNAME);
5045 r.in.domain_handle = domain_handle;
5047 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5048 r.out.group_handle = group_handle;
5051 printf("Testing CreateDomainGroup(%s)\n", r.in.name->string);
5053 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
5055 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5056 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5057 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.name->string);
5060 printf("Server should have refused create of '%s', got %s instead\n", r.in.name->string,
5066 if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS)) {
5067 if (!test_DeleteGroup_byname(p, tctx, domain_handle, r.in.name->string)) {
5068 printf("CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
5072 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
5074 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
5075 if (!test_DeleteUser_byname(p, tctx, domain_handle, r.in.name->string)) {
5077 printf("CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
5081 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
5083 torture_assert_ntstatus_ok(tctx, status, "CreateDomainGroup");
5085 if (!test_AddGroupMember(p, tctx, domain_handle, group_handle)) {
5086 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
5090 if (!test_SetGroupInfo(p, tctx, group_handle)) {
5099 its not totally clear what this does. It seems to accept any sid you like.
5101 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p,
5102 struct torture_context *tctx,
5103 struct policy_handle *domain_handle)
5106 struct samr_RemoveMemberFromForeignDomain r;
5108 r.in.domain_handle = domain_handle;
5109 r.in.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-12-34-56-78");
5111 status = dcerpc_samr_RemoveMemberFromForeignDomain(p, tctx, &r);
5112 torture_assert_ntstatus_ok(tctx, status, "RemoveMemberFromForeignDomain");
5119 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
5120 struct policy_handle *handle);
5122 static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
5123 struct policy_handle *handle, struct dom_sid *sid,
5124 enum torture_samr_choice which_ops)
5127 struct samr_OpenDomain r;
5128 struct policy_handle domain_handle;
5129 struct policy_handle alias_handle;
5130 struct policy_handle user_handle;
5131 struct policy_handle group_handle;
5134 ZERO_STRUCT(alias_handle);
5135 ZERO_STRUCT(user_handle);
5136 ZERO_STRUCT(group_handle);
5137 ZERO_STRUCT(domain_handle);
5139 torture_comment(tctx, "Testing OpenDomain of %s\n", dom_sid_string(tctx, sid));
5141 r.in.connect_handle = handle;
5142 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5144 r.out.domain_handle = &domain_handle;
5146 status = dcerpc_samr_OpenDomain(p, tctx, &r);
5147 torture_assert_ntstatus_ok(tctx, status, "OpenDomain");
5149 /* run the domain tests with the main handle closed - this tests
5150 the servers reference counting */
5151 ret &= test_samr_handle_Close(p, tctx, handle);
5153 switch (which_ops) {
5154 case TORTURE_SAMR_USER_ATTRIBUTES:
5155 case TORTURE_SAMR_PASSWORDS:
5156 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
5157 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops);
5158 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops);
5159 /* This test needs 'complex' users to validate */
5160 ret &= test_QueryDisplayInfo(p, tctx, &domain_handle);
5162 printf("Testing PASSWORDS or ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
5165 case TORTURE_SAMR_OTHER:
5166 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops);
5168 printf("Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid));
5170 ret &= test_QuerySecurity(p, tctx, &domain_handle);
5171 ret &= test_RemoveMemberFromForeignDomain(p, tctx, &domain_handle);
5172 ret &= test_CreateAlias(p, tctx, &domain_handle, &alias_handle, sid);
5173 ret &= test_CreateDomainGroup(p, tctx, &domain_handle, &group_handle, sid);
5174 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
5175 ret &= test_QueryDomainInfo2(p, tctx, &domain_handle);
5176 ret &= test_EnumDomainUsers(p, tctx, &domain_handle);
5177 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
5178 ret &= test_EnumDomainGroups(p, tctx, &domain_handle);
5179 ret &= test_EnumDomainAliases(p, tctx, &domain_handle);
5180 ret &= test_QueryDisplayInfo2(p, tctx, &domain_handle);
5181 ret &= test_QueryDisplayInfo3(p, tctx, &domain_handle);
5182 ret &= test_QueryDisplayInfo_continue(p, tctx, &domain_handle);
5184 if (torture_setting_bool(tctx, "samba4", false)) {
5185 torture_comment(tctx, "skipping GetDisplayEnumerationIndex test against Samba4\n");
5187 ret &= test_GetDisplayEnumerationIndex(p, tctx, &domain_handle);
5188 ret &= test_GetDisplayEnumerationIndex2(p, tctx, &domain_handle);
5190 ret &= test_GroupList(p, tctx, &domain_handle);
5191 ret &= test_TestPrivateFunctionsDomain(p, tctx, &domain_handle);
5192 ret &= test_RidToSid(p, tctx, sid, &domain_handle);
5193 ret &= test_GetBootKeyInformation(p, tctx, &domain_handle);
5195 torture_comment(tctx, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx, sid));
5200 if (!policy_handle_empty(&user_handle) &&
5201 !test_DeleteUser(p, tctx, &user_handle)) {
5205 if (!policy_handle_empty(&alias_handle) &&
5206 !test_DeleteAlias(p, tctx, &alias_handle)) {
5210 if (!policy_handle_empty(&group_handle) &&
5211 !test_DeleteDomainGroup(p, tctx, &group_handle)) {
5215 ret &= test_samr_handle_Close(p, tctx, &domain_handle);
5217 /* reconnect the main handle */
5218 ret &= test_Connect(p, tctx, handle);
5221 printf("Testing domain %s failed!\n", dom_sid_string(tctx, sid));
5227 static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
5228 struct policy_handle *handle, const char *domain,
5229 enum torture_samr_choice which_ops)
5232 struct samr_LookupDomain r;
5233 struct dom_sid2 *sid = NULL;
5234 struct lsa_String n1;
5235 struct lsa_String n2;
5238 torture_comment(tctx, "Testing LookupDomain(%s)\n", domain);
5240 /* check for correct error codes */
5241 r.in.connect_handle = handle;
5242 r.in.domain_name = &n2;
5246 status = dcerpc_samr_LookupDomain(p, tctx, &r);
5247 torture_assert_ntstatus_equal(tctx, NT_STATUS_INVALID_PARAMETER, status, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
5249 init_lsa_String(&n2, "xxNODOMAINxx");
5251 status = dcerpc_samr_LookupDomain(p, tctx, &r);
5252 torture_assert_ntstatus_equal(tctx, NT_STATUS_NO_SUCH_DOMAIN, status, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
5254 r.in.connect_handle = handle;
5256 init_lsa_String(&n1, domain);
5257 r.in.domain_name = &n1;
5259 status = dcerpc_samr_LookupDomain(p, tctx, &r);
5260 torture_assert_ntstatus_ok(tctx, status, "LookupDomain");
5262 if (!test_GetDomPwInfo(p, tctx, &n1)) {
5266 if (!test_OpenDomain(p, tctx, handle, *r.out.sid, which_ops)) {
5274 static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
5275 struct policy_handle *handle, enum torture_samr_choice which_ops)
5278 struct samr_EnumDomains r;
5279 uint32_t resume_handle = 0;
5280 uint32_t num_entries = 0;
5281 struct samr_SamArray *sam = NULL;
5285 r.in.connect_handle = handle;
5286 r.in.resume_handle = &resume_handle;
5287 r.in.buf_size = (uint32_t)-1;
5288 r.out.resume_handle = &resume_handle;
5289 r.out.num_entries = &num_entries;
5292 status = dcerpc_samr_EnumDomains(p, tctx, &r);
5293 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
5299 for (i=0;i<sam->count;i++) {
5300 if (!test_LookupDomain(p, tctx, handle,
5301 sam->entries[i].name.string, which_ops)) {
5306 status = dcerpc_samr_EnumDomains(p, tctx, &r);
5307 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
5313 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
5314 struct policy_handle *handle)
5317 struct samr_Connect r;
5318 struct samr_Connect2 r2;
5319 struct samr_Connect3 r3;
5320 struct samr_Connect4 r4;
5321 struct samr_Connect5 r5;
5322 union samr_ConnectInfo info;
5323 struct policy_handle h;
5324 uint32_t level_out = 0;
5325 bool ret = true, got_handle = false;
5327 torture_comment(tctx, "testing samr_Connect\n");
5329 r.in.system_name = 0;
5330 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5331 r.out.connect_handle = &h;
5333 status = dcerpc_samr_Connect(p, tctx, &r);
5334 if (!NT_STATUS_IS_OK(status)) {
5335 torture_comment(tctx, "Connect failed - %s\n", nt_errstr(status));
5342 torture_comment(tctx, "testing samr_Connect2\n");
5344 r2.in.system_name = NULL;
5345 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5346 r2.out.connect_handle = &h;
5348 status = dcerpc_samr_Connect2(p, tctx, &r2);
5349 if (!NT_STATUS_IS_OK(status)) {
5350 torture_comment(tctx, "Connect2 failed - %s\n", nt_errstr(status));
5354 test_samr_handle_Close(p, tctx, handle);
5360 torture_comment(tctx, "testing samr_Connect3\n");
5362 r3.in.system_name = NULL;
5364 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5365 r3.out.connect_handle = &h;
5367 status = dcerpc_samr_Connect3(p, tctx, &r3);
5368 if (!NT_STATUS_IS_OK(status)) {
5369 printf("Connect3 failed - %s\n", nt_errstr(status));
5373 test_samr_handle_Close(p, tctx, handle);
5379 torture_comment(tctx, "testing samr_Connect4\n");
5381 r4.in.system_name = "";
5382 r4.in.client_version = 0;
5383 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5384 r4.out.connect_handle = &h;
5386 status = dcerpc_samr_Connect4(p, tctx, &r4);
5387 if (!NT_STATUS_IS_OK(status)) {
5388 printf("Connect4 failed - %s\n", nt_errstr(status));
5392 test_samr_handle_Close(p, tctx, handle);
5398 torture_comment(tctx, "testing samr_Connect5\n");
5400 info.info1.client_version = 0;
5401 info.info1.unknown2 = 0;
5403 r5.in.system_name = "";
5404 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5406 r5.out.level_out = &level_out;
5407 r5.in.info_in = &info;
5408 r5.out.info_out = &info;
5409 r5.out.connect_handle = &h;
5411 status = dcerpc_samr_Connect5(p, tctx, &r5);
5412 if (!NT_STATUS_IS_OK(status)) {
5413 printf("Connect5 failed - %s\n", nt_errstr(status));
5417 test_samr_handle_Close(p, tctx, handle);
5427 bool torture_rpc_samr(struct torture_context *torture)
5430 struct dcerpc_pipe *p;
5432 struct policy_handle handle;
5434 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
5435 if (!NT_STATUS_IS_OK(status)) {
5439 ret &= test_Connect(p, torture, &handle);
5441 ret &= test_QuerySecurity(p, torture, &handle);
5443 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_OTHER);
5445 ret &= test_SetDsrmPassword(p, torture, &handle);
5447 ret &= test_Shutdown(p, torture, &handle);
5449 ret &= test_samr_handle_Close(p, torture, &handle);
5455 bool torture_rpc_samr_users(struct torture_context *torture)
5458 struct dcerpc_pipe *p;
5460 struct policy_handle handle;
5462 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
5463 if (!NT_STATUS_IS_OK(status)) {
5467 ret &= test_Connect(p, torture, &handle);
5469 ret &= test_QuerySecurity(p, torture, &handle);
5471 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_USER_ATTRIBUTES);
5473 ret &= test_SetDsrmPassword(p, torture, &handle);
5475 ret &= test_Shutdown(p, torture, &handle);
5477 ret &= test_samr_handle_Close(p, torture, &handle);
5483 bool torture_rpc_samr_passwords(struct torture_context *torture)
5486 struct dcerpc_pipe *p;
5488 struct policy_handle handle;
5490 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
5491 if (!NT_STATUS_IS_OK(status)) {
5495 ret &= test_Connect(p, torture, &handle);
5497 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_PASSWORDS);
5499 ret &= test_samr_handle_Close(p, torture, &handle);
5504 bool torture_rpc_samr_passwords_pwdlastset(struct torture_context *torture)
5507 struct dcerpc_pipe *p;
5509 struct policy_handle handle;
5511 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
5512 if (!NT_STATUS_IS_OK(status)) {
5516 ret &= test_Connect(p, torture, &handle);
5518 ret &= test_EnumDomains(p, torture, &handle,
5519 TORTURE_SAMR_PASSWORDS_PWDLASTSET);
5521 ret &= test_samr_handle_Close(p, torture, &handle);