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_18(struct dcerpc_pipe *p, struct torture_context *tctx,
853 struct policy_handle *handle, char **password)
856 struct samr_SetUserInfo s;
857 union samr_UserInfo u;
859 DATA_BLOB session_key;
861 struct samr_GetUserPwInfo pwp;
862 struct samr_PwInfo info;
863 int policy_min_pw_len = 0;
864 uint8_t lm_hash[16], nt_hash[16];
866 pwp.in.user_handle = handle;
867 pwp.out.info = &info;
869 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
870 if (NT_STATUS_IS_OK(status)) {
871 policy_min_pw_len = pwp.out.info->min_password_length;
873 newpass = samr_rand_pass(tctx, policy_min_pw_len);
875 s.in.user_handle = handle;
881 u.info18.nt_pwd_active = true;
882 u.info18.lm_pwd_active = true;
884 E_md4hash(newpass, nt_hash);
885 E_deshash(newpass, lm_hash);
887 status = dcerpc_fetch_session_key(p, &session_key);
888 if (!NT_STATUS_IS_OK(status)) {
889 printf("SetUserInfo level %u - no session key - %s\n",
890 s.in.level, nt_errstr(status));
896 in = data_blob_const(nt_hash, 16);
897 out = data_blob_talloc_zero(tctx, 16);
898 sess_crypt_blob(&out, &in, &session_key, true);
899 memcpy(u.info18.nt_pwd.hash, out.data, out.length);
903 in = data_blob_const(lm_hash, 16);
904 out = data_blob_talloc_zero(tctx, 16);
905 sess_crypt_blob(&out, &in, &session_key, true);
906 memcpy(u.info18.lm_pwd.hash, out.data, out.length);
909 torture_comment(tctx, "Testing SetUserInfo level 18 (set password hash)\n");
911 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
912 if (!NT_STATUS_IS_OK(status)) {
913 printf("SetUserInfo level %u failed - %s\n",
914 s.in.level, nt_errstr(status));
923 static bool test_SetUserPass_21(struct dcerpc_pipe *p, struct torture_context *tctx,
924 struct policy_handle *handle, uint32_t fields_present,
928 struct samr_SetUserInfo s;
929 union samr_UserInfo u;
931 DATA_BLOB session_key;
933 struct samr_GetUserPwInfo pwp;
934 struct samr_PwInfo info;
935 int policy_min_pw_len = 0;
936 uint8_t lm_hash[16], nt_hash[16];
938 pwp.in.user_handle = handle;
939 pwp.out.info = &info;
941 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
942 if (NT_STATUS_IS_OK(status)) {
943 policy_min_pw_len = pwp.out.info->min_password_length;
945 newpass = samr_rand_pass(tctx, policy_min_pw_len);
947 s.in.user_handle = handle;
951 E_md4hash(newpass, nt_hash);
952 E_deshash(newpass, lm_hash);
956 u.info21.fields_present = fields_present;
958 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
959 u.info21.lm_owf_password.length = 16;
960 u.info21.lm_owf_password.size = 16;
961 u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
962 u.info21.lm_password_set = true;
965 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
966 u.info21.nt_owf_password.length = 16;
967 u.info21.nt_owf_password.size = 16;
968 u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
969 u.info21.nt_password_set = true;
972 status = dcerpc_fetch_session_key(p, &session_key);
973 if (!NT_STATUS_IS_OK(status)) {
974 printf("SetUserInfo level %u - no session key - %s\n",
975 s.in.level, nt_errstr(status));
979 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
981 in = data_blob_const(u.info21.lm_owf_password.array,
982 u.info21.lm_owf_password.length);
983 out = data_blob_talloc_zero(tctx, 16);
984 sess_crypt_blob(&out, &in, &session_key, true);
985 u.info21.lm_owf_password.array = (uint16_t *)out.data;
988 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
990 in = data_blob_const(u.info21.nt_owf_password.array,
991 u.info21.nt_owf_password.length);
992 out = data_blob_talloc_zero(tctx, 16);
993 sess_crypt_blob(&out, &in, &session_key, true);
994 u.info21.nt_owf_password.array = (uint16_t *)out.data;
997 torture_comment(tctx, "Testing SetUserInfo level 21 (set password hash)\n");
999 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1000 if (!NT_STATUS_IS_OK(status)) {
1001 printf("SetUserInfo level %u failed - %s\n",
1002 s.in.level, nt_errstr(status));
1005 *password = newpass;
1008 /* try invalid length */
1009 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1011 u.info21.nt_owf_password.length++;
1013 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1015 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1016 printf("SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1017 s.in.level, nt_errstr(status));
1022 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1024 u.info21.lm_owf_password.length++;
1026 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1028 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1029 printf("SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1030 s.in.level, nt_errstr(status));
1038 static bool test_SetUserPass_level_ex(struct dcerpc_pipe *p,
1039 struct torture_context *tctx,
1040 struct policy_handle *handle,
1042 uint32_t fields_present,
1043 char **password, uint8_t password_expired,
1045 bool *matched_expected_error)
1048 NTSTATUS expected_error = NT_STATUS_OK;
1049 struct samr_SetUserInfo s;
1050 struct samr_SetUserInfo2 s2;
1051 union samr_UserInfo u;
1053 DATA_BLOB session_key;
1054 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
1055 struct MD5Context ctx;
1056 uint8_t confounder[16];
1058 struct samr_GetUserPwInfo pwp;
1059 struct samr_PwInfo info;
1060 int policy_min_pw_len = 0;
1061 const char *comment = NULL;
1063 pwp.in.user_handle = handle;
1064 pwp.out.info = &info;
1066 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1067 if (NT_STATUS_IS_OK(status)) {
1068 policy_min_pw_len = pwp.out.info->min_password_length;
1070 newpass = samr_rand_pass_silent(tctx, policy_min_pw_len);
1073 s2.in.user_handle = handle;
1075 s2.in.level = level;
1077 s.in.user_handle = handle;
1082 if (fields_present & SAMR_FIELD_COMMENT) {
1083 comment = talloc_asprintf(tctx, "comment: %d\n", time(NULL));
1090 u.info21.fields_present = fields_present;
1091 u.info21.password_expired = password_expired;
1092 u.info21.comment.string = comment;
1096 u.info23.info.fields_present = fields_present;
1097 u.info23.info.password_expired = password_expired;
1098 u.info23.info.comment.string = comment;
1100 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
1104 u.info24.password_expired = password_expired;
1106 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
1110 u.info25.info.fields_present = fields_present;
1111 u.info25.info.password_expired = password_expired;
1112 u.info25.info.comment.string = comment;
1114 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
1118 u.info26.password_expired = password_expired;
1120 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
1125 status = dcerpc_fetch_session_key(p, &session_key);
1126 if (!NT_STATUS_IS_OK(status)) {
1127 printf("SetUserInfo level %u - no session key - %s\n",
1128 s.in.level, nt_errstr(status));
1132 generate_random_buffer((uint8_t *)confounder, 16);
1135 MD5Update(&ctx, confounder, 16);
1136 MD5Update(&ctx, session_key.data, session_key.length);
1137 MD5Final(confounded_session_key.data, &ctx);
1141 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
1144 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
1147 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
1148 memcpy(&u.info25.password.data[516], confounder, 16);
1151 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
1152 memcpy(&u.info26.password.data[516], confounder, 16);
1157 status = dcerpc_samr_SetUserInfo2(p, tctx, &s2);
1159 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1162 if (!NT_STATUS_IS_OK(status)) {
1163 if (fields_present == 0) {
1164 expected_error = NT_STATUS_INVALID_PARAMETER;
1166 if (fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
1167 expected_error = NT_STATUS_ACCESS_DENIED;
1171 if (!NT_STATUS_IS_OK(expected_error)) {
1173 torture_assert_ntstatus_equal(tctx,
1175 expected_error, "SetUserInfo2 failed");
1177 torture_assert_ntstatus_equal(tctx,
1179 expected_error, "SetUserInfo failed");
1181 *matched_expected_error = true;
1185 if (!NT_STATUS_IS_OK(status)) {
1186 printf("SetUserInfo%s level %u failed - %s\n",
1187 use_setinfo2 ? "2":"", level, nt_errstr(status));
1191 *password = newpass;
1198 static bool test_SetAliasInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1199 struct policy_handle *handle)
1202 struct samr_SetAliasInfo r;
1203 struct samr_QueryAliasInfo q;
1204 union samr_AliasInfo *info;
1205 uint16_t levels[] = {2, 3};
1209 /* Ignoring switch level 1, as that includes the number of members for the alias
1210 * and setting this to a wrong value might have negative consequences
1213 for (i=0;i<ARRAY_SIZE(levels);i++) {
1214 torture_comment(tctx, "Testing SetAliasInfo level %u\n", levels[i]);
1216 r.in.alias_handle = handle;
1217 r.in.level = levels[i];
1218 r.in.info = talloc(tctx, union samr_AliasInfo);
1219 switch (r.in.level) {
1220 case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
1221 case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
1222 "Test Description, should test I18N as well"); break;
1223 case ALIASINFOALL: printf("ALIASINFOALL ignored\n"); break;
1226 status = dcerpc_samr_SetAliasInfo(p, tctx, &r);
1227 if (!NT_STATUS_IS_OK(status)) {
1228 printf("SetAliasInfo level %u failed - %s\n",
1229 levels[i], nt_errstr(status));
1233 q.in.alias_handle = handle;
1234 q.in.level = levels[i];
1237 status = dcerpc_samr_QueryAliasInfo(p, tctx, &q);
1238 if (!NT_STATUS_IS_OK(status)) {
1239 printf("QueryAliasInfo level %u failed - %s\n",
1240 levels[i], nt_errstr(status));
1248 static bool test_GetGroupsForUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1249 struct policy_handle *user_handle)
1251 struct samr_GetGroupsForUser r;
1252 struct samr_RidWithAttributeArray *rids = NULL;
1255 torture_comment(tctx, "testing GetGroupsForUser\n");
1257 r.in.user_handle = user_handle;
1260 status = dcerpc_samr_GetGroupsForUser(p, tctx, &r);
1261 torture_assert_ntstatus_ok(tctx, status, "GetGroupsForUser");
1267 static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1268 struct lsa_String *domain_name)
1271 struct samr_GetDomPwInfo r;
1272 struct samr_PwInfo info;
1274 r.in.domain_name = domain_name;
1277 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1279 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1280 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1282 r.in.domain_name->string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1283 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1285 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1286 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1288 r.in.domain_name->string = "\\\\__NONAME__";
1289 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1291 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1292 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1294 r.in.domain_name->string = "\\\\Builtin";
1295 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1297 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1298 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1303 static bool test_GetUserPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1304 struct policy_handle *handle)
1307 struct samr_GetUserPwInfo r;
1308 struct samr_PwInfo info;
1310 torture_comment(tctx, "Testing GetUserPwInfo\n");
1312 r.in.user_handle = handle;
1315 status = dcerpc_samr_GetUserPwInfo(p, tctx, &r);
1316 torture_assert_ntstatus_ok(tctx, status, "GetUserPwInfo");
1321 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, struct torture_context *tctx,
1322 struct policy_handle *domain_handle, const char *name,
1326 struct samr_LookupNames n;
1327 struct lsa_String sname[2];
1328 struct samr_Ids rids, types;
1330 init_lsa_String(&sname[0], name);
1332 n.in.domain_handle = domain_handle;
1336 n.out.types = &types;
1337 status = dcerpc_samr_LookupNames(p, tctx, &n);
1338 if (NT_STATUS_IS_OK(status)) {
1339 *rid = n.out.rids->ids[0];
1344 init_lsa_String(&sname[1], "xxNONAMExx");
1346 status = dcerpc_samr_LookupNames(p, tctx, &n);
1347 if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
1348 printf("LookupNames[2] failed - %s\n", nt_errstr(status));
1349 if (NT_STATUS_IS_OK(status)) {
1350 return NT_STATUS_UNSUCCESSFUL;
1356 status = dcerpc_samr_LookupNames(p, tctx, &n);
1357 if (!NT_STATUS_IS_OK(status)) {
1358 printf("LookupNames[0] failed - %s\n", nt_errstr(status));
1362 init_lsa_String(&sname[0], "xxNONAMExx");
1364 status = dcerpc_samr_LookupNames(p, tctx, &n);
1365 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1366 printf("LookupNames[1 bad name] failed - %s\n", nt_errstr(status));
1367 if (NT_STATUS_IS_OK(status)) {
1368 return NT_STATUS_UNSUCCESSFUL;
1373 init_lsa_String(&sname[0], "xxNONAMExx");
1374 init_lsa_String(&sname[1], "xxNONAME2xx");
1376 status = dcerpc_samr_LookupNames(p, tctx, &n);
1377 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1378 printf("LookupNames[2 bad names] failed - %s\n", nt_errstr(status));
1379 if (NT_STATUS_IS_OK(status)) {
1380 return NT_STATUS_UNSUCCESSFUL;
1385 return NT_STATUS_OK;
1388 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1389 struct policy_handle *domain_handle,
1390 const char *name, struct policy_handle *user_handle)
1393 struct samr_OpenUser r;
1396 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
1397 if (!NT_STATUS_IS_OK(status)) {
1401 r.in.domain_handle = domain_handle;
1402 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1404 r.out.user_handle = user_handle;
1405 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
1406 if (!NT_STATUS_IS_OK(status)) {
1407 printf("OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(status));
1414 static bool test_ChangePasswordNT3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1415 struct policy_handle *handle)
1418 struct samr_ChangePasswordUser r;
1420 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1421 struct policy_handle user_handle;
1422 char *oldpass = "test";
1423 char *newpass = "test2";
1424 uint8_t old_nt_hash[16], new_nt_hash[16];
1425 uint8_t old_lm_hash[16], new_lm_hash[16];
1427 status = test_OpenUser_byname(p, mem_ctx, handle, "testuser", &user_handle);
1428 if (!NT_STATUS_IS_OK(status)) {
1432 printf("Testing ChangePasswordUser for user 'testuser'\n");
1434 printf("old password: %s\n", oldpass);
1435 printf("new password: %s\n", newpass);
1437 E_md4hash(oldpass, old_nt_hash);
1438 E_md4hash(newpass, new_nt_hash);
1439 E_deshash(oldpass, old_lm_hash);
1440 E_deshash(newpass, new_lm_hash);
1442 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1443 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1444 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1445 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1446 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1447 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1449 r.in.handle = &user_handle;
1450 r.in.lm_present = 1;
1451 r.in.old_lm_crypted = &hash1;
1452 r.in.new_lm_crypted = &hash2;
1453 r.in.nt_present = 1;
1454 r.in.old_nt_crypted = &hash3;
1455 r.in.new_nt_crypted = &hash4;
1456 r.in.cross1_present = 1;
1457 r.in.nt_cross = &hash5;
1458 r.in.cross2_present = 1;
1459 r.in.lm_cross = &hash6;
1461 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1462 if (!NT_STATUS_IS_OK(status)) {
1463 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1467 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1475 static bool test_ChangePasswordUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1476 const char *acct_name,
1477 struct policy_handle *handle, char **password)
1480 struct samr_ChangePasswordUser r;
1482 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1483 struct policy_handle user_handle;
1485 uint8_t old_nt_hash[16], new_nt_hash[16];
1486 uint8_t old_lm_hash[16], new_lm_hash[16];
1487 bool changed = true;
1490 struct samr_GetUserPwInfo pwp;
1491 struct samr_PwInfo info;
1492 int policy_min_pw_len = 0;
1494 status = test_OpenUser_byname(p, tctx, handle, acct_name, &user_handle);
1495 if (!NT_STATUS_IS_OK(status)) {
1498 pwp.in.user_handle = &user_handle;
1499 pwp.out.info = &info;
1501 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1502 if (NT_STATUS_IS_OK(status)) {
1503 policy_min_pw_len = pwp.out.info->min_password_length;
1505 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1507 torture_comment(tctx, "Testing ChangePasswordUser\n");
1509 torture_assert(tctx, *password != NULL,
1510 "Failing ChangePasswordUser as old password was NULL. Previous test failed?");
1512 oldpass = *password;
1514 E_md4hash(oldpass, old_nt_hash);
1515 E_md4hash(newpass, new_nt_hash);
1516 E_deshash(oldpass, old_lm_hash);
1517 E_deshash(newpass, new_lm_hash);
1519 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1520 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1521 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1522 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1523 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1524 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1526 r.in.user_handle = &user_handle;
1527 r.in.lm_present = 1;
1528 /* Break the LM hash */
1530 r.in.old_lm_crypted = &hash1;
1531 r.in.new_lm_crypted = &hash2;
1532 r.in.nt_present = 1;
1533 r.in.old_nt_crypted = &hash3;
1534 r.in.new_nt_crypted = &hash4;
1535 r.in.cross1_present = 1;
1536 r.in.nt_cross = &hash5;
1537 r.in.cross2_present = 1;
1538 r.in.lm_cross = &hash6;
1540 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1541 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1542 "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash");
1544 /* Unbreak the LM hash */
1547 r.in.user_handle = &user_handle;
1548 r.in.lm_present = 1;
1549 r.in.old_lm_crypted = &hash1;
1550 r.in.new_lm_crypted = &hash2;
1551 /* Break the NT hash */
1553 r.in.nt_present = 1;
1554 r.in.old_nt_crypted = &hash3;
1555 r.in.new_nt_crypted = &hash4;
1556 r.in.cross1_present = 1;
1557 r.in.nt_cross = &hash5;
1558 r.in.cross2_present = 1;
1559 r.in.lm_cross = &hash6;
1561 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1562 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1563 "expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash");
1565 /* Unbreak the NT hash */
1568 r.in.user_handle = &user_handle;
1569 r.in.lm_present = 1;
1570 r.in.old_lm_crypted = &hash1;
1571 r.in.new_lm_crypted = &hash2;
1572 r.in.nt_present = 1;
1573 r.in.old_nt_crypted = &hash3;
1574 r.in.new_nt_crypted = &hash4;
1575 r.in.cross1_present = 1;
1576 r.in.nt_cross = &hash5;
1577 r.in.cross2_present = 1;
1578 /* Break the LM cross */
1580 r.in.lm_cross = &hash6;
1582 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1583 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1584 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status));
1588 /* Unbreak the LM cross */
1591 r.in.user_handle = &user_handle;
1592 r.in.lm_present = 1;
1593 r.in.old_lm_crypted = &hash1;
1594 r.in.new_lm_crypted = &hash2;
1595 r.in.nt_present = 1;
1596 r.in.old_nt_crypted = &hash3;
1597 r.in.new_nt_crypted = &hash4;
1598 r.in.cross1_present = 1;
1599 /* Break the NT cross */
1601 r.in.nt_cross = &hash5;
1602 r.in.cross2_present = 1;
1603 r.in.lm_cross = &hash6;
1605 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1606 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1607 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status));
1611 /* Unbreak the NT cross */
1615 /* Reset the hashes to not broken values */
1616 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1617 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1618 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1619 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1620 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1621 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1623 r.in.user_handle = &user_handle;
1624 r.in.lm_present = 1;
1625 r.in.old_lm_crypted = &hash1;
1626 r.in.new_lm_crypted = &hash2;
1627 r.in.nt_present = 1;
1628 r.in.old_nt_crypted = &hash3;
1629 r.in.new_nt_crypted = &hash4;
1630 r.in.cross1_present = 1;
1631 r.in.nt_cross = &hash5;
1632 r.in.cross2_present = 0;
1633 r.in.lm_cross = NULL;
1635 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1636 if (NT_STATUS_IS_OK(status)) {
1638 *password = newpass;
1639 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1640 printf("ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(status));
1645 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1647 E_md4hash(oldpass, old_nt_hash);
1648 E_md4hash(newpass, new_nt_hash);
1649 E_deshash(oldpass, old_lm_hash);
1650 E_deshash(newpass, new_lm_hash);
1653 /* Reset the hashes to not broken values */
1654 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1655 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1656 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1657 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1658 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1659 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1661 r.in.user_handle = &user_handle;
1662 r.in.lm_present = 1;
1663 r.in.old_lm_crypted = &hash1;
1664 r.in.new_lm_crypted = &hash2;
1665 r.in.nt_present = 1;
1666 r.in.old_nt_crypted = &hash3;
1667 r.in.new_nt_crypted = &hash4;
1668 r.in.cross1_present = 0;
1669 r.in.nt_cross = NULL;
1670 r.in.cross2_present = 1;
1671 r.in.lm_cross = &hash6;
1673 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1674 if (NT_STATUS_IS_OK(status)) {
1676 *password = newpass;
1677 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1678 printf("ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status));
1683 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1685 E_md4hash(oldpass, old_nt_hash);
1686 E_md4hash(newpass, new_nt_hash);
1687 E_deshash(oldpass, old_lm_hash);
1688 E_deshash(newpass, new_lm_hash);
1691 /* Reset the hashes to not broken values */
1692 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1693 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1694 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1695 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1696 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1697 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1699 r.in.user_handle = &user_handle;
1700 r.in.lm_present = 1;
1701 r.in.old_lm_crypted = &hash1;
1702 r.in.new_lm_crypted = &hash2;
1703 r.in.nt_present = 1;
1704 r.in.old_nt_crypted = &hash3;
1705 r.in.new_nt_crypted = &hash4;
1706 r.in.cross1_present = 1;
1707 r.in.nt_cross = &hash5;
1708 r.in.cross2_present = 1;
1709 r.in.lm_cross = &hash6;
1711 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1712 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1713 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1714 } else if (!NT_STATUS_IS_OK(status)) {
1715 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1719 *password = newpass;
1722 r.in.user_handle = &user_handle;
1723 r.in.lm_present = 1;
1724 r.in.old_lm_crypted = &hash1;
1725 r.in.new_lm_crypted = &hash2;
1726 r.in.nt_present = 1;
1727 r.in.old_nt_crypted = &hash3;
1728 r.in.new_nt_crypted = &hash4;
1729 r.in.cross1_present = 1;
1730 r.in.nt_cross = &hash5;
1731 r.in.cross2_present = 1;
1732 r.in.lm_cross = &hash6;
1735 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1736 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1737 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1738 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1739 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status));
1745 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
1753 static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
1754 const char *acct_name,
1755 struct policy_handle *handle, char **password)
1758 struct samr_OemChangePasswordUser2 r;
1760 struct samr_Password lm_verifier;
1761 struct samr_CryptPassword lm_pass;
1762 struct lsa_AsciiString server, account, account_bad;
1765 uint8_t old_lm_hash[16], new_lm_hash[16];
1767 struct samr_GetDomPwInfo dom_pw_info;
1768 struct samr_PwInfo info;
1769 int policy_min_pw_len = 0;
1771 struct lsa_String domain_name;
1773 domain_name.string = "";
1774 dom_pw_info.in.domain_name = &domain_name;
1775 dom_pw_info.out.info = &info;
1777 torture_comment(tctx, "Testing OemChangePasswordUser2\n");
1779 torture_assert(tctx, *password != NULL,
1780 "Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?");
1782 oldpass = *password;
1784 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
1785 if (NT_STATUS_IS_OK(status)) {
1786 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
1789 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1791 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1792 account.string = acct_name;
1794 E_deshash(oldpass, old_lm_hash);
1795 E_deshash(newpass, new_lm_hash);
1797 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1798 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1799 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1801 r.in.server = &server;
1802 r.in.account = &account;
1803 r.in.password = &lm_pass;
1804 r.in.hash = &lm_verifier;
1806 /* Break the verification */
1807 lm_verifier.hash[0]++;
1809 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1811 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1812 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1813 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1818 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1819 /* Break the old password */
1821 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1822 /* unbreak it for the next operation */
1824 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1826 r.in.server = &server;
1827 r.in.account = &account;
1828 r.in.password = &lm_pass;
1829 r.in.hash = &lm_verifier;
1831 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1833 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1834 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1835 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1840 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1841 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1843 r.in.server = &server;
1844 r.in.account = &account;
1845 r.in.password = &lm_pass;
1848 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1850 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1851 && !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1852 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
1857 /* This shouldn't be a valid name */
1858 account_bad.string = TEST_ACCOUNT_NAME "XX";
1859 r.in.account = &account_bad;
1861 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1863 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1864 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
1869 /* This shouldn't be a valid name */
1870 account_bad.string = TEST_ACCOUNT_NAME "XX";
1871 r.in.account = &account_bad;
1872 r.in.password = &lm_pass;
1873 r.in.hash = &lm_verifier;
1875 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1877 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1878 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1883 /* This shouldn't be a valid name */
1884 account_bad.string = TEST_ACCOUNT_NAME "XX";
1885 r.in.account = &account_bad;
1886 r.in.password = NULL;
1887 r.in.hash = &lm_verifier;
1889 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1891 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1892 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
1897 E_deshash(oldpass, old_lm_hash);
1898 E_deshash(newpass, new_lm_hash);
1900 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1901 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1902 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1904 r.in.server = &server;
1905 r.in.account = &account;
1906 r.in.password = &lm_pass;
1907 r.in.hash = &lm_verifier;
1909 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1910 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1911 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1912 } else if (!NT_STATUS_IS_OK(status)) {
1913 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
1916 *password = newpass;
1923 static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
1924 const char *acct_name,
1926 char *newpass, bool allow_password_restriction)
1929 struct samr_ChangePasswordUser2 r;
1931 struct lsa_String server, account;
1932 struct samr_CryptPassword nt_pass, lm_pass;
1933 struct samr_Password nt_verifier, lm_verifier;
1935 uint8_t old_nt_hash[16], new_nt_hash[16];
1936 uint8_t old_lm_hash[16], new_lm_hash[16];
1938 struct samr_GetDomPwInfo dom_pw_info;
1939 struct samr_PwInfo info;
1941 struct lsa_String domain_name;
1943 domain_name.string = "";
1944 dom_pw_info.in.domain_name = &domain_name;
1945 dom_pw_info.out.info = &info;
1947 torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name);
1949 torture_assert(tctx, *password != NULL,
1950 "Failing ChangePasswordUser2 as old password was NULL. Previous test failed?");
1951 oldpass = *password;
1954 int policy_min_pw_len = 0;
1955 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
1956 if (NT_STATUS_IS_OK(status)) {
1957 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
1960 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1963 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1964 init_lsa_String(&account, acct_name);
1966 E_md4hash(oldpass, old_nt_hash);
1967 E_md4hash(newpass, new_nt_hash);
1969 E_deshash(oldpass, old_lm_hash);
1970 E_deshash(newpass, new_lm_hash);
1972 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
1973 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1974 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1976 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1977 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1978 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1980 r.in.server = &server;
1981 r.in.account = &account;
1982 r.in.nt_password = &nt_pass;
1983 r.in.nt_verifier = &nt_verifier;
1985 r.in.lm_password = &lm_pass;
1986 r.in.lm_verifier = &lm_verifier;
1988 status = dcerpc_samr_ChangePasswordUser2(p, tctx, &r);
1989 if (allow_password_restriction && NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1990 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1991 } else if (!NT_STATUS_IS_OK(status)) {
1992 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
1995 *password = newpass;
2002 bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tctx,
2003 const char *account_string,
2004 int policy_min_pw_len,
2006 const char *newpass,
2007 NTTIME last_password_change,
2008 bool handle_reject_reason)
2011 struct samr_ChangePasswordUser3 r;
2013 struct lsa_String server, account, account_bad;
2014 struct samr_CryptPassword nt_pass, lm_pass;
2015 struct samr_Password nt_verifier, lm_verifier;
2017 uint8_t old_nt_hash[16], new_nt_hash[16];
2018 uint8_t old_lm_hash[16], new_lm_hash[16];
2020 struct samr_DomInfo1 *dominfo = NULL;
2021 struct samr_ChangeReject *reject = NULL;
2023 torture_comment(tctx, "Testing ChangePasswordUser3\n");
2025 if (newpass == NULL) {
2027 if (policy_min_pw_len == 0) {
2028 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2030 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len);
2032 } while (check_password_quality(newpass) == false);
2034 torture_comment(tctx, "Using password '%s'\n", newpass);
2037 torture_assert(tctx, *password != NULL,
2038 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2040 oldpass = *password;
2041 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2042 init_lsa_String(&account, account_string);
2044 E_md4hash(oldpass, old_nt_hash);
2045 E_md4hash(newpass, new_nt_hash);
2047 E_deshash(oldpass, old_lm_hash);
2048 E_deshash(newpass, new_lm_hash);
2050 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2051 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2052 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2054 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2055 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2056 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2058 /* Break the verification */
2059 nt_verifier.hash[0]++;
2061 r.in.server = &server;
2062 r.in.account = &account;
2063 r.in.nt_password = &nt_pass;
2064 r.in.nt_verifier = &nt_verifier;
2066 r.in.lm_password = &lm_pass;
2067 r.in.lm_verifier = &lm_verifier;
2068 r.in.password3 = NULL;
2069 r.out.dominfo = &dominfo;
2070 r.out.reject = &reject;
2072 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2073 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
2074 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
2075 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
2080 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2081 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2082 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2084 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2085 /* Break the NT hash */
2087 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2088 /* Unbreak it again */
2090 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2092 r.in.server = &server;
2093 r.in.account = &account;
2094 r.in.nt_password = &nt_pass;
2095 r.in.nt_verifier = &nt_verifier;
2097 r.in.lm_password = &lm_pass;
2098 r.in.lm_verifier = &lm_verifier;
2099 r.in.password3 = NULL;
2100 r.out.dominfo = &dominfo;
2101 r.out.reject = &reject;
2103 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2104 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
2105 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
2106 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
2111 /* This shouldn't be a valid name */
2112 init_lsa_String(&account_bad, talloc_asprintf(tctx, "%sXX", account_string));
2114 r.in.account = &account_bad;
2115 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2116 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
2117 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
2122 E_md4hash(oldpass, old_nt_hash);
2123 E_md4hash(newpass, new_nt_hash);
2125 E_deshash(oldpass, old_lm_hash);
2126 E_deshash(newpass, new_lm_hash);
2128 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2129 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2130 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2132 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2133 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2134 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2136 r.in.server = &server;
2137 r.in.account = &account;
2138 r.in.nt_password = &nt_pass;
2139 r.in.nt_verifier = &nt_verifier;
2141 r.in.lm_password = &lm_pass;
2142 r.in.lm_verifier = &lm_verifier;
2143 r.in.password3 = NULL;
2144 r.out.dominfo = &dominfo;
2145 r.out.reject = &reject;
2147 unix_to_nt_time(&t, time(NULL));
2149 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2151 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
2154 && handle_reject_reason
2155 && (!null_nttime(last_password_change) || !dominfo->min_password_age)) {
2156 if (dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
2158 if (reject && (reject->reason != SAMR_REJECT_OTHER)) {
2159 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2160 SAMR_REJECT_OTHER, reject->reason);
2165 /* We tested the order of precendence which is as follows:
2174 if ((dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
2175 (last_password_change + dominfo->min_password_age > t)) {
2177 if (reject->reason != SAMR_REJECT_OTHER) {
2178 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2179 SAMR_REJECT_OTHER, reject->reason);
2183 } else if ((dominfo->min_password_length > 0) &&
2184 (strlen(newpass) < dominfo->min_password_length)) {
2186 if (reject->reason != SAMR_REJECT_TOO_SHORT) {
2187 printf("expected SAMR_REJECT_TOO_SHORT (%d), got %d\n",
2188 SAMR_REJECT_TOO_SHORT, reject->reason);
2192 } else if ((dominfo->password_history_length > 0) &&
2193 strequal(oldpass, newpass)) {
2195 if (reject->reason != SAMR_REJECT_IN_HISTORY) {
2196 printf("expected SAMR_REJECT_IN_HISTORY (%d), got %d\n",
2197 SAMR_REJECT_IN_HISTORY, reject->reason);
2200 } else if (dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
2202 if (reject->reason != SAMR_REJECT_COMPLEXITY) {
2203 printf("expected SAMR_REJECT_COMPLEXITY (%d), got %d\n",
2204 SAMR_REJECT_COMPLEXITY, reject->reason);
2210 if (reject->reason == SAMR_REJECT_TOO_SHORT) {
2211 /* retry with adjusted size */
2212 return test_ChangePasswordUser3(p, tctx, account_string,
2213 dominfo->min_password_length,
2214 password, NULL, 0, false);
2218 } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2219 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2220 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2221 SAMR_REJECT_OTHER, reject->reason);
2224 /* Perhaps the server has a 'min password age' set? */
2227 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3");
2228 *password = talloc_strdup(tctx, newpass);
2234 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_context *tctx,
2235 const char *account_string,
2236 struct policy_handle *handle,
2240 struct samr_ChangePasswordUser3 r;
2241 struct samr_SetUserInfo s;
2242 union samr_UserInfo u;
2243 DATA_BLOB session_key;
2244 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
2245 uint8_t confounder[16];
2246 struct MD5Context ctx;
2249 struct lsa_String server, account;
2250 struct samr_CryptPassword nt_pass;
2251 struct samr_Password nt_verifier;
2252 DATA_BLOB new_random_pass;
2255 uint8_t old_nt_hash[16], new_nt_hash[16];
2257 struct samr_DomInfo1 *dominfo = NULL;
2258 struct samr_ChangeReject *reject = NULL;
2260 new_random_pass = samr_very_rand_pass(tctx, 128);
2262 torture_assert(tctx, *password != NULL,
2263 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2265 oldpass = *password;
2266 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2267 init_lsa_String(&account, account_string);
2269 s.in.user_handle = handle;
2275 u.info25.info.fields_present = SAMR_FIELD_NT_PASSWORD_PRESENT;
2277 set_pw_in_buffer(u.info25.password.data, &new_random_pass);
2279 status = dcerpc_fetch_session_key(p, &session_key);
2280 if (!NT_STATUS_IS_OK(status)) {
2281 printf("SetUserInfo level %u - no session key - %s\n",
2282 s.in.level, nt_errstr(status));
2286 generate_random_buffer((uint8_t *)confounder, 16);
2289 MD5Update(&ctx, confounder, 16);
2290 MD5Update(&ctx, session_key.data, session_key.length);
2291 MD5Final(confounded_session_key.data, &ctx);
2293 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
2294 memcpy(&u.info25.password.data[516], confounder, 16);
2296 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
2298 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
2299 if (!NT_STATUS_IS_OK(status)) {
2300 printf("SetUserInfo level %u failed - %s\n",
2301 s.in.level, nt_errstr(status));
2305 torture_comment(tctx, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
2307 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2309 new_random_pass = samr_very_rand_pass(tctx, 128);
2311 mdfour(new_nt_hash, new_random_pass.data, new_random_pass.length);
2313 set_pw_in_buffer(nt_pass.data, &new_random_pass);
2314 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2315 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2317 r.in.server = &server;
2318 r.in.account = &account;
2319 r.in.nt_password = &nt_pass;
2320 r.in.nt_verifier = &nt_verifier;
2322 r.in.lm_password = NULL;
2323 r.in.lm_verifier = NULL;
2324 r.in.password3 = NULL;
2325 r.out.dominfo = &dominfo;
2326 r.out.reject = &reject;
2328 unix_to_nt_time(&t, time(NULL));
2330 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2332 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2333 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2334 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2335 SAMR_REJECT_OTHER, reject->reason);
2338 /* Perhaps the server has a 'min password age' set? */
2340 } else if (!NT_STATUS_IS_OK(status)) {
2341 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
2345 newpass = samr_rand_pass(tctx, 128);
2347 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2349 E_md4hash(newpass, new_nt_hash);
2351 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2352 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2353 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2355 r.in.server = &server;
2356 r.in.account = &account;
2357 r.in.nt_password = &nt_pass;
2358 r.in.nt_verifier = &nt_verifier;
2360 r.in.lm_password = NULL;
2361 r.in.lm_verifier = NULL;
2362 r.in.password3 = NULL;
2363 r.out.dominfo = &dominfo;
2364 r.out.reject = &reject;
2366 unix_to_nt_time(&t, time(NULL));
2368 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2370 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2371 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2372 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2373 SAMR_REJECT_OTHER, reject->reason);
2376 /* Perhaps the server has a 'min password age' set? */
2379 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3 (on second random password)");
2380 *password = talloc_strdup(tctx, newpass);
2387 static bool test_GetMembersInAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2388 struct policy_handle *alias_handle)
2390 struct samr_GetMembersInAlias r;
2391 struct lsa_SidArray sids;
2394 torture_comment(tctx, "Testing GetMembersInAlias\n");
2396 r.in.alias_handle = alias_handle;
2399 status = dcerpc_samr_GetMembersInAlias(p, tctx, &r);
2400 torture_assert_ntstatus_ok(tctx, status, "GetMembersInAlias");
2405 static bool test_AddMemberToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2406 struct policy_handle *alias_handle,
2407 const struct dom_sid *domain_sid)
2409 struct samr_AddAliasMember r;
2410 struct samr_DeleteAliasMember d;
2412 struct dom_sid *sid;
2414 sid = dom_sid_add_rid(tctx, domain_sid, 512);
2416 torture_comment(tctx, "testing AddAliasMember\n");
2417 r.in.alias_handle = alias_handle;
2420 status = dcerpc_samr_AddAliasMember(p, tctx, &r);
2421 torture_assert_ntstatus_ok(tctx, status, "AddAliasMember");
2423 d.in.alias_handle = alias_handle;
2426 status = dcerpc_samr_DeleteAliasMember(p, tctx, &d);
2427 torture_assert_ntstatus_ok(tctx, status, "DelAliasMember");
2432 static bool test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2433 struct policy_handle *alias_handle)
2435 struct samr_AddMultipleMembersToAlias a;
2436 struct samr_RemoveMultipleMembersFromAlias r;
2438 struct lsa_SidArray sids;
2440 torture_comment(tctx, "testing AddMultipleMembersToAlias\n");
2441 a.in.alias_handle = alias_handle;
2445 sids.sids = talloc_array(tctx, struct lsa_SidPtr, 3);
2447 sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2448 sids.sids[1].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-2");
2449 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-3");
2451 status = dcerpc_samr_AddMultipleMembersToAlias(p, tctx, &a);
2452 torture_assert_ntstatus_ok(tctx, status, "AddMultipleMembersToAlias");
2455 torture_comment(tctx, "testing RemoveMultipleMembersFromAlias\n");
2456 r.in.alias_handle = alias_handle;
2459 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2460 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2462 /* strange! removing twice doesn't give any error */
2463 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2464 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2466 /* but removing an alias that isn't there does */
2467 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-4");
2469 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2470 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, "RemoveMultipleMembersFromAlias");
2475 static bool test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2476 struct policy_handle *user_handle)
2478 struct samr_TestPrivateFunctionsUser r;
2481 torture_comment(tctx, "Testing TestPrivateFunctionsUser\n");
2483 r.in.user_handle = user_handle;
2485 status = dcerpc_samr_TestPrivateFunctionsUser(p, tctx, &r);
2486 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsUser");
2491 static bool test_QueryUserInfo_pwdlastset(struct dcerpc_pipe *p,
2492 struct torture_context *tctx,
2493 struct policy_handle *handle,
2498 uint16_t levels[] = { /* 3, */ 5, 21 };
2500 NTTIME pwdlastset3 = 0;
2501 NTTIME pwdlastset5 = 0;
2502 NTTIME pwdlastset21 = 0;
2504 torture_comment(tctx, "Testing QueryUserInfo%s level 5 and 21 call ",
2505 use_info2 ? "2":"");
2507 for (i=0; i<ARRAY_SIZE(levels); i++) {
2509 struct samr_QueryUserInfo r;
2510 struct samr_QueryUserInfo2 r2;
2511 union samr_UserInfo *info;
2514 r2.in.user_handle = handle;
2515 r2.in.level = levels[i];
2516 r2.out.info = &info;
2517 status = dcerpc_samr_QueryUserInfo2(p, tctx, &r2);
2520 r.in.user_handle = handle;
2521 r.in.level = levels[i];
2523 status = dcerpc_samr_QueryUserInfo(p, tctx, &r);
2526 if (!NT_STATUS_IS_OK(status) &&
2527 !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
2528 printf("QueryUserInfo%s level %u failed - %s\n",
2529 use_info2 ? "2":"", levels[i], nt_errstr(status));
2533 switch (levels[i]) {
2535 pwdlastset3 = info->info3.last_password_change;
2538 pwdlastset5 = info->info5.last_password_change;
2541 pwdlastset21 = info->info21.last_password_change;
2547 /* torture_assert_int_equal(tctx, pwdlastset3, pwdlastset5,
2548 "pwdlastset mixup"); */
2549 torture_assert_int_equal(tctx, pwdlastset5, pwdlastset21,
2550 "pwdlastset mixup");
2552 *pwdlastset = pwdlastset21;
2554 torture_comment(tctx, "(pwdlastset: %lld)\n", *pwdlastset);
2559 static bool test_SetPassword_level(struct dcerpc_pipe *p,
2560 struct torture_context *tctx,
2561 struct policy_handle *handle,
2563 uint32_t fields_present,
2564 uint8_t password_expired,
2565 bool *matched_expected_error,
2568 bool use_queryinfo2,
2571 const char *fields = NULL;
2578 fields = talloc_asprintf(tctx, "(fields_present: 0x%08x)",
2585 torture_comment(tctx, "Testing SetUserInfo%s level %d call "
2586 "(password_expired: %d) %s\n",
2587 use_setinfo2 ? "2":"", level, password_expired,
2588 fields ? fields : "");
2596 if (!test_SetUserPass_level_ex(p, tctx, handle, level,
2601 matched_expected_error)) {
2609 if (!test_QueryUserInfo_pwdlastset(p, tctx, handle,
2618 static bool test_SetPassword_pwdlastset(struct dcerpc_pipe *p,
2619 struct torture_context *tctx,
2620 uint32_t acct_flags,
2621 struct policy_handle *handle,
2624 int i, s = 0, q = 0, f = 0;
2627 bool set_levels[] = { false, true };
2628 bool query_levels[] = { false, true };
2629 uint32_t fields_present[] = {
2631 SAMR_FIELD_EXPIRED_FLAG,
2632 SAMR_FIELD_LAST_PWD_CHANGE,
2633 SAMR_FIELD_EXPIRED_FLAG | SAMR_FIELD_LAST_PWD_CHANGE,
2635 SAMR_FIELD_NT_PASSWORD_PRESENT,
2636 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
2637 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
2638 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
2639 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
2640 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
2641 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE | SAMR_FIELD_EXPIRED_FLAG
2646 uint8_t password_expired_nonzero;
2652 .password_expired_nonzero = 1,
2655 .password_expired_nonzero = 24,
2660 .password_expired_nonzero = 1,
2663 .password_expired_nonzero = 24,
2669 .password_expired_nonzero = 1,
2672 .password_expired_nonzero = 24,
2678 .password_expired_nonzero = 1,
2681 .password_expired_nonzero = 24
2687 .password_expired_nonzero = 1,
2690 .password_expired_nonzero = 24,
2694 if (torture_setting_bool(tctx, "samba3", false)) {
2696 printf("Samba3 has second granularity, setting delay to: %d\n",
2700 /* set to 1 to enable testing for all possible opcode
2701 (SetUserInfo, SetUserInfo2, QueryUserInfo, QueryUserInfo2)
2704 #define TEST_SET_LEVELS 1
2705 #define TEST_QUERY_LEVELS 1
2707 for (i=0; i<ARRAY_SIZE(pwd_tests); i++) {
2708 for (f=0; f<ARRAY_SIZE(fields_present); f++) {
2709 #ifdef TEST_SET_LEVELS
2710 for (s=0; s<ARRAY_SIZE(set_levels); s++) {
2712 #ifdef TEST_QUERY_LEVELS
2713 for (q=0; q<ARRAY_SIZE(query_levels); q++) {
2715 NTTIME pwdlastset_old = 0;
2716 NTTIME pwdlastset_new = 0;
2717 bool matched_expected_error = false;
2719 torture_comment(tctx, "------------------------------\n"
2720 "Testing pwdLastSet attribute for flags: 0x%08x "
2721 "(s: %d (l: %d), q: %d)\n",
2722 acct_flags, s, pwd_tests[i].level, q);
2726 /* set a password and force password change (pwdlastset 0) by
2727 * setting the password expired flag to a non-0 value */
2729 if (!test_SetPassword_level(p, tctx, handle,
2732 pwd_tests[i].password_expired_nonzero,
2733 &matched_expected_error,
2741 if (matched_expected_error == true) {
2742 /* skipping on expected failure */
2746 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
2747 * set without the SAMR_FIELD_EXPIRED_FLAG */
2749 switch (pwd_tests[i].level) {
2753 if ((pwdlastset_new != 0) &&
2754 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
2755 torture_comment(tctx, "not considering a non-0 "
2756 "pwdLastSet as a an error as the "
2757 "SAMR_FIELD_EXPIRED_FLAG has not "
2762 if (pwdlastset_new != 0) {
2763 torture_warning(tctx, "pwdLastSet test failed: "
2764 "expected pwdLastSet 0 but got %lld\n",
2771 switch (pwd_tests[i].level) {
2775 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
2776 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
2777 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
2778 (pwdlastset_old >= pwdlastset_new)) {
2779 torture_warning(tctx, "pwdlastset not increasing\n");
2784 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
2785 (pwdlastset_old >= pwdlastset_new)) {
2786 torture_warning(tctx, "pwdlastset not increasing\n");
2796 /* set a password, pwdlastset needs to get updated (increased
2797 * value), password_expired value used here is 0 */
2799 if (!test_SetPassword_level(p, tctx, handle,
2803 &matched_expected_error,
2811 /* when a password has been changed, pwdlastset must not be 0 afterwards
2812 * and must be larger then the old value */
2814 switch (pwd_tests[i].level) {
2819 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
2820 * password has been changed, old and new pwdlastset
2821 * need to be the same value */
2823 if (!(pwd_tests[i].fields_present & SAMR_FIELD_EXPIRED_FLAG) &&
2824 !((pwd_tests[i].fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
2825 (pwd_tests[i].fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)))
2827 torture_assert_int_equal(tctx, pwdlastset_old,
2828 pwdlastset_new, "pwdlastset must be equal");
2832 if (pwdlastset_old >= pwdlastset_new) {
2833 torture_warning(tctx, "pwdLastSet test failed: "
2834 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
2835 pwdlastset_old, pwdlastset_new);
2838 if (pwdlastset_new == 0) {
2839 torture_warning(tctx, "pwdLastSet test failed: "
2840 "expected non-0 pwdlastset, got: %lld\n",
2846 switch (pwd_tests[i].level) {
2850 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
2851 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
2852 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
2853 (pwdlastset_old >= pwdlastset_new)) {
2854 torture_warning(tctx, "pwdlastset not increasing\n");
2859 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
2860 (pwdlastset_old >= pwdlastset_new)) {
2861 torture_warning(tctx, "pwdlastset not increasing\n");
2867 pwdlastset_old = pwdlastset_new;
2873 /* set a password, pwdlastset needs to get updated (increased
2874 * value), password_expired value used here is 0 */
2876 if (!test_SetPassword_level(p, tctx, handle,
2880 &matched_expected_error,
2888 /* when a password has been changed, pwdlastset must not be 0 afterwards
2889 * and must be larger then the old value */
2891 switch (pwd_tests[i].level) {
2896 /* if no password has been changed, old and new pwdlastset
2897 * need to be the same value */
2899 if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
2900 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
2902 torture_assert_int_equal(tctx, pwdlastset_old,
2903 pwdlastset_new, "pwdlastset must be equal");
2907 if (pwdlastset_old >= pwdlastset_new) {
2908 torture_warning(tctx, "pwdLastSet test failed: "
2909 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
2910 pwdlastset_old, pwdlastset_new);
2913 if (pwdlastset_new == 0) {
2914 torture_warning(tctx, "pwdLastSet test failed: "
2915 "expected non-0 pwdlastset, got: %lld\n",
2923 /* set a password and force password change (pwdlastset 0) by
2924 * setting the password expired flag to a non-0 value */
2926 if (!test_SetPassword_level(p, tctx, handle,
2929 pwd_tests[i].password_expired_nonzero,
2930 &matched_expected_error,
2938 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
2939 * set without the SAMR_FIELD_EXPIRED_FLAG */
2941 switch (pwd_tests[i].level) {
2945 if ((pwdlastset_new != 0) &&
2946 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
2947 torture_comment(tctx, "not considering a non-0 "
2948 "pwdLastSet as a an error as the "
2949 "SAMR_FIELD_EXPIRED_FLAG has not "
2954 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
2955 * password has been changed, old and new pwdlastset
2956 * need to be the same value */
2958 if (!(pwd_tests[i].fields_present & SAMR_FIELD_EXPIRED_FLAG) &&
2959 !((pwd_tests[i].fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
2960 (pwd_tests[i].fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)))
2962 torture_assert_int_equal(tctx, pwdlastset_old,
2963 pwdlastset_new, "pwdlastset must be equal");
2968 if (pwdlastset_old == pwdlastset_new) {
2969 torture_warning(tctx, "pwdLastSet test failed: "
2970 "expected last pwdlastset (%lld) != new pwdlastset (%lld)\n",
2971 pwdlastset_old, pwdlastset_new);
2975 if (pwdlastset_new != 0) {
2976 torture_warning(tctx, "pwdLastSet test failed: "
2977 "expected pwdLastSet 0, got %lld\n",
2984 switch (pwd_tests[i].level) {
2988 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
2989 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
2990 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
2991 (pwdlastset_old >= pwdlastset_new)) {
2992 torture_warning(tctx, "pwdlastset not increasing\n");
2997 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
2998 (pwdlastset_old >= pwdlastset_new)) {
2999 torture_warning(tctx, "pwdlastset not increasing\n");
3005 switch (pwd_tests[i].level) {
3008 f = ARRAY_SIZE(fields_present);
3012 #ifdef TEST_QUERY_LEVELS
3015 #ifdef TEST_SET_LEVELS
3021 #undef TEST_SET_LEVELS
3022 #undef TEST_QUERY_LEVELS
3027 static bool test_user_ops(struct dcerpc_pipe *p,
3028 struct torture_context *tctx,
3029 struct policy_handle *user_handle,
3030 struct policy_handle *domain_handle,
3031 uint32_t base_acct_flags,
3032 const char *base_acct_name, enum torture_samr_choice which_ops)
3034 char *password = NULL;
3035 struct samr_QueryUserInfo q;
3036 union samr_UserInfo *info;
3042 const uint32_t password_fields[] = {
3043 SAMR_FIELD_NT_PASSWORD_PRESENT,
3044 SAMR_FIELD_LM_PASSWORD_PRESENT,
3045 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
3049 status = test_LookupName(p, tctx, domain_handle, base_acct_name, &rid);
3050 if (!NT_STATUS_IS_OK(status)) {
3054 switch (which_ops) {
3055 case TORTURE_SAMR_USER_ATTRIBUTES:
3056 if (!test_QuerySecurity(p, tctx, user_handle)) {
3060 if (!test_QueryUserInfo(p, tctx, user_handle)) {
3064 if (!test_QueryUserInfo2(p, tctx, user_handle)) {
3068 if (!test_SetUserInfo(p, tctx, user_handle, base_acct_flags,
3073 if (!test_GetUserPwInfo(p, tctx, user_handle)) {
3077 if (!test_TestPrivateFunctionsUser(p, tctx, user_handle)) {
3081 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
3085 case TORTURE_SAMR_PASSWORDS:
3086 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
3087 char simple_pass[9];
3088 char *v = generate_random_str(tctx, 1);
3090 ZERO_STRUCT(simple_pass);
3091 memset(simple_pass, *v, sizeof(simple_pass) - 1);
3093 printf("Testing machine account password policy rules\n");
3095 /* Workstation trust accounts don't seem to need to honour password quality policy */
3096 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
3100 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
3104 /* reset again, to allow another 'user' password change */
3105 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
3109 /* Try a 'short' password */
3110 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
3114 /* Try a compleatly random password */
3115 if (!test_ChangePasswordRandomBytes(p, tctx, base_acct_name, user_handle, &password)) {
3120 for (i = 0; password_fields[i]; i++) {
3121 if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
3125 /* check it was set right */
3126 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3131 for (i = 0; password_fields[i]; i++) {
3132 if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
3136 /* check it was set right */
3137 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3142 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
3146 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
3150 if (torture_setting_bool(tctx, "samba4", false)) {
3151 printf("skipping Set Password level 18 and 21 against Samba4\n");
3154 if (!test_SetUserPass_18(p, tctx, user_handle, &password)) {
3158 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3162 for (i = 0; password_fields[i]; i++) {
3164 if (password_fields[i] == SAMR_FIELD_LM_PASSWORD_PRESENT) {
3165 /* we need to skip as that would break
3166 * the ChangePasswordUser3 verify */
3170 if (!test_SetUserPass_21(p, tctx, user_handle, password_fields[i], &password)) {
3174 /* check it was set right */
3175 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3181 q.in.user_handle = user_handle;
3185 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
3186 if (!NT_STATUS_IS_OK(status)) {
3187 printf("QueryUserInfo level %u failed - %s\n",
3188 q.in.level, nt_errstr(status));
3191 uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
3192 if ((info->info5.acct_flags) != expected_flags) {
3193 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
3194 info->info5.acct_flags,
3198 if (info->info5.rid != rid) {
3199 printf("QuerUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
3200 info->info5.rid, rid);
3207 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
3209 /* test last password change timestamp behaviour */
3210 if (!test_SetPassword_pwdlastset(p, tctx, base_acct_flags,
3211 user_handle, &password)) {
3216 torture_comment(tctx, "pwdLastSet test succeeded\n");
3218 torture_warning(tctx, "pwdLastSet test failed\n");
3223 case TORTURE_SAMR_OTHER:
3224 /* We just need the account to exist */
3230 static bool test_alias_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
3231 struct policy_handle *alias_handle,
3232 const struct dom_sid *domain_sid)
3236 if (!test_QuerySecurity(p, tctx, alias_handle)) {
3240 if (!test_QueryAliasInfo(p, tctx, alias_handle)) {
3244 if (!test_SetAliasInfo(p, tctx, alias_handle)) {
3248 if (!test_AddMemberToAlias(p, tctx, alias_handle, domain_sid)) {
3252 if (torture_setting_bool(tctx, "samba4", false)) {
3253 printf("skipping MultipleMembers Alias tests against Samba4\n");
3257 if (!test_AddMultipleMembersToAlias(p, tctx, alias_handle)) {
3265 static bool test_DeleteUser(struct dcerpc_pipe *p, struct torture_context *tctx,
3266 struct policy_handle *user_handle)
3268 struct samr_DeleteUser d;
3270 torture_comment(tctx, "Testing DeleteUser\n");
3272 d.in.user_handle = user_handle;
3273 d.out.user_handle = user_handle;
3275 status = dcerpc_samr_DeleteUser(p, tctx, &d);
3276 torture_assert_ntstatus_ok(tctx, status, "DeleteUser");
3281 bool test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3282 struct policy_handle *handle, const char *name)
3285 struct samr_DeleteUser d;
3286 struct policy_handle user_handle;
3289 status = test_LookupName(p, mem_ctx, handle, name, &rid);
3290 if (!NT_STATUS_IS_OK(status)) {
3294 status = test_OpenUser_byname(p, mem_ctx, handle, name, &user_handle);
3295 if (!NT_STATUS_IS_OK(status)) {
3299 d.in.user_handle = &user_handle;
3300 d.out.user_handle = &user_handle;
3301 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
3302 if (!NT_STATUS_IS_OK(status)) {
3309 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
3314 static bool test_DeleteGroup_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3315 struct policy_handle *handle, const char *name)
3318 struct samr_OpenGroup r;
3319 struct samr_DeleteDomainGroup d;
3320 struct policy_handle group_handle;
3323 status = test_LookupName(p, mem_ctx, handle, name, &rid);
3324 if (!NT_STATUS_IS_OK(status)) {
3328 r.in.domain_handle = handle;
3329 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3331 r.out.group_handle = &group_handle;
3332 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
3333 if (!NT_STATUS_IS_OK(status)) {
3337 d.in.group_handle = &group_handle;
3338 d.out.group_handle = &group_handle;
3339 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
3340 if (!NT_STATUS_IS_OK(status)) {
3347 printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
3352 static bool test_DeleteAlias_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3353 struct policy_handle *domain_handle, const char *name)
3356 struct samr_OpenAlias r;
3357 struct samr_DeleteDomAlias d;
3358 struct policy_handle alias_handle;
3361 printf("testing DeleteAlias_byname\n");
3363 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
3364 if (!NT_STATUS_IS_OK(status)) {
3368 r.in.domain_handle = domain_handle;
3369 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3371 r.out.alias_handle = &alias_handle;
3372 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
3373 if (!NT_STATUS_IS_OK(status)) {
3377 d.in.alias_handle = &alias_handle;
3378 d.out.alias_handle = &alias_handle;
3379 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
3380 if (!NT_STATUS_IS_OK(status)) {
3387 printf("DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
3391 static bool test_DeleteAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3392 struct policy_handle *alias_handle)
3394 struct samr_DeleteDomAlias d;
3397 printf("Testing DeleteAlias\n");
3399 d.in.alias_handle = alias_handle;
3400 d.out.alias_handle = alias_handle;
3402 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
3403 if (!NT_STATUS_IS_OK(status)) {
3404 printf("DeleteAlias failed - %s\n", nt_errstr(status));
3411 static bool test_CreateAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
3412 struct policy_handle *domain_handle,
3413 struct policy_handle *alias_handle,
3414 const struct dom_sid *domain_sid)
3417 struct samr_CreateDomAlias r;
3418 struct lsa_String name;
3422 init_lsa_String(&name, TEST_ALIASNAME);
3423 r.in.domain_handle = domain_handle;
3424 r.in.alias_name = &name;
3425 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3426 r.out.alias_handle = alias_handle;
3429 printf("Testing CreateAlias (%s)\n", r.in.alias_name->string);
3431 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
3433 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
3434 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
3435 printf("Server correctly refused create of '%s'\n", r.in.alias_name->string);
3438 printf("Server should have refused create of '%s', got %s instead\n", r.in.alias_name->string,
3444 if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
3445 if (!test_DeleteAlias_byname(p, tctx, domain_handle, r.in.alias_name->string)) {
3448 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
3451 if (!NT_STATUS_IS_OK(status)) {
3452 printf("CreateAlias failed - %s\n", nt_errstr(status));
3456 if (!test_alias_ops(p, tctx, alias_handle, domain_sid)) {
3463 static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3464 const char *acct_name,
3465 struct policy_handle *domain_handle, char **password)
3473 if (!test_ChangePasswordUser(p, mem_ctx, acct_name, domain_handle, password)) {
3477 if (!test_ChangePasswordUser2(p, mem_ctx, acct_name, password, 0, true)) {
3481 if (!test_OemChangePasswordUser2(p, mem_ctx, acct_name, domain_handle, password)) {
3485 /* test what happens when setting the old password again */
3486 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, *password, 0, true)) {
3491 char simple_pass[9];
3492 char *v = generate_random_str(mem_ctx, 1);
3494 ZERO_STRUCT(simple_pass);
3495 memset(simple_pass, *v, sizeof(simple_pass) - 1);
3497 /* test what happens when picking a simple password */
3498 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, simple_pass, 0, true)) {
3503 /* set samr_SetDomainInfo level 1 with min_length 5 */
3505 struct samr_QueryDomainInfo r;
3506 union samr_DomainInfo *info = NULL;
3507 struct samr_SetDomainInfo s;
3508 uint16_t len_old, len;
3509 uint32_t pwd_prop_old;
3510 int64_t min_pwd_age_old;
3515 r.in.domain_handle = domain_handle;
3519 printf("testing samr_QueryDomainInfo level 1\n");
3520 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
3521 if (!NT_STATUS_IS_OK(status)) {
3525 s.in.domain_handle = domain_handle;
3529 /* remember the old min length, so we can reset it */
3530 len_old = s.in.info->info1.min_password_length;
3531 s.in.info->info1.min_password_length = len;
3532 pwd_prop_old = s.in.info->info1.password_properties;
3533 /* turn off password complexity checks for this test */
3534 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
3536 min_pwd_age_old = s.in.info->info1.min_password_age;
3537 s.in.info->info1.min_password_age = 0;
3539 printf("testing samr_SetDomainInfo level 1\n");
3540 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
3541 if (!NT_STATUS_IS_OK(status)) {
3545 printf("calling test_ChangePasswordUser3 with too short password\n");
3547 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, len - 1, password, NULL, 0, true)) {
3551 s.in.info->info1.min_password_length = len_old;
3552 s.in.info->info1.password_properties = pwd_prop_old;
3553 s.in.info->info1.min_password_age = min_pwd_age_old;
3555 printf("testing samr_SetDomainInfo level 1\n");
3556 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
3557 if (!NT_STATUS_IS_OK(status)) {
3565 struct samr_OpenUser r;
3566 struct samr_QueryUserInfo q;
3567 union samr_UserInfo *info;
3568 struct samr_LookupNames n;
3569 struct policy_handle user_handle;
3570 struct samr_Ids rids, types;
3572 n.in.domain_handle = domain_handle;
3574 n.in.names = talloc_array(mem_ctx, struct lsa_String, 1);
3575 n.in.names[0].string = acct_name;
3577 n.out.types = &types;
3579 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
3580 if (!NT_STATUS_IS_OK(status)) {
3581 printf("LookupNames failed - %s\n", nt_errstr(status));
3585 r.in.domain_handle = domain_handle;
3586 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3587 r.in.rid = n.out.rids->ids[0];
3588 r.out.user_handle = &user_handle;
3590 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3591 if (!NT_STATUS_IS_OK(status)) {
3592 printf("OpenUser(%u) failed - %s\n", n.out.rids->ids[0], nt_errstr(status));
3596 q.in.user_handle = &user_handle;
3600 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
3601 if (!NT_STATUS_IS_OK(status)) {
3602 printf("QueryUserInfo failed - %s\n", nt_errstr(status));
3606 printf("calling test_ChangePasswordUser3 with too early password change\n");
3608 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL,
3609 info->info5.last_password_change, true)) {
3614 /* we change passwords twice - this has the effect of verifying
3615 they were changed correctly for the final call */
3616 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, true)) {
3620 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, true)) {
3627 static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
3628 struct policy_handle *domain_handle,
3629 struct policy_handle *user_handle_out,
3630 struct dom_sid *domain_sid,
3631 enum torture_samr_choice which_ops)
3634 TALLOC_CTX *user_ctx;
3637 struct samr_CreateUser r;
3638 struct samr_QueryUserInfo q;
3639 union samr_UserInfo *info;
3640 struct samr_DeleteUser d;
3643 /* This call creates a 'normal' account - check that it really does */
3644 const uint32_t acct_flags = ACB_NORMAL;
3645 struct lsa_String name;
3648 struct policy_handle user_handle;
3649 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
3650 init_lsa_String(&name, TEST_ACCOUNT_NAME);
3652 r.in.domain_handle = domain_handle;
3653 r.in.account_name = &name;
3654 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3655 r.out.user_handle = &user_handle;
3658 printf("Testing CreateUser(%s)\n", r.in.account_name->string);
3660 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
3662 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
3663 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
3664 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
3667 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
3673 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
3674 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
3675 talloc_free(user_ctx);
3678 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
3680 if (!NT_STATUS_IS_OK(status)) {
3681 talloc_free(user_ctx);
3682 printf("CreateUser failed - %s\n", nt_errstr(status));
3685 q.in.user_handle = &user_handle;
3689 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
3690 if (!NT_STATUS_IS_OK(status)) {
3691 printf("QueryUserInfo level %u failed - %s\n",
3692 q.in.level, nt_errstr(status));
3695 if ((info->info16.acct_flags & acct_flags) != acct_flags) {
3696 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
3697 info->info16.acct_flags,
3703 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
3704 acct_flags, name.string, which_ops)) {
3708 if (user_handle_out) {
3709 *user_handle_out = user_handle;
3711 printf("Testing DeleteUser (createuser test)\n");
3713 d.in.user_handle = &user_handle;
3714 d.out.user_handle = &user_handle;
3716 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
3717 if (!NT_STATUS_IS_OK(status)) {
3718 printf("DeleteUser failed - %s\n", nt_errstr(status));
3725 talloc_free(user_ctx);
3731 static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
3732 struct policy_handle *domain_handle,
3733 struct dom_sid *domain_sid,
3734 enum torture_samr_choice which_ops)
3737 struct samr_CreateUser2 r;
3738 struct samr_QueryUserInfo q;
3739 union samr_UserInfo *info;
3740 struct samr_DeleteUser d;
3741 struct policy_handle user_handle;
3743 struct lsa_String name;
3748 uint32_t acct_flags;
3749 const char *account_name;
3751 } account_types[] = {
3752 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
3753 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
3754 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
3755 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
3756 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
3757 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
3758 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
3759 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
3760 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
3761 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
3762 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
3763 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
3764 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
3765 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
3766 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
3769 for (i = 0; account_types[i].account_name; i++) {
3770 TALLOC_CTX *user_ctx;
3771 uint32_t acct_flags = account_types[i].acct_flags;
3772 uint32_t access_granted;
3773 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
3774 init_lsa_String(&name, account_types[i].account_name);
3776 r.in.domain_handle = domain_handle;
3777 r.in.account_name = &name;
3778 r.in.acct_flags = acct_flags;
3779 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3780 r.out.user_handle = &user_handle;
3781 r.out.access_granted = &access_granted;
3784 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
3786 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
3788 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
3789 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
3790 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
3793 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
3800 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
3801 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
3802 talloc_free(user_ctx);
3806 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
3809 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
3810 printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
3811 nt_errstr(status), nt_errstr(account_types[i].nt_status));
3815 if (NT_STATUS_IS_OK(status)) {
3816 q.in.user_handle = &user_handle;
3820 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
3821 if (!NT_STATUS_IS_OK(status)) {
3822 printf("QueryUserInfo level %u failed - %s\n",
3823 q.in.level, nt_errstr(status));
3826 uint32_t expected_flags = (acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
3827 if (acct_flags == ACB_NORMAL) {
3828 expected_flags |= ACB_PW_EXPIRED;
3830 if ((info->info5.acct_flags) != expected_flags) {
3831 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
3832 info->info5.acct_flags,
3836 switch (acct_flags) {
3838 if (info->info5.primary_gid != DOMAIN_RID_DCS) {
3839 printf("QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n",
3840 DOMAIN_RID_DCS, info->info5.primary_gid);
3845 if (info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
3846 printf("QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
3847 DOMAIN_RID_DOMAIN_MEMBERS, info->info5.primary_gid);
3852 if (info->info5.primary_gid != DOMAIN_RID_USERS) {
3853 printf("QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n",
3854 DOMAIN_RID_USERS, info->info5.primary_gid);
3861 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
3862 acct_flags, name.string, which_ops)) {
3866 printf("Testing DeleteUser (createuser2 test)\n");
3868 d.in.user_handle = &user_handle;
3869 d.out.user_handle = &user_handle;
3871 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
3872 if (!NT_STATUS_IS_OK(status)) {
3873 printf("DeleteUser failed - %s\n", nt_errstr(status));
3877 talloc_free(user_ctx);
3883 static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3884 struct policy_handle *handle)
3887 struct samr_QueryAliasInfo r;
3888 union samr_AliasInfo *info;
3889 uint16_t levels[] = {1, 2, 3};
3893 for (i=0;i<ARRAY_SIZE(levels);i++) {
3894 printf("Testing QueryAliasInfo level %u\n", levels[i]);
3896 r.in.alias_handle = handle;
3897 r.in.level = levels[i];
3900 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
3901 if (!NT_STATUS_IS_OK(status)) {
3902 printf("QueryAliasInfo level %u failed - %s\n",
3903 levels[i], nt_errstr(status));
3911 static bool test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3912 struct policy_handle *handle)
3915 struct samr_QueryGroupInfo r;
3916 union samr_GroupInfo *info;
3917 uint16_t levels[] = {1, 2, 3, 4, 5};
3921 for (i=0;i<ARRAY_SIZE(levels);i++) {
3922 printf("Testing QueryGroupInfo level %u\n", levels[i]);
3924 r.in.group_handle = handle;
3925 r.in.level = levels[i];
3928 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
3929 if (!NT_STATUS_IS_OK(status)) {
3930 printf("QueryGroupInfo level %u failed - %s\n",
3931 levels[i], nt_errstr(status));
3939 static bool test_QueryGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3940 struct policy_handle *handle)
3943 struct samr_QueryGroupMember r;
3944 struct samr_RidTypeArray *rids = NULL;
3947 printf("Testing QueryGroupMember\n");
3949 r.in.group_handle = handle;
3952 status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &r);
3953 if (!NT_STATUS_IS_OK(status)) {
3954 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
3962 static bool test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3963 struct policy_handle *handle)
3966 struct samr_QueryGroupInfo r;
3967 union samr_GroupInfo *info;
3968 struct samr_SetGroupInfo s;
3969 uint16_t levels[] = {1, 2, 3, 4};
3970 uint16_t set_ok[] = {0, 1, 1, 1};
3974 for (i=0;i<ARRAY_SIZE(levels);i++) {
3975 printf("Testing QueryGroupInfo level %u\n", levels[i]);
3977 r.in.group_handle = handle;
3978 r.in.level = levels[i];
3981 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
3982 if (!NT_STATUS_IS_OK(status)) {
3983 printf("QueryGroupInfo level %u failed - %s\n",
3984 levels[i], nt_errstr(status));
3988 printf("Testing SetGroupInfo level %u\n", levels[i]);
3990 s.in.group_handle = handle;
3991 s.in.level = levels[i];
3992 s.in.info = *r.out.info;
3995 /* disabled this, as it changes the name only from the point of view of samr,
3996 but leaves the name from the point of view of w2k3 internals (and ldap). This means
3997 the name is still reserved, so creating the old name fails, but deleting by the old name
3999 if (s.in.level == 2) {
4000 init_lsa_String(&s.in.info->string, "NewName");
4004 if (s.in.level == 4) {
4005 init_lsa_String(&s.in.info->description, "test description");
4008 status = dcerpc_samr_SetGroupInfo(p, mem_ctx, &s);
4010 if (!NT_STATUS_IS_OK(status)) {
4011 printf("SetGroupInfo level %u failed - %s\n",
4012 r.in.level, nt_errstr(status));
4017 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
4018 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
4019 r.in.level, nt_errstr(status));
4029 static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4030 struct policy_handle *handle)
4033 struct samr_QueryUserInfo r;
4034 union samr_UserInfo *info;
4035 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
4036 11, 12, 13, 14, 16, 17, 20, 21};
4040 for (i=0;i<ARRAY_SIZE(levels);i++) {
4041 printf("Testing QueryUserInfo level %u\n", levels[i]);
4043 r.in.user_handle = handle;
4044 r.in.level = levels[i];
4047 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
4048 if (!NT_STATUS_IS_OK(status)) {
4049 printf("QueryUserInfo level %u failed - %s\n",
4050 levels[i], nt_errstr(status));
4058 static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4059 struct policy_handle *handle)
4062 struct samr_QueryUserInfo2 r;
4063 union samr_UserInfo *info;
4064 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
4065 11, 12, 13, 14, 16, 17, 20, 21};
4069 for (i=0;i<ARRAY_SIZE(levels);i++) {
4070 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
4072 r.in.user_handle = handle;
4073 r.in.level = levels[i];
4076 status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r);
4077 if (!NT_STATUS_IS_OK(status)) {
4078 printf("QueryUserInfo2 level %u failed - %s\n",
4079 levels[i], nt_errstr(status));
4087 static bool test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4088 struct policy_handle *handle, uint32_t rid)
4091 struct samr_OpenUser r;
4092 struct policy_handle user_handle;
4095 printf("Testing OpenUser(%u)\n", rid);
4097 r.in.domain_handle = handle;
4098 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4100 r.out.user_handle = &user_handle;
4102 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
4103 if (!NT_STATUS_IS_OK(status)) {
4104 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
4108 if (!test_QuerySecurity(p, mem_ctx, &user_handle)) {
4112 if (!test_QueryUserInfo(p, mem_ctx, &user_handle)) {
4116 if (!test_QueryUserInfo2(p, mem_ctx, &user_handle)) {
4120 if (!test_GetUserPwInfo(p, mem_ctx, &user_handle)) {
4124 if (!test_GetGroupsForUser(p,mem_ctx, &user_handle)) {
4128 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
4135 static bool test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4136 struct policy_handle *handle, uint32_t rid)
4139 struct samr_OpenGroup r;
4140 struct policy_handle group_handle;
4143 printf("Testing OpenGroup(%u)\n", rid);
4145 r.in.domain_handle = handle;
4146 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4148 r.out.group_handle = &group_handle;
4150 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
4151 if (!NT_STATUS_IS_OK(status)) {
4152 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
4156 if (!test_QuerySecurity(p, mem_ctx, &group_handle)) {
4160 if (!test_QueryGroupInfo(p, mem_ctx, &group_handle)) {
4164 if (!test_QueryGroupMember(p, mem_ctx, &group_handle)) {
4168 if (!test_samr_handle_Close(p, mem_ctx, &group_handle)) {
4175 static bool test_OpenAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
4176 struct policy_handle *handle, uint32_t rid)
4179 struct samr_OpenAlias r;
4180 struct policy_handle alias_handle;
4183 torture_comment(tctx, "Testing OpenAlias(%u)\n", rid);
4185 r.in.domain_handle = handle;
4186 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4188 r.out.alias_handle = &alias_handle;
4190 status = dcerpc_samr_OpenAlias(p, tctx, &r);
4191 if (!NT_STATUS_IS_OK(status)) {
4192 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
4196 if (!test_QuerySecurity(p, tctx, &alias_handle)) {
4200 if (!test_QueryAliasInfo(p, tctx, &alias_handle)) {
4204 if (!test_GetMembersInAlias(p, tctx, &alias_handle)) {
4208 if (!test_samr_handle_Close(p, tctx, &alias_handle)) {
4215 static bool check_mask(struct dcerpc_pipe *p, struct torture_context *tctx,
4216 struct policy_handle *handle, uint32_t rid,
4217 uint32_t acct_flag_mask)
4220 struct samr_OpenUser r;
4221 struct samr_QueryUserInfo q;
4222 union samr_UserInfo *info;
4223 struct policy_handle user_handle;
4226 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
4228 r.in.domain_handle = handle;
4229 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4231 r.out.user_handle = &user_handle;
4233 status = dcerpc_samr_OpenUser(p, tctx, &r);
4234 if (!NT_STATUS_IS_OK(status)) {
4235 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
4239 q.in.user_handle = &user_handle;
4243 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
4244 if (!NT_STATUS_IS_OK(status)) {
4245 printf("QueryUserInfo level 16 failed - %s\n",
4249 if ((acct_flag_mask & info->info16.acct_flags) == 0) {
4250 printf("Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
4251 acct_flag_mask, info->info16.acct_flags, rid);
4256 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
4263 static bool test_EnumDomainUsers(struct dcerpc_pipe *p, struct torture_context *tctx,
4264 struct policy_handle *handle)
4266 NTSTATUS status = STATUS_MORE_ENTRIES;
4267 struct samr_EnumDomainUsers r;
4268 uint32_t mask, resume_handle=0;
4271 struct samr_LookupNames n;
4272 struct samr_LookupRids lr ;
4273 struct lsa_Strings names;
4274 struct samr_Ids rids, types;
4275 struct samr_SamArray *sam = NULL;
4276 uint32_t num_entries = 0;
4278 uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
4279 ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
4280 ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
4283 printf("Testing EnumDomainUsers\n");
4285 for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
4286 r.in.domain_handle = handle;
4287 r.in.resume_handle = &resume_handle;
4288 r.in.acct_flags = mask = masks[mask_idx];
4289 r.in.max_size = (uint32_t)-1;
4290 r.out.resume_handle = &resume_handle;
4291 r.out.num_entries = &num_entries;
4294 status = dcerpc_samr_EnumDomainUsers(p, tctx, &r);
4295 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
4296 !NT_STATUS_IS_OK(status)) {
4297 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
4301 torture_assert(tctx, sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
4303 if (sam->count == 0) {
4307 for (i=0;i<sam->count;i++) {
4309 if (!check_mask(p, tctx, handle, sam->entries[i].idx, mask)) {
4312 } else if (!test_OpenUser(p, tctx, handle, sam->entries[i].idx)) {
4318 printf("Testing LookupNames\n");
4319 n.in.domain_handle = handle;
4320 n.in.num_names = sam->count;
4321 n.in.names = talloc_array(tctx, struct lsa_String, sam->count);
4323 n.out.types = &types;
4324 for (i=0;i<sam->count;i++) {
4325 n.in.names[i].string = sam->entries[i].name.string;
4327 status = dcerpc_samr_LookupNames(p, tctx, &n);
4328 if (!NT_STATUS_IS_OK(status)) {
4329 printf("LookupNames failed - %s\n", nt_errstr(status));
4334 printf("Testing LookupRids\n");
4335 lr.in.domain_handle = handle;
4336 lr.in.num_rids = sam->count;
4337 lr.in.rids = talloc_array(tctx, uint32_t, sam->count);
4338 lr.out.names = &names;
4339 lr.out.types = &types;
4340 for (i=0;i<sam->count;i++) {
4341 lr.in.rids[i] = sam->entries[i].idx;
4343 status = dcerpc_samr_LookupRids(p, tctx, &lr);
4344 torture_assert_ntstatus_ok(tctx, status, "LookupRids");
4350 try blasting the server with a bunch of sync requests
4352 static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, struct torture_context *tctx,
4353 struct policy_handle *handle)
4356 struct samr_EnumDomainUsers r;
4357 uint32_t resume_handle=0;
4359 #define ASYNC_COUNT 100
4360 struct rpc_request *req[ASYNC_COUNT];
4362 if (!torture_setting_bool(tctx, "dangerous", false)) {
4363 torture_skip(tctx, "samr async test disabled - enable dangerous tests to use\n");
4366 torture_comment(tctx, "Testing EnumDomainUsers_async\n");
4368 r.in.domain_handle = handle;
4369 r.in.resume_handle = &resume_handle;
4370 r.in.acct_flags = 0;
4371 r.in.max_size = (uint32_t)-1;
4372 r.out.resume_handle = &resume_handle;
4374 for (i=0;i<ASYNC_COUNT;i++) {
4375 req[i] = dcerpc_samr_EnumDomainUsers_send(p, tctx, &r);
4378 for (i=0;i<ASYNC_COUNT;i++) {
4379 status = dcerpc_ndr_request_recv(req[i]);
4380 if (!NT_STATUS_IS_OK(status)) {
4381 printf("EnumDomainUsers[%d] failed - %s\n",
4382 i, nt_errstr(status));
4387 torture_comment(tctx, "%d async requests OK\n", i);
4392 static bool test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4393 struct policy_handle *handle)
4396 struct samr_EnumDomainGroups r;
4397 uint32_t resume_handle=0;
4398 struct samr_SamArray *sam = NULL;
4399 uint32_t num_entries = 0;
4403 printf("Testing EnumDomainGroups\n");
4405 r.in.domain_handle = handle;
4406 r.in.resume_handle = &resume_handle;
4407 r.in.max_size = (uint32_t)-1;
4408 r.out.resume_handle = &resume_handle;
4409 r.out.num_entries = &num_entries;
4412 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
4413 if (!NT_STATUS_IS_OK(status)) {
4414 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
4422 for (i=0;i<sam->count;i++) {
4423 if (!test_OpenGroup(p, mem_ctx, handle, sam->entries[i].idx)) {
4431 static bool test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4432 struct policy_handle *handle)
4435 struct samr_EnumDomainAliases r;
4436 uint32_t resume_handle=0;
4437 struct samr_SamArray *sam = NULL;
4438 uint32_t num_entries = 0;
4442 printf("Testing EnumDomainAliases\n");
4444 r.in.domain_handle = handle;
4445 r.in.resume_handle = &resume_handle;
4446 r.in.max_size = (uint32_t)-1;
4448 r.out.num_entries = &num_entries;
4449 r.out.resume_handle = &resume_handle;
4451 status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
4452 if (!NT_STATUS_IS_OK(status)) {
4453 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
4461 for (i=0;i<sam->count;i++) {
4462 if (!test_OpenAlias(p, mem_ctx, handle, sam->entries[i].idx)) {
4470 static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4471 struct policy_handle *handle)
4474 struct samr_GetDisplayEnumerationIndex r;
4476 uint16_t levels[] = {1, 2, 3, 4, 5};
4477 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
4478 struct lsa_String name;
4482 for (i=0;i<ARRAY_SIZE(levels);i++) {
4483 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
4485 init_lsa_String(&name, TEST_ACCOUNT_NAME);
4487 r.in.domain_handle = handle;
4488 r.in.level = levels[i];
4492 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
4495 !NT_STATUS_IS_OK(status) &&
4496 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
4497 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
4498 levels[i], nt_errstr(status));
4502 init_lsa_String(&name, "zzzzzzzz");
4504 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
4506 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
4507 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
4508 levels[i], nt_errstr(status));
4516 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4517 struct policy_handle *handle)
4520 struct samr_GetDisplayEnumerationIndex2 r;
4522 uint16_t levels[] = {1, 2, 3, 4, 5};
4523 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
4524 struct lsa_String name;
4528 for (i=0;i<ARRAY_SIZE(levels);i++) {
4529 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
4531 init_lsa_String(&name, TEST_ACCOUNT_NAME);
4533 r.in.domain_handle = handle;
4534 r.in.level = levels[i];
4538 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
4540 !NT_STATUS_IS_OK(status) &&
4541 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
4542 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
4543 levels[i], nt_errstr(status));
4547 init_lsa_String(&name, "zzzzzzzz");
4549 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
4550 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
4551 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
4552 levels[i], nt_errstr(status));
4560 #define STRING_EQUAL_QUERY(s1, s2, user) \
4561 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
4562 /* odd, but valid */ \
4563 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
4564 printf("%s mismatch for %s: %s != %s (%s)\n", \
4565 #s1, user.string, s1.string, s2.string, __location__); \
4568 #define INT_EQUAL_QUERY(s1, s2, user) \
4570 printf("%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
4571 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
4575 static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4576 struct samr_QueryDisplayInfo *querydisplayinfo,
4577 bool *seen_testuser)
4579 struct samr_OpenUser r;
4580 struct samr_QueryUserInfo q;
4581 union samr_UserInfo *info;
4582 struct policy_handle user_handle;
4585 r.in.domain_handle = querydisplayinfo->in.domain_handle;
4586 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4587 for (i = 0; ; i++) {
4588 switch (querydisplayinfo->in.level) {
4590 if (i >= querydisplayinfo->out.info->info1.count) {
4593 r.in.rid = querydisplayinfo->out.info->info1.entries[i].rid;
4596 if (i >= querydisplayinfo->out.info->info2.count) {
4599 r.in.rid = querydisplayinfo->out.info->info2.entries[i].rid;
4605 /* Not interested in validating just the account name */
4609 r.out.user_handle = &user_handle;
4611 switch (querydisplayinfo->in.level) {
4614 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
4615 if (!NT_STATUS_IS_OK(status)) {
4616 printf("OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(status));
4621 q.in.user_handle = &user_handle;
4624 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
4625 if (!NT_STATUS_IS_OK(status)) {
4626 printf("QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(status));
4630 switch (querydisplayinfo->in.level) {
4632 if (seen_testuser && strcmp(info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
4633 *seen_testuser = true;
4635 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].full_name,
4636 info->info21.full_name, info->info21.account_name);
4637 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].account_name,
4638 info->info21.account_name, info->info21.account_name);
4639 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].description,
4640 info->info21.description, info->info21.account_name);
4641 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].rid,
4642 info->info21.rid, info->info21.account_name);
4643 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].acct_flags,
4644 info->info21.acct_flags, info->info21.account_name);
4648 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].account_name,
4649 info->info21.account_name, info->info21.account_name);
4650 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].description,
4651 info->info21.description, info->info21.account_name);
4652 INT_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].rid,
4653 info->info21.rid, info->info21.account_name);
4654 INT_EQUAL_QUERY((querydisplayinfo->out.info->info2.entries[i].acct_flags & ~ACB_NORMAL),
4655 info->info21.acct_flags, info->info21.account_name);
4657 if (!(querydisplayinfo->out.info->info2.entries[i].acct_flags & ACB_NORMAL)) {
4658 printf("Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
4659 info->info21.account_name.string);
4662 if (!(info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
4663 printf("Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
4664 info->info21.account_name.string,
4665 querydisplayinfo->out.info->info2.entries[i].acct_flags,
4666 info->info21.acct_flags);
4673 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
4680 static bool test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4681 struct policy_handle *handle)
4684 struct samr_QueryDisplayInfo r;
4685 struct samr_QueryDomainInfo dom_info;
4686 union samr_DomainInfo *info = NULL;
4688 uint16_t levels[] = {1, 2, 3, 4, 5};
4690 bool seen_testuser = false;
4691 uint32_t total_size;
4692 uint32_t returned_size;
4693 union samr_DispInfo disp_info;
4696 for (i=0;i<ARRAY_SIZE(levels);i++) {
4697 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
4700 status = STATUS_MORE_ENTRIES;
4701 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
4702 r.in.domain_handle = handle;
4703 r.in.level = levels[i];
4704 r.in.max_entries = 2;
4705 r.in.buf_size = (uint32_t)-1;
4706 r.out.total_size = &total_size;
4707 r.out.returned_size = &returned_size;
4708 r.out.info = &disp_info;
4710 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
4711 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(status)) {
4712 printf("QueryDisplayInfo level %u failed - %s\n",
4713 levels[i], nt_errstr(status));
4716 switch (r.in.level) {
4718 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, &seen_testuser)) {
4721 r.in.start_idx += r.out.info->info1.count;
4724 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, NULL)) {
4727 r.in.start_idx += r.out.info->info2.count;
4730 r.in.start_idx += r.out.info->info3.count;
4733 r.in.start_idx += r.out.info->info4.count;
4736 r.in.start_idx += r.out.info->info5.count;
4740 dom_info.in.domain_handle = handle;
4741 dom_info.in.level = 2;
4742 dom_info.out.info = &info;
4744 /* Check number of users returned is correct */
4745 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &dom_info);
4746 if (!NT_STATUS_IS_OK(status)) {
4747 printf("QueryDomainInfo level %u failed - %s\n",
4748 r.in.level, nt_errstr(status));
4752 switch (r.in.level) {
4755 if (info->general.num_users < r.in.start_idx) {
4756 printf("QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
4757 r.in.start_idx, info->general.num_groups,
4758 info->general.domain_name.string);
4761 if (!seen_testuser) {
4762 struct policy_handle user_handle;
4763 if (NT_STATUS_IS_OK(test_OpenUser_byname(p, mem_ctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
4764 printf("Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
4765 info->general.domain_name.string);
4767 test_samr_handle_Close(p, mem_ctx, &user_handle);
4773 if (info->general.num_groups != r.in.start_idx) {
4774 printf("QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
4775 r.in.start_idx, info->general.num_groups,
4776 info->general.domain_name.string);
4788 static bool test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4789 struct policy_handle *handle)
4792 struct samr_QueryDisplayInfo2 r;
4794 uint16_t levels[] = {1, 2, 3, 4, 5};
4796 uint32_t total_size;
4797 uint32_t returned_size;
4798 union samr_DispInfo info;
4800 for (i=0;i<ARRAY_SIZE(levels);i++) {
4801 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
4803 r.in.domain_handle = handle;
4804 r.in.level = levels[i];
4806 r.in.max_entries = 1000;
4807 r.in.buf_size = (uint32_t)-1;
4808 r.out.total_size = &total_size;
4809 r.out.returned_size = &returned_size;
4812 status = dcerpc_samr_QueryDisplayInfo2(p, mem_ctx, &r);
4813 if (!NT_STATUS_IS_OK(status)) {
4814 printf("QueryDisplayInfo2 level %u failed - %s\n",
4815 levels[i], nt_errstr(status));
4823 static bool test_QueryDisplayInfo3(struct dcerpc_pipe *p, struct torture_context *tctx,
4824 struct policy_handle *handle)
4827 struct samr_QueryDisplayInfo3 r;
4829 uint16_t levels[] = {1, 2, 3, 4, 5};
4831 uint32_t total_size;
4832 uint32_t returned_size;
4833 union samr_DispInfo info;
4835 for (i=0;i<ARRAY_SIZE(levels);i++) {
4836 torture_comment(tctx, "Testing QueryDisplayInfo3 level %u\n", levels[i]);
4838 r.in.domain_handle = handle;
4839 r.in.level = levels[i];
4841 r.in.max_entries = 1000;
4842 r.in.buf_size = (uint32_t)-1;
4843 r.out.total_size = &total_size;
4844 r.out.returned_size = &returned_size;
4847 status = dcerpc_samr_QueryDisplayInfo3(p, tctx, &r);
4848 if (!NT_STATUS_IS_OK(status)) {
4849 printf("QueryDisplayInfo3 level %u failed - %s\n",
4850 levels[i], nt_errstr(status));
4859 static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4860 struct policy_handle *handle)
4863 struct samr_QueryDisplayInfo r;
4865 uint32_t total_size;
4866 uint32_t returned_size;
4867 union samr_DispInfo info;
4869 printf("Testing QueryDisplayInfo continuation\n");
4871 r.in.domain_handle = handle;
4874 r.in.max_entries = 1;
4875 r.in.buf_size = (uint32_t)-1;
4876 r.out.total_size = &total_size;
4877 r.out.returned_size = &returned_size;
4881 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
4882 if (NT_STATUS_IS_OK(status) && *r.out.returned_size != 0) {
4883 if (r.out.info->info1.entries[0].idx != r.in.start_idx + 1) {
4884 printf("expected idx %d but got %d\n",
4886 r.out.info->info1.entries[0].idx);
4890 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
4891 !NT_STATUS_IS_OK(status)) {
4892 printf("QueryDisplayInfo level %u failed - %s\n",
4893 r.in.level, nt_errstr(status));
4898 } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
4899 NT_STATUS_IS_OK(status)) &&
4900 *r.out.returned_size != 0);
4905 static bool test_QueryDomainInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
4906 struct policy_handle *handle)
4909 struct samr_QueryDomainInfo r;
4910 union samr_DomainInfo *info = NULL;
4911 struct samr_SetDomainInfo s;
4912 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
4913 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
4916 const char *domain_comment = talloc_asprintf(tctx,
4917 "Tortured by Samba4 RPC-SAMR: %s",
4918 timestring(tctx, time(NULL)));
4920 s.in.domain_handle = handle;
4922 s.in.info = talloc(tctx, union samr_DomainInfo);
4924 s.in.info->oem.oem_information.string = domain_comment;
4925 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
4926 if (!NT_STATUS_IS_OK(status)) {
4927 printf("SetDomainInfo level %u (set comment) failed - %s\n",
4928 r.in.level, nt_errstr(status));
4932 for (i=0;i<ARRAY_SIZE(levels);i++) {
4933 torture_comment(tctx, "Testing QueryDomainInfo level %u\n", levels[i]);
4935 r.in.domain_handle = handle;
4936 r.in.level = levels[i];
4939 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
4940 if (!NT_STATUS_IS_OK(status)) {
4941 printf("QueryDomainInfo level %u failed - %s\n",
4942 r.in.level, nt_errstr(status));
4947 switch (levels[i]) {
4949 if (strcmp(info->general.oem_information.string, domain_comment) != 0) {
4950 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
4951 levels[i], info->general.oem_information.string, domain_comment);
4954 if (!info->general.primary.string) {
4955 printf("QueryDomainInfo level %u returned no PDC name\n",
4958 } else if (info->general.role == SAMR_ROLE_DOMAIN_PDC) {
4959 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), info->general.primary.string) != 0) {
4960 printf("QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
4961 levels[i], info->general.primary.string, dcerpc_server_name(p));
4966 if (strcmp(info->oem.oem_information.string, domain_comment) != 0) {
4967 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
4968 levels[i], info->oem.oem_information.string, domain_comment);
4973 if (!info->info6.primary.string) {
4974 printf("QueryDomainInfo level %u returned no PDC name\n",
4980 if (strcmp(info->general2.general.oem_information.string, domain_comment) != 0) {
4981 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
4982 levels[i], info->general2.general.oem_information.string, domain_comment);
4988 torture_comment(tctx, "Testing SetDomainInfo level %u\n", levels[i]);
4990 s.in.domain_handle = handle;
4991 s.in.level = levels[i];
4994 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
4996 if (!NT_STATUS_IS_OK(status)) {
4997 printf("SetDomainInfo level %u failed - %s\n",
4998 r.in.level, nt_errstr(status));
5003 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
5004 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
5005 r.in.level, nt_errstr(status));
5011 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
5012 if (!NT_STATUS_IS_OK(status)) {
5013 printf("QueryDomainInfo level %u failed - %s\n",
5014 r.in.level, nt_errstr(status));
5024 static bool test_QueryDomainInfo2(struct dcerpc_pipe *p, struct torture_context *tctx,
5025 struct policy_handle *handle)
5028 struct samr_QueryDomainInfo2 r;
5029 union samr_DomainInfo *info = NULL;
5030 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
5034 for (i=0;i<ARRAY_SIZE(levels);i++) {
5035 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
5037 r.in.domain_handle = handle;
5038 r.in.level = levels[i];
5041 status = dcerpc_samr_QueryDomainInfo2(p, tctx, &r);
5042 if (!NT_STATUS_IS_OK(status)) {
5043 printf("QueryDomainInfo2 level %u failed - %s\n",
5044 r.in.level, nt_errstr(status));
5053 /* Test whether querydispinfo level 5 and enumdomgroups return the same
5054 set of group names. */
5055 static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx,
5056 struct policy_handle *handle)
5058 struct samr_EnumDomainGroups q1;
5059 struct samr_QueryDisplayInfo q2;
5061 uint32_t resume_handle=0;
5062 struct samr_SamArray *sam = NULL;
5063 uint32_t num_entries = 0;
5066 uint32_t total_size;
5067 uint32_t returned_size;
5068 union samr_DispInfo info;
5071 const char **names = NULL;
5073 torture_comment(tctx, "Testing coherency of querydispinfo vs enumdomgroups\n");
5075 q1.in.domain_handle = handle;
5076 q1.in.resume_handle = &resume_handle;
5078 q1.out.resume_handle = &resume_handle;
5079 q1.out.num_entries = &num_entries;
5082 status = STATUS_MORE_ENTRIES;
5083 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
5084 status = dcerpc_samr_EnumDomainGroups(p, tctx, &q1);
5086 if (!NT_STATUS_IS_OK(status) &&
5087 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
5090 for (i=0; i<*q1.out.num_entries; i++) {
5091 add_string_to_array(tctx,
5092 sam->entries[i].name.string,
5093 &names, &num_names);
5097 torture_assert_ntstatus_ok(tctx, status, "EnumDomainGroups");
5099 torture_assert(tctx, sam, "EnumDomainGroups failed to return sam");
5101 q2.in.domain_handle = handle;
5103 q2.in.start_idx = 0;
5104 q2.in.max_entries = 5;
5105 q2.in.buf_size = (uint32_t)-1;
5106 q2.out.total_size = &total_size;
5107 q2.out.returned_size = &returned_size;
5108 q2.out.info = &info;
5110 status = STATUS_MORE_ENTRIES;
5111 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
5112 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &q2);
5114 if (!NT_STATUS_IS_OK(status) &&
5115 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
5118 for (i=0; i<q2.out.info->info5.count; i++) {
5120 const char *name = q2.out.info->info5.entries[i].account_name.string;
5122 for (j=0; j<num_names; j++) {
5123 if (names[j] == NULL)
5125 if (strequal(names[j], name)) {
5133 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
5138 q2.in.start_idx += q2.out.info->info5.count;
5141 if (!NT_STATUS_IS_OK(status)) {
5142 printf("QueryDisplayInfo level 5 failed - %s\n",
5147 for (i=0; i<num_names; i++) {
5148 if (names[i] != NULL) {
5149 printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
5158 static bool test_DeleteDomainGroup(struct dcerpc_pipe *p, struct torture_context *tctx,
5159 struct policy_handle *group_handle)
5161 struct samr_DeleteDomainGroup d;
5164 torture_comment(tctx, "Testing DeleteDomainGroup\n");
5166 d.in.group_handle = group_handle;
5167 d.out.group_handle = group_handle;
5169 status = dcerpc_samr_DeleteDomainGroup(p, tctx, &d);
5170 torture_assert_ntstatus_ok(tctx, status, "DeleteDomainGroup");
5175 static bool test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
5176 struct policy_handle *domain_handle)
5178 struct samr_TestPrivateFunctionsDomain r;
5182 torture_comment(tctx, "Testing TestPrivateFunctionsDomain\n");
5184 r.in.domain_handle = domain_handle;
5186 status = dcerpc_samr_TestPrivateFunctionsDomain(p, tctx, &r);
5187 torture_assert_ntstatus_equal(tctx, NT_STATUS_NOT_IMPLEMENTED, status, "TestPrivateFunctionsDomain");
5192 static bool test_RidToSid(struct dcerpc_pipe *p, struct torture_context *tctx,
5193 struct dom_sid *domain_sid,
5194 struct policy_handle *domain_handle)
5196 struct samr_RidToSid r;
5199 struct dom_sid *calc_sid, *out_sid;
5200 int rids[] = { 0, 42, 512, 10200 };
5203 for (i=0;i<ARRAY_SIZE(rids);i++) {
5204 torture_comment(tctx, "Testing RidToSid\n");
5206 calc_sid = dom_sid_dup(tctx, domain_sid);
5207 r.in.domain_handle = domain_handle;
5209 r.out.sid = &out_sid;
5211 status = dcerpc_samr_RidToSid(p, tctx, &r);
5212 if (!NT_STATUS_IS_OK(status)) {
5213 printf("RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
5216 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
5218 if (!dom_sid_equal(calc_sid, out_sid)) {
5219 printf("RidToSid for %d failed - got %s, expected %s\n", rids[i],
5220 dom_sid_string(tctx, out_sid),
5221 dom_sid_string(tctx, calc_sid));
5230 static bool test_GetBootKeyInformation(struct dcerpc_pipe *p, struct torture_context *tctx,
5231 struct policy_handle *domain_handle)
5233 struct samr_GetBootKeyInformation r;
5236 uint32_t unknown = 0;
5238 torture_comment(tctx, "Testing GetBootKeyInformation\n");
5240 r.in.domain_handle = domain_handle;
5241 r.out.unknown = &unknown;
5243 status = dcerpc_samr_GetBootKeyInformation(p, tctx, &r);
5244 if (!NT_STATUS_IS_OK(status)) {
5245 /* w2k3 seems to fail this sometimes and pass it sometimes */
5246 torture_comment(tctx, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
5252 static bool test_AddGroupMember(struct dcerpc_pipe *p, struct torture_context *tctx,
5253 struct policy_handle *domain_handle,
5254 struct policy_handle *group_handle)
5257 struct samr_AddGroupMember r;
5258 struct samr_DeleteGroupMember d;
5259 struct samr_QueryGroupMember q;
5260 struct samr_RidTypeArray *rids = NULL;
5261 struct samr_SetMemberAttributesOfGroup s;
5264 status = test_LookupName(p, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
5265 torture_assert_ntstatus_ok(tctx, status, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME);
5267 r.in.group_handle = group_handle;
5269 r.in.flags = 0; /* ??? */
5271 torture_comment(tctx, "Testing AddGroupMember and DeleteGroupMember\n");
5273 d.in.group_handle = group_handle;
5276 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
5277 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_NOT_IN_GROUP, status, "DeleteGroupMember");
5279 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5280 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
5282 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5283 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_IN_GROUP, status, "AddGroupMember");
5285 if (torture_setting_bool(tctx, "samba4", false)) {
5286 torture_comment(tctx, "skipping SetMemberAttributesOfGroup test against Samba4\n");
5288 /* this one is quite strange. I am using random inputs in the
5289 hope of triggering an error that might give us a clue */
5291 s.in.group_handle = group_handle;
5292 s.in.unknown1 = random();
5293 s.in.unknown2 = random();
5295 status = dcerpc_samr_SetMemberAttributesOfGroup(p, tctx, &s);
5296 torture_assert_ntstatus_ok(tctx, status, "SetMemberAttributesOfGroup");
5299 q.in.group_handle = group_handle;
5302 status = dcerpc_samr_QueryGroupMember(p, tctx, &q);
5303 torture_assert_ntstatus_ok(tctx, status, "QueryGroupMember");
5305 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
5306 torture_assert_ntstatus_ok(tctx, status, "DeleteGroupMember");
5308 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5309 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
5315 static bool test_CreateDomainGroup(struct dcerpc_pipe *p,
5316 struct torture_context *tctx,
5317 struct policy_handle *domain_handle,
5318 struct policy_handle *group_handle,
5319 struct dom_sid *domain_sid)
5322 struct samr_CreateDomainGroup r;
5324 struct lsa_String name;
5327 init_lsa_String(&name, TEST_GROUPNAME);
5329 r.in.domain_handle = domain_handle;
5331 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5332 r.out.group_handle = group_handle;
5335 printf("Testing CreateDomainGroup(%s)\n", r.in.name->string);
5337 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
5339 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5340 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5341 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.name->string);
5344 printf("Server should have refused create of '%s', got %s instead\n", r.in.name->string,
5350 if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS)) {
5351 if (!test_DeleteGroup_byname(p, tctx, domain_handle, r.in.name->string)) {
5352 printf("CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
5356 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
5358 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
5359 if (!test_DeleteUser_byname(p, tctx, domain_handle, r.in.name->string)) {
5361 printf("CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
5365 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
5367 torture_assert_ntstatus_ok(tctx, status, "CreateDomainGroup");
5369 if (!test_AddGroupMember(p, tctx, domain_handle, group_handle)) {
5370 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
5374 if (!test_SetGroupInfo(p, tctx, group_handle)) {
5383 its not totally clear what this does. It seems to accept any sid you like.
5385 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p,
5386 struct torture_context *tctx,
5387 struct policy_handle *domain_handle)
5390 struct samr_RemoveMemberFromForeignDomain r;
5392 r.in.domain_handle = domain_handle;
5393 r.in.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-12-34-56-78");
5395 status = dcerpc_samr_RemoveMemberFromForeignDomain(p, tctx, &r);
5396 torture_assert_ntstatus_ok(tctx, status, "RemoveMemberFromForeignDomain");
5403 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
5404 struct policy_handle *handle);
5406 static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
5407 struct policy_handle *handle, struct dom_sid *sid,
5408 enum torture_samr_choice which_ops)
5411 struct samr_OpenDomain r;
5412 struct policy_handle domain_handle;
5413 struct policy_handle alias_handle;
5414 struct policy_handle user_handle;
5415 struct policy_handle group_handle;
5418 ZERO_STRUCT(alias_handle);
5419 ZERO_STRUCT(user_handle);
5420 ZERO_STRUCT(group_handle);
5421 ZERO_STRUCT(domain_handle);
5423 torture_comment(tctx, "Testing OpenDomain of %s\n", dom_sid_string(tctx, sid));
5425 r.in.connect_handle = handle;
5426 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5428 r.out.domain_handle = &domain_handle;
5430 status = dcerpc_samr_OpenDomain(p, tctx, &r);
5431 torture_assert_ntstatus_ok(tctx, status, "OpenDomain");
5433 /* run the domain tests with the main handle closed - this tests
5434 the servers reference counting */
5435 ret &= test_samr_handle_Close(p, tctx, handle);
5437 switch (which_ops) {
5438 case TORTURE_SAMR_USER_ATTRIBUTES:
5439 case TORTURE_SAMR_PASSWORDS:
5440 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops);
5441 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops);
5442 /* This test needs 'complex' users to validate */
5443 ret &= test_QueryDisplayInfo(p, tctx, &domain_handle);
5445 printf("Testing PASSWORDS or ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
5448 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
5449 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops);
5450 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops);
5452 printf("Testing PASSWORDS PWDLASTSET on domain %s failed!\n", dom_sid_string(tctx, sid));
5455 case TORTURE_SAMR_OTHER:
5456 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops);
5458 printf("Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid));
5460 ret &= test_QuerySecurity(p, tctx, &domain_handle);
5461 ret &= test_RemoveMemberFromForeignDomain(p, tctx, &domain_handle);
5462 ret &= test_CreateAlias(p, tctx, &domain_handle, &alias_handle, sid);
5463 ret &= test_CreateDomainGroup(p, tctx, &domain_handle, &group_handle, sid);
5464 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
5465 ret &= test_QueryDomainInfo2(p, tctx, &domain_handle);
5466 ret &= test_EnumDomainUsers(p, tctx, &domain_handle);
5467 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
5468 ret &= test_EnumDomainGroups(p, tctx, &domain_handle);
5469 ret &= test_EnumDomainAliases(p, tctx, &domain_handle);
5470 ret &= test_QueryDisplayInfo2(p, tctx, &domain_handle);
5471 ret &= test_QueryDisplayInfo3(p, tctx, &domain_handle);
5472 ret &= test_QueryDisplayInfo_continue(p, tctx, &domain_handle);
5474 if (torture_setting_bool(tctx, "samba4", false)) {
5475 torture_comment(tctx, "skipping GetDisplayEnumerationIndex test against Samba4\n");
5477 ret &= test_GetDisplayEnumerationIndex(p, tctx, &domain_handle);
5478 ret &= test_GetDisplayEnumerationIndex2(p, tctx, &domain_handle);
5480 ret &= test_GroupList(p, tctx, &domain_handle);
5481 ret &= test_TestPrivateFunctionsDomain(p, tctx, &domain_handle);
5482 ret &= test_RidToSid(p, tctx, sid, &domain_handle);
5483 ret &= test_GetBootKeyInformation(p, tctx, &domain_handle);
5485 torture_comment(tctx, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx, sid));
5490 if (!policy_handle_empty(&user_handle) &&
5491 !test_DeleteUser(p, tctx, &user_handle)) {
5495 if (!policy_handle_empty(&alias_handle) &&
5496 !test_DeleteAlias(p, tctx, &alias_handle)) {
5500 if (!policy_handle_empty(&group_handle) &&
5501 !test_DeleteDomainGroup(p, tctx, &group_handle)) {
5505 ret &= test_samr_handle_Close(p, tctx, &domain_handle);
5507 /* reconnect the main handle */
5508 ret &= test_Connect(p, tctx, handle);
5511 printf("Testing domain %s failed!\n", dom_sid_string(tctx, sid));
5517 static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
5518 struct policy_handle *handle, const char *domain,
5519 enum torture_samr_choice which_ops)
5522 struct samr_LookupDomain r;
5523 struct dom_sid2 *sid = NULL;
5524 struct lsa_String n1;
5525 struct lsa_String n2;
5528 torture_comment(tctx, "Testing LookupDomain(%s)\n", domain);
5530 /* check for correct error codes */
5531 r.in.connect_handle = handle;
5532 r.in.domain_name = &n2;
5536 status = dcerpc_samr_LookupDomain(p, tctx, &r);
5537 torture_assert_ntstatus_equal(tctx, NT_STATUS_INVALID_PARAMETER, status, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
5539 init_lsa_String(&n2, "xxNODOMAINxx");
5541 status = dcerpc_samr_LookupDomain(p, tctx, &r);
5542 torture_assert_ntstatus_equal(tctx, NT_STATUS_NO_SUCH_DOMAIN, status, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
5544 r.in.connect_handle = handle;
5546 init_lsa_String(&n1, domain);
5547 r.in.domain_name = &n1;
5549 status = dcerpc_samr_LookupDomain(p, tctx, &r);
5550 torture_assert_ntstatus_ok(tctx, status, "LookupDomain");
5552 if (!test_GetDomPwInfo(p, tctx, &n1)) {
5556 if (!test_OpenDomain(p, tctx, handle, *r.out.sid, which_ops)) {
5564 static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
5565 struct policy_handle *handle, enum torture_samr_choice which_ops)
5568 struct samr_EnumDomains r;
5569 uint32_t resume_handle = 0;
5570 uint32_t num_entries = 0;
5571 struct samr_SamArray *sam = NULL;
5575 r.in.connect_handle = handle;
5576 r.in.resume_handle = &resume_handle;
5577 r.in.buf_size = (uint32_t)-1;
5578 r.out.resume_handle = &resume_handle;
5579 r.out.num_entries = &num_entries;
5582 status = dcerpc_samr_EnumDomains(p, tctx, &r);
5583 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
5589 for (i=0;i<sam->count;i++) {
5590 if (!test_LookupDomain(p, tctx, handle,
5591 sam->entries[i].name.string, which_ops)) {
5596 status = dcerpc_samr_EnumDomains(p, tctx, &r);
5597 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
5603 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
5604 struct policy_handle *handle)
5607 struct samr_Connect r;
5608 struct samr_Connect2 r2;
5609 struct samr_Connect3 r3;
5610 struct samr_Connect4 r4;
5611 struct samr_Connect5 r5;
5612 union samr_ConnectInfo info;
5613 struct policy_handle h;
5614 uint32_t level_out = 0;
5615 bool ret = true, got_handle = false;
5617 torture_comment(tctx, "testing samr_Connect\n");
5619 r.in.system_name = 0;
5620 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5621 r.out.connect_handle = &h;
5623 status = dcerpc_samr_Connect(p, tctx, &r);
5624 if (!NT_STATUS_IS_OK(status)) {
5625 torture_comment(tctx, "Connect failed - %s\n", nt_errstr(status));
5632 torture_comment(tctx, "testing samr_Connect2\n");
5634 r2.in.system_name = NULL;
5635 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5636 r2.out.connect_handle = &h;
5638 status = dcerpc_samr_Connect2(p, tctx, &r2);
5639 if (!NT_STATUS_IS_OK(status)) {
5640 torture_comment(tctx, "Connect2 failed - %s\n", nt_errstr(status));
5644 test_samr_handle_Close(p, tctx, handle);
5650 torture_comment(tctx, "testing samr_Connect3\n");
5652 r3.in.system_name = NULL;
5654 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5655 r3.out.connect_handle = &h;
5657 status = dcerpc_samr_Connect3(p, tctx, &r3);
5658 if (!NT_STATUS_IS_OK(status)) {
5659 printf("Connect3 failed - %s\n", nt_errstr(status));
5663 test_samr_handle_Close(p, tctx, handle);
5669 torture_comment(tctx, "testing samr_Connect4\n");
5671 r4.in.system_name = "";
5672 r4.in.client_version = 0;
5673 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5674 r4.out.connect_handle = &h;
5676 status = dcerpc_samr_Connect4(p, tctx, &r4);
5677 if (!NT_STATUS_IS_OK(status)) {
5678 printf("Connect4 failed - %s\n", nt_errstr(status));
5682 test_samr_handle_Close(p, tctx, handle);
5688 torture_comment(tctx, "testing samr_Connect5\n");
5690 info.info1.client_version = 0;
5691 info.info1.unknown2 = 0;
5693 r5.in.system_name = "";
5694 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5696 r5.out.level_out = &level_out;
5697 r5.in.info_in = &info;
5698 r5.out.info_out = &info;
5699 r5.out.connect_handle = &h;
5701 status = dcerpc_samr_Connect5(p, tctx, &r5);
5702 if (!NT_STATUS_IS_OK(status)) {
5703 printf("Connect5 failed - %s\n", nt_errstr(status));
5707 test_samr_handle_Close(p, tctx, handle);
5717 bool torture_rpc_samr(struct torture_context *torture)
5720 struct dcerpc_pipe *p;
5722 struct policy_handle handle;
5724 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
5725 if (!NT_STATUS_IS_OK(status)) {
5729 ret &= test_Connect(p, torture, &handle);
5731 ret &= test_QuerySecurity(p, torture, &handle);
5733 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_OTHER);
5735 ret &= test_SetDsrmPassword(p, torture, &handle);
5737 ret &= test_Shutdown(p, torture, &handle);
5739 ret &= test_samr_handle_Close(p, torture, &handle);
5745 bool torture_rpc_samr_users(struct torture_context *torture)
5748 struct dcerpc_pipe *p;
5750 struct policy_handle handle;
5752 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
5753 if (!NT_STATUS_IS_OK(status)) {
5757 ret &= test_Connect(p, torture, &handle);
5759 ret &= test_QuerySecurity(p, torture, &handle);
5761 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_USER_ATTRIBUTES);
5763 ret &= test_SetDsrmPassword(p, torture, &handle);
5765 ret &= test_Shutdown(p, torture, &handle);
5767 ret &= test_samr_handle_Close(p, torture, &handle);
5773 bool torture_rpc_samr_passwords(struct torture_context *torture)
5776 struct dcerpc_pipe *p;
5778 struct policy_handle handle;
5780 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
5781 if (!NT_STATUS_IS_OK(status)) {
5785 ret &= test_Connect(p, torture, &handle);
5787 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_PASSWORDS);
5789 ret &= test_samr_handle_Close(p, torture, &handle);
5794 bool torture_rpc_samr_passwords_pwdlastset(struct torture_context *torture)
5797 struct dcerpc_pipe *p;
5799 struct policy_handle handle;
5801 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
5802 if (!NT_STATUS_IS_OK(status)) {
5806 ret &= test_Connect(p, torture, &handle);
5808 ret &= test_EnumDomains(p, torture, &handle,
5809 TORTURE_SAMR_PASSWORDS_PWDLASTSET);
5811 ret &= test_samr_handle_Close(p, torture, &handle);