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_netlogon.h"
27 #include "librpc/gen_ndr/ndr_netlogon_c.h"
28 #include "librpc/gen_ndr/ndr_samr_c.h"
29 #include "../lib/crypto/crypto.h"
30 #include "libcli/auth/libcli_auth.h"
31 #include "libcli/security/security.h"
32 #include "torture/rpc/rpc.h"
36 #define TEST_ACCOUNT_NAME "samrtorturetest"
37 #define TEST_ACCOUNT_NAME_PWD "samrpwdlastset"
38 #define TEST_ALIASNAME "samrtorturetestalias"
39 #define TEST_GROUPNAME "samrtorturetestgroup"
40 #define TEST_MACHINENAME "samrtestmach$"
41 #define TEST_DOMAINNAME "samrtestdom$"
43 enum torture_samr_choice {
44 TORTURE_SAMR_PASSWORDS,
45 TORTURE_SAMR_PASSWORDS_PWDLASTSET,
46 TORTURE_SAMR_USER_ATTRIBUTES,
50 static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
51 struct policy_handle *handle);
53 static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
54 struct policy_handle *handle);
56 static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
57 struct policy_handle *handle);
59 static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
60 const char *acct_name,
61 struct policy_handle *domain_handle, char **password);
63 static void init_lsa_String(struct lsa_String *string, const char *s)
68 static void init_lsa_BinaryString(struct lsa_BinaryString *string, const char *s, uint32_t length)
70 string->length = length;
71 string->size = length;
72 string->array = (uint16_t *)discard_const(s);
75 bool test_samr_handle_Close(struct dcerpc_pipe *p, struct torture_context *tctx,
76 struct policy_handle *handle)
82 r.out.handle = handle;
84 status = dcerpc_samr_Close(p, tctx, &r);
85 torture_assert_ntstatus_ok(tctx, status, "Close");
90 static bool test_Shutdown(struct dcerpc_pipe *p, struct torture_context *tctx,
91 struct policy_handle *handle)
94 struct samr_Shutdown r;
96 if (!torture_setting_bool(tctx, "dangerous", false)) {
97 torture_skip(tctx, "samr_Shutdown disabled - enable dangerous tests to use\n");
101 r.in.connect_handle = handle;
103 torture_comment(tctx, "testing samr_Shutdown\n");
105 status = dcerpc_samr_Shutdown(p, tctx, &r);
106 torture_assert_ntstatus_ok(tctx, status, "samr_Shutdown");
111 static bool test_SetDsrmPassword(struct dcerpc_pipe *p, struct torture_context *tctx,
112 struct policy_handle *handle)
115 struct samr_SetDsrmPassword r;
116 struct lsa_String string;
117 struct samr_Password hash;
119 if (!torture_setting_bool(tctx, "dangerous", false)) {
120 torture_skip(tctx, "samr_SetDsrmPassword disabled - enable dangerous tests to use");
123 E_md4hash("TeSTDSRM123", hash.hash);
125 init_lsa_String(&string, "Administrator");
131 torture_comment(tctx, "testing samr_SetDsrmPassword\n");
133 status = dcerpc_samr_SetDsrmPassword(p, tctx, &r);
134 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_SUPPORTED, "samr_SetDsrmPassword");
140 static bool test_QuerySecurity(struct dcerpc_pipe *p,
141 struct torture_context *tctx,
142 struct policy_handle *handle)
145 struct samr_QuerySecurity r;
146 struct samr_SetSecurity s;
147 struct sec_desc_buf *sdbuf = NULL;
149 r.in.handle = handle;
151 r.out.sdbuf = &sdbuf;
153 status = dcerpc_samr_QuerySecurity(p, tctx, &r);
154 torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
156 torture_assert(tctx, sdbuf != NULL, "sdbuf is NULL");
158 s.in.handle = handle;
162 if (torture_setting_bool(tctx, "samba4", false)) {
163 torture_skip(tctx, "skipping SetSecurity test against Samba4\n");
166 status = dcerpc_samr_SetSecurity(p, tctx, &s);
167 torture_assert_ntstatus_ok(tctx, status, "SetSecurity");
169 status = dcerpc_samr_QuerySecurity(p, tctx, &r);
170 torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
176 static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
177 struct policy_handle *handle, uint32_t base_acct_flags,
178 const char *base_account_name)
181 struct samr_SetUserInfo s;
182 struct samr_SetUserInfo2 s2;
183 struct samr_QueryUserInfo q;
184 struct samr_QueryUserInfo q0;
185 union samr_UserInfo u;
186 union samr_UserInfo *info;
188 const char *test_account_name;
190 uint32_t user_extra_flags = 0;
191 if (base_acct_flags == ACB_NORMAL) {
192 /* When created, accounts are expired by default */
193 user_extra_flags = ACB_PW_EXPIRED;
196 s.in.user_handle = handle;
199 s2.in.user_handle = handle;
202 q.in.user_handle = handle;
206 #define TESTCALL(call, r) \
207 status = dcerpc_samr_ ##call(p, tctx, &r); \
208 if (!NT_STATUS_IS_OK(status)) { \
209 torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
210 r.in.level, nt_errstr(status), __location__); \
215 #define STRING_EQUAL(s1, s2, field) \
216 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
217 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
218 #field, s2, __location__); \
223 #define MEM_EQUAL(s1, s2, length, field) \
224 if ((s1 && !s2) || (s2 && !s1) || memcmp(s1, s2, length)) { \
225 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
226 #field, (const char *)s2, __location__); \
231 #define INT_EQUAL(i1, i2, field) \
233 torture_comment(tctx, "Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \
234 #field, (unsigned long long)i2, (unsigned long long)i1, __location__); \
239 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
240 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
242 TESTCALL(QueryUserInfo, q) \
244 s2.in.level = lvl1; \
247 ZERO_STRUCT(u.info21); \
248 u.info21.fields_present = fpval; \
250 init_lsa_String(&u.info ## lvl1.field1, value); \
251 TESTCALL(SetUserInfo, s) \
252 TESTCALL(SetUserInfo2, s2) \
253 init_lsa_String(&u.info ## lvl1.field1, ""); \
254 TESTCALL(QueryUserInfo, q); \
256 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
258 TESTCALL(QueryUserInfo, q) \
260 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
263 #define TEST_USERINFO_BINARYSTRING(lvl1, field1, lvl2, field2, value, fpval) do { \
264 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
266 TESTCALL(QueryUserInfo, q) \
268 s2.in.level = lvl1; \
271 ZERO_STRUCT(u.info21); \
272 u.info21.fields_present = fpval; \
274 init_lsa_BinaryString(&u.info ## lvl1.field1, value, strlen(value)); \
275 TESTCALL(SetUserInfo, s) \
276 TESTCALL(SetUserInfo2, s2) \
277 init_lsa_BinaryString(&u.info ## lvl1.field1, "", 1); \
278 TESTCALL(QueryUserInfo, q); \
280 MEM_EQUAL(u.info ## lvl1.field1.array, value, strlen(value), field1); \
282 TESTCALL(QueryUserInfo, q) \
284 MEM_EQUAL(u.info ## lvl2.field2.array, value, strlen(value), field2); \
287 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
288 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
290 TESTCALL(QueryUserInfo, q) \
292 s2.in.level = lvl1; \
295 uint8_t *bits = u.info21.logon_hours.bits; \
296 ZERO_STRUCT(u.info21); \
297 if (fpval == SAMR_FIELD_LOGON_HOURS) { \
298 u.info21.logon_hours.units_per_week = 168; \
299 u.info21.logon_hours.bits = bits; \
301 u.info21.fields_present = fpval; \
303 u.info ## lvl1.field1 = value; \
304 TESTCALL(SetUserInfo, s) \
305 TESTCALL(SetUserInfo2, s2) \
306 u.info ## lvl1.field1 = 0; \
307 TESTCALL(QueryUserInfo, q); \
309 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
311 TESTCALL(QueryUserInfo, q) \
313 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
316 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
317 TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
321 do { TESTCALL(QueryUserInfo, q0) } while (0);
323 TEST_USERINFO_STRING(2, comment, 1, comment, "xx2-1 comment", 0);
324 TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
325 TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment",
328 test_account_name = talloc_asprintf(tctx, "%sxx7-1", base_account_name);
329 TEST_USERINFO_STRING(7, account_name, 1, account_name, base_account_name, 0);
330 test_account_name = talloc_asprintf(tctx, "%sxx7-3", base_account_name);
331 TEST_USERINFO_STRING(7, account_name, 3, account_name, base_account_name, 0);
332 test_account_name = talloc_asprintf(tctx, "%sxx7-5", base_account_name);
333 TEST_USERINFO_STRING(7, account_name, 5, account_name, base_account_name, 0);
334 test_account_name = talloc_asprintf(tctx, "%sxx7-6", base_account_name);
335 TEST_USERINFO_STRING(7, account_name, 6, account_name, base_account_name, 0);
336 test_account_name = talloc_asprintf(tctx, "%sxx7-7", base_account_name);
337 TEST_USERINFO_STRING(7, account_name, 7, account_name, base_account_name, 0);
338 test_account_name = talloc_asprintf(tctx, "%sxx7-21", base_account_name);
339 TEST_USERINFO_STRING(7, account_name, 21, account_name, base_account_name, 0);
340 test_account_name = base_account_name;
341 TEST_USERINFO_STRING(21, account_name, 21, account_name, base_account_name,
342 SAMR_FIELD_ACCOUNT_NAME);
344 TEST_USERINFO_STRING(6, full_name, 1, full_name, "xx6-1 full_name", 0);
345 TEST_USERINFO_STRING(6, full_name, 3, full_name, "xx6-3 full_name", 0);
346 TEST_USERINFO_STRING(6, full_name, 5, full_name, "xx6-5 full_name", 0);
347 TEST_USERINFO_STRING(6, full_name, 6, full_name, "xx6-6 full_name", 0);
348 TEST_USERINFO_STRING(6, full_name, 8, full_name, "xx6-8 full_name", 0);
349 TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
350 TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
351 TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name",
352 SAMR_FIELD_FULL_NAME);
354 TEST_USERINFO_STRING(6, full_name, 1, full_name, "", 0);
355 TEST_USERINFO_STRING(6, full_name, 3, full_name, "", 0);
356 TEST_USERINFO_STRING(6, full_name, 5, full_name, "", 0);
357 TEST_USERINFO_STRING(6, full_name, 6, full_name, "", 0);
358 TEST_USERINFO_STRING(6, full_name, 8, full_name, "", 0);
359 TEST_USERINFO_STRING(6, full_name, 21, full_name, "", 0);
360 TEST_USERINFO_STRING(8, full_name, 21, full_name, "", 0);
361 TEST_USERINFO_STRING(21, full_name, 21, full_name, "",
362 SAMR_FIELD_FULL_NAME);
364 TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
365 TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
366 TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
367 TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script",
368 SAMR_FIELD_LOGON_SCRIPT);
370 TEST_USERINFO_STRING(12, profile_path, 3, profile_path, "xx12-3 profile_path", 0);
371 TEST_USERINFO_STRING(12, profile_path, 5, profile_path, "xx12-5 profile_path", 0);
372 TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
373 TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path",
374 SAMR_FIELD_PROFILE_PATH);
376 TEST_USERINFO_STRING(10, home_directory, 3, home_directory, "xx10-3 home_directory", 0);
377 TEST_USERINFO_STRING(10, home_directory, 5, home_directory, "xx10-5 home_directory", 0);
378 TEST_USERINFO_STRING(10, home_directory, 21, home_directory, "xx10-21 home_directory", 0);
379 TEST_USERINFO_STRING(21, home_directory, 21, home_directory, "xx21-21 home_directory",
380 SAMR_FIELD_HOME_DIRECTORY);
381 TEST_USERINFO_STRING(21, home_directory, 10, home_directory, "xx21-10 home_directory",
382 SAMR_FIELD_HOME_DIRECTORY);
384 TEST_USERINFO_STRING(10, home_drive, 3, home_drive, "xx10-3 home_drive", 0);
385 TEST_USERINFO_STRING(10, home_drive, 5, home_drive, "xx10-5 home_drive", 0);
386 TEST_USERINFO_STRING(10, home_drive, 21, home_drive, "xx10-21 home_drive", 0);
387 TEST_USERINFO_STRING(21, home_drive, 21, home_drive, "xx21-21 home_drive",
388 SAMR_FIELD_HOME_DRIVE);
389 TEST_USERINFO_STRING(21, home_drive, 10, home_drive, "xx21-10 home_drive",
390 SAMR_FIELD_HOME_DRIVE);
392 TEST_USERINFO_STRING(13, description, 1, description, "xx13-1 description", 0);
393 TEST_USERINFO_STRING(13, description, 5, description, "xx13-5 description", 0);
394 TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
395 TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description",
396 SAMR_FIELD_DESCRIPTION);
398 TEST_USERINFO_STRING(14, workstations, 3, workstations, "14workstation3", 0);
399 TEST_USERINFO_STRING(14, workstations, 5, workstations, "14workstation4", 0);
400 TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
401 TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21",
402 SAMR_FIELD_WORKSTATIONS);
403 TEST_USERINFO_STRING(21, workstations, 3, workstations, "21workstation3",
404 SAMR_FIELD_WORKSTATIONS);
405 TEST_USERINFO_STRING(21, workstations, 5, workstations, "21workstation5",
406 SAMR_FIELD_WORKSTATIONS);
407 TEST_USERINFO_STRING(21, workstations, 14, workstations, "21workstation14",
408 SAMR_FIELD_WORKSTATIONS);
410 TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
411 TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "xx21-21 parameters",
412 SAMR_FIELD_PARAMETERS);
413 TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "xx21-20 parameters",
414 SAMR_FIELD_PARAMETERS);
415 /* also empty user parameters are allowed */
416 TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "", 0);
417 TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "",
418 SAMR_FIELD_PARAMETERS);
419 TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "",
420 SAMR_FIELD_PARAMETERS);
422 TEST_USERINFO_INT(2, country_code, 2, country_code, __LINE__, 0);
423 TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
424 TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__,
425 SAMR_FIELD_COUNTRY_CODE);
426 TEST_USERINFO_INT(21, country_code, 2, country_code, __LINE__,
427 SAMR_FIELD_COUNTRY_CODE);
429 TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
430 TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__,
431 SAMR_FIELD_CODE_PAGE);
432 TEST_USERINFO_INT(21, code_page, 2, code_page, __LINE__,
433 SAMR_FIELD_CODE_PAGE);
435 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, __LINE__, 0);
436 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, __LINE__, 0);
437 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, __LINE__,
438 SAMR_FIELD_ACCT_EXPIRY);
439 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, __LINE__,
440 SAMR_FIELD_ACCT_EXPIRY);
441 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, __LINE__,
442 SAMR_FIELD_ACCT_EXPIRY);
444 TEST_USERINFO_INT(4, logon_hours.bits[3], 3, logon_hours.bits[3], 1, 0);
445 TEST_USERINFO_INT(4, logon_hours.bits[3], 5, logon_hours.bits[3], 2, 0);
446 TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
447 TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4,
448 SAMR_FIELD_LOGON_HOURS);
450 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
451 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
452 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
454 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
455 (base_acct_flags | ACB_DISABLED),
456 (base_acct_flags | ACB_DISABLED | user_extra_flags),
459 /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
460 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
461 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
462 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
464 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
465 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
466 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
470 /* The 'autolock' flag doesn't stick - check this */
471 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
472 (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK),
473 (base_acct_flags | ACB_DISABLED | user_extra_flags),
476 /* Removing the 'disabled' flag doesn't stick - check this */
477 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
479 (base_acct_flags | ACB_DISABLED | user_extra_flags),
482 /* The 'store plaintext' flag does stick */
483 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
484 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED),
485 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags),
487 /* The 'use DES' flag does stick */
488 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
489 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY),
490 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags),
492 /* The 'don't require kerberos pre-authentication flag does stick */
493 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
494 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH),
495 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags),
497 /* The 'no kerberos PAC required' flag sticks */
498 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
499 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD),
500 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags),
503 TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags,
504 (base_acct_flags | ACB_DISABLED),
505 (base_acct_flags | ACB_DISABLED | user_extra_flags),
506 SAMR_FIELD_ACCT_FLAGS);
509 /* these fail with win2003 - it appears you can't set the primary gid?
510 the set succeeds, but the gid isn't changed. Very weird! */
511 TEST_USERINFO_INT(9, primary_gid, 1, primary_gid, 513);
512 TEST_USERINFO_INT(9, primary_gid, 3, primary_gid, 513);
513 TEST_USERINFO_INT(9, primary_gid, 5, primary_gid, 513);
514 TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
521 generate a random password for password change tests
523 static char *samr_rand_pass_silent(TALLOC_CTX *mem_ctx, int min_len)
525 size_t len = MAX(8, min_len) + (random() % 6);
526 char *s = generate_random_str(mem_ctx, len);
530 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
532 char *s = samr_rand_pass_silent(mem_ctx, min_len);
533 printf("Generated password '%s'\n", s);
539 generate a random password for password change tests
541 static DATA_BLOB samr_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
544 DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
545 generate_random_buffer(password.data, password.length);
547 for (i=0; i < len; i++) {
548 if (((uint16_t *)password.data)[i] == 0) {
549 ((uint16_t *)password.data)[i] = 1;
557 generate a random password for password change tests (fixed length)
559 static char *samr_rand_pass_fixed_len(TALLOC_CTX *mem_ctx, int len)
561 char *s = generate_random_str(mem_ctx, len);
562 printf("Generated password '%s'\n", s);
566 static bool test_SetUserPass(struct dcerpc_pipe *p, struct torture_context *tctx,
567 struct policy_handle *handle, char **password)
570 struct samr_SetUserInfo s;
571 union samr_UserInfo u;
573 DATA_BLOB session_key;
575 struct samr_GetUserPwInfo pwp;
576 struct samr_PwInfo info;
577 int policy_min_pw_len = 0;
578 pwp.in.user_handle = handle;
579 pwp.out.info = &info;
581 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
582 if (NT_STATUS_IS_OK(status)) {
583 policy_min_pw_len = pwp.out.info->min_password_length;
585 newpass = samr_rand_pass(tctx, policy_min_pw_len);
587 s.in.user_handle = handle;
591 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
592 u.info24.password_expired = 0;
594 status = dcerpc_fetch_session_key(p, &session_key);
595 if (!NT_STATUS_IS_OK(status)) {
596 printf("SetUserInfo level %u - no session key - %s\n",
597 s.in.level, nt_errstr(status));
601 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
603 torture_comment(tctx, "Testing SetUserInfo level 24 (set password)\n");
605 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
606 if (!NT_STATUS_IS_OK(status)) {
607 printf("SetUserInfo level %u failed - %s\n",
608 s.in.level, nt_errstr(status));
618 static bool test_SetUserPass_23(struct dcerpc_pipe *p, struct torture_context *tctx,
619 struct policy_handle *handle, uint32_t fields_present,
623 struct samr_SetUserInfo s;
624 union samr_UserInfo u;
626 DATA_BLOB session_key;
628 struct samr_GetUserPwInfo pwp;
629 struct samr_PwInfo info;
630 int policy_min_pw_len = 0;
631 pwp.in.user_handle = handle;
632 pwp.out.info = &info;
634 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
635 if (NT_STATUS_IS_OK(status)) {
636 policy_min_pw_len = pwp.out.info->min_password_length;
638 newpass = samr_rand_pass(tctx, policy_min_pw_len);
640 s.in.user_handle = handle;
646 u.info23.info.fields_present = fields_present;
648 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
650 status = dcerpc_fetch_session_key(p, &session_key);
651 if (!NT_STATUS_IS_OK(status)) {
652 printf("SetUserInfo level %u - no session key - %s\n",
653 s.in.level, nt_errstr(status));
657 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
659 torture_comment(tctx, "Testing SetUserInfo level 23 (set password)\n");
661 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
662 if (!NT_STATUS_IS_OK(status)) {
663 printf("SetUserInfo level %u failed - %s\n",
664 s.in.level, nt_errstr(status));
670 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
672 status = dcerpc_fetch_session_key(p, &session_key);
673 if (!NT_STATUS_IS_OK(status)) {
674 printf("SetUserInfo level %u - no session key - %s\n",
675 s.in.level, nt_errstr(status));
679 /* This should break the key nicely */
680 session_key.length--;
681 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
683 torture_comment(tctx, "Testing SetUserInfo level 23 (set password) with wrong password\n");
685 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
686 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
687 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
688 s.in.level, nt_errstr(status));
696 static bool test_SetUserPassEx(struct dcerpc_pipe *p, struct torture_context *tctx,
697 struct policy_handle *handle, bool makeshort,
701 struct samr_SetUserInfo s;
702 union samr_UserInfo u;
704 DATA_BLOB session_key;
705 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
706 uint8_t confounder[16];
708 struct MD5Context ctx;
709 struct samr_GetUserPwInfo pwp;
710 struct samr_PwInfo info;
711 int policy_min_pw_len = 0;
712 pwp.in.user_handle = handle;
713 pwp.out.info = &info;
715 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
716 if (NT_STATUS_IS_OK(status)) {
717 policy_min_pw_len = pwp.out.info->min_password_length;
719 if (makeshort && policy_min_pw_len) {
720 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len - 1);
722 newpass = samr_rand_pass(tctx, policy_min_pw_len);
725 s.in.user_handle = handle;
729 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
730 u.info26.password_expired = 0;
732 status = dcerpc_fetch_session_key(p, &session_key);
733 if (!NT_STATUS_IS_OK(status)) {
734 printf("SetUserInfo level %u - no session key - %s\n",
735 s.in.level, nt_errstr(status));
739 generate_random_buffer((uint8_t *)confounder, 16);
742 MD5Update(&ctx, confounder, 16);
743 MD5Update(&ctx, session_key.data, session_key.length);
744 MD5Final(confounded_session_key.data, &ctx);
746 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
747 memcpy(&u.info26.password.data[516], confounder, 16);
749 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex)\n");
751 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
752 if (!NT_STATUS_IS_OK(status)) {
753 printf("SetUserInfo level %u failed - %s\n",
754 s.in.level, nt_errstr(status));
760 /* This should break the key nicely */
761 confounded_session_key.data[0]++;
763 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
764 memcpy(&u.info26.password.data[516], confounder, 16);
766 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
768 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
769 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
770 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
771 s.in.level, nt_errstr(status));
780 static bool test_SetUserPass_25(struct dcerpc_pipe *p, struct torture_context *tctx,
781 struct policy_handle *handle, uint32_t fields_present,
785 struct samr_SetUserInfo s;
786 union samr_UserInfo u;
788 DATA_BLOB session_key;
789 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
790 struct MD5Context ctx;
791 uint8_t confounder[16];
793 struct samr_GetUserPwInfo pwp;
794 struct samr_PwInfo info;
795 int policy_min_pw_len = 0;
796 pwp.in.user_handle = handle;
797 pwp.out.info = &info;
799 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
800 if (NT_STATUS_IS_OK(status)) {
801 policy_min_pw_len = pwp.out.info->min_password_length;
803 newpass = samr_rand_pass(tctx, policy_min_pw_len);
805 s.in.user_handle = handle;
811 u.info25.info.fields_present = fields_present;
813 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
815 status = dcerpc_fetch_session_key(p, &session_key);
816 if (!NT_STATUS_IS_OK(status)) {
817 printf("SetUserInfo level %u - no session key - %s\n",
818 s.in.level, nt_errstr(status));
822 generate_random_buffer((uint8_t *)confounder, 16);
825 MD5Update(&ctx, confounder, 16);
826 MD5Update(&ctx, session_key.data, session_key.length);
827 MD5Final(confounded_session_key.data, &ctx);
829 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
830 memcpy(&u.info25.password.data[516], confounder, 16);
832 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex)\n");
834 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
835 if (!NT_STATUS_IS_OK(status)) {
836 printf("SetUserInfo level %u failed - %s\n",
837 s.in.level, nt_errstr(status));
843 /* This should break the key nicely */
844 confounded_session_key.data[0]++;
846 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
847 memcpy(&u.info25.password.data[516], confounder, 16);
849 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
851 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
852 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
853 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
854 s.in.level, nt_errstr(status));
861 static bool test_SetUserPass_18(struct dcerpc_pipe *p, struct torture_context *tctx,
862 struct policy_handle *handle, char **password)
865 struct samr_SetUserInfo s;
866 union samr_UserInfo u;
868 DATA_BLOB session_key;
870 struct samr_GetUserPwInfo pwp;
871 struct samr_PwInfo info;
872 int policy_min_pw_len = 0;
873 uint8_t lm_hash[16], nt_hash[16];
875 pwp.in.user_handle = handle;
876 pwp.out.info = &info;
878 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
879 if (NT_STATUS_IS_OK(status)) {
880 policy_min_pw_len = pwp.out.info->min_password_length;
882 newpass = samr_rand_pass(tctx, policy_min_pw_len);
884 s.in.user_handle = handle;
890 u.info18.nt_pwd_active = true;
891 u.info18.lm_pwd_active = true;
893 E_md4hash(newpass, nt_hash);
894 E_deshash(newpass, lm_hash);
896 status = dcerpc_fetch_session_key(p, &session_key);
897 if (!NT_STATUS_IS_OK(status)) {
898 printf("SetUserInfo level %u - no session key - %s\n",
899 s.in.level, nt_errstr(status));
905 in = data_blob_const(nt_hash, 16);
906 out = data_blob_talloc_zero(tctx, 16);
907 sess_crypt_blob(&out, &in, &session_key, true);
908 memcpy(u.info18.nt_pwd.hash, out.data, out.length);
912 in = data_blob_const(lm_hash, 16);
913 out = data_blob_talloc_zero(tctx, 16);
914 sess_crypt_blob(&out, &in, &session_key, true);
915 memcpy(u.info18.lm_pwd.hash, out.data, out.length);
918 torture_comment(tctx, "Testing SetUserInfo level 18 (set password hash)\n");
920 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
921 if (!NT_STATUS_IS_OK(status)) {
922 printf("SetUserInfo level %u failed - %s\n",
923 s.in.level, nt_errstr(status));
932 static bool test_SetUserPass_21(struct dcerpc_pipe *p, struct torture_context *tctx,
933 struct policy_handle *handle, uint32_t fields_present,
937 struct samr_SetUserInfo s;
938 union samr_UserInfo u;
940 DATA_BLOB session_key;
942 struct samr_GetUserPwInfo pwp;
943 struct samr_PwInfo info;
944 int policy_min_pw_len = 0;
945 uint8_t lm_hash[16], nt_hash[16];
947 pwp.in.user_handle = handle;
948 pwp.out.info = &info;
950 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
951 if (NT_STATUS_IS_OK(status)) {
952 policy_min_pw_len = pwp.out.info->min_password_length;
954 newpass = samr_rand_pass(tctx, policy_min_pw_len);
956 s.in.user_handle = handle;
960 E_md4hash(newpass, nt_hash);
961 E_deshash(newpass, lm_hash);
965 u.info21.fields_present = fields_present;
967 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
968 u.info21.lm_owf_password.length = 16;
969 u.info21.lm_owf_password.size = 16;
970 u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
971 u.info21.lm_password_set = true;
974 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
975 u.info21.nt_owf_password.length = 16;
976 u.info21.nt_owf_password.size = 16;
977 u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
978 u.info21.nt_password_set = true;
981 status = dcerpc_fetch_session_key(p, &session_key);
982 if (!NT_STATUS_IS_OK(status)) {
983 printf("SetUserInfo level %u - no session key - %s\n",
984 s.in.level, nt_errstr(status));
988 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
990 in = data_blob_const(u.info21.lm_owf_password.array,
991 u.info21.lm_owf_password.length);
992 out = data_blob_talloc_zero(tctx, 16);
993 sess_crypt_blob(&out, &in, &session_key, true);
994 u.info21.lm_owf_password.array = (uint16_t *)out.data;
997 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
999 in = data_blob_const(u.info21.nt_owf_password.array,
1000 u.info21.nt_owf_password.length);
1001 out = data_blob_talloc_zero(tctx, 16);
1002 sess_crypt_blob(&out, &in, &session_key, true);
1003 u.info21.nt_owf_password.array = (uint16_t *)out.data;
1006 torture_comment(tctx, "Testing SetUserInfo level 21 (set password hash)\n");
1008 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1009 if (!NT_STATUS_IS_OK(status)) {
1010 printf("SetUserInfo level %u failed - %s\n",
1011 s.in.level, nt_errstr(status));
1014 *password = newpass;
1017 /* try invalid length */
1018 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1020 u.info21.nt_owf_password.length++;
1022 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1024 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1025 printf("SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1026 s.in.level, nt_errstr(status));
1031 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1033 u.info21.lm_owf_password.length++;
1035 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1037 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1038 printf("SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1039 s.in.level, nt_errstr(status));
1047 static bool test_SetUserPass_level_ex(struct dcerpc_pipe *p,
1048 struct torture_context *tctx,
1049 struct policy_handle *handle,
1051 uint32_t fields_present,
1052 char **password, uint8_t password_expired,
1054 bool *matched_expected_error)
1057 NTSTATUS expected_error = NT_STATUS_OK;
1058 struct samr_SetUserInfo s;
1059 struct samr_SetUserInfo2 s2;
1060 union samr_UserInfo u;
1062 DATA_BLOB session_key;
1063 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
1064 struct MD5Context ctx;
1065 uint8_t confounder[16];
1067 struct samr_GetUserPwInfo pwp;
1068 struct samr_PwInfo info;
1069 int policy_min_pw_len = 0;
1070 const char *comment = NULL;
1071 uint8_t lm_hash[16], nt_hash[16];
1073 pwp.in.user_handle = handle;
1074 pwp.out.info = &info;
1076 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1077 if (NT_STATUS_IS_OK(status)) {
1078 policy_min_pw_len = pwp.out.info->min_password_length;
1080 newpass = samr_rand_pass_silent(tctx, policy_min_pw_len);
1083 s2.in.user_handle = handle;
1085 s2.in.level = level;
1087 s.in.user_handle = handle;
1092 if (fields_present & SAMR_FIELD_COMMENT) {
1093 comment = talloc_asprintf(tctx, "comment: %ld\n", time(NULL));
1100 E_md4hash(newpass, nt_hash);
1101 E_deshash(newpass, lm_hash);
1103 u.info18.nt_pwd_active = true;
1104 u.info18.lm_pwd_active = true;
1105 u.info18.password_expired = password_expired;
1107 memcpy(u.info18.lm_pwd.hash, lm_hash, 16);
1108 memcpy(u.info18.nt_pwd.hash, nt_hash, 16);
1112 E_md4hash(newpass, nt_hash);
1113 E_deshash(newpass, lm_hash);
1115 u.info21.fields_present = fields_present;
1116 u.info21.password_expired = password_expired;
1117 u.info21.comment.string = comment;
1119 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1120 u.info21.lm_owf_password.length = 16;
1121 u.info21.lm_owf_password.size = 16;
1122 u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
1123 u.info21.lm_password_set = true;
1126 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1127 u.info21.nt_owf_password.length = 16;
1128 u.info21.nt_owf_password.size = 16;
1129 u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
1130 u.info21.nt_password_set = true;
1135 u.info23.info.fields_present = fields_present;
1136 u.info23.info.password_expired = password_expired;
1137 u.info23.info.comment.string = comment;
1139 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
1143 u.info24.password_expired = password_expired;
1145 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
1149 u.info25.info.fields_present = fields_present;
1150 u.info25.info.password_expired = password_expired;
1151 u.info25.info.comment.string = comment;
1153 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
1157 u.info26.password_expired = password_expired;
1159 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
1164 status = dcerpc_fetch_session_key(p, &session_key);
1165 if (!NT_STATUS_IS_OK(status)) {
1166 printf("SetUserInfo level %u - no session key - %s\n",
1167 s.in.level, nt_errstr(status));
1171 generate_random_buffer((uint8_t *)confounder, 16);
1174 MD5Update(&ctx, confounder, 16);
1175 MD5Update(&ctx, session_key.data, session_key.length);
1176 MD5Final(confounded_session_key.data, &ctx);
1182 in = data_blob_const(u.info18.nt_pwd.hash, 16);
1183 out = data_blob_talloc_zero(tctx, 16);
1184 sess_crypt_blob(&out, &in, &session_key, true);
1185 memcpy(u.info18.nt_pwd.hash, out.data, out.length);
1189 in = data_blob_const(u.info18.lm_pwd.hash, 16);
1190 out = data_blob_talloc_zero(tctx, 16);
1191 sess_crypt_blob(&out, &in, &session_key, true);
1192 memcpy(u.info18.lm_pwd.hash, out.data, out.length);
1197 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1199 in = data_blob_const(u.info21.lm_owf_password.array,
1200 u.info21.lm_owf_password.length);
1201 out = data_blob_talloc_zero(tctx, 16);
1202 sess_crypt_blob(&out, &in, &session_key, true);
1203 u.info21.lm_owf_password.array = (uint16_t *)out.data;
1205 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1207 in = data_blob_const(u.info21.nt_owf_password.array,
1208 u.info21.nt_owf_password.length);
1209 out = data_blob_talloc_zero(tctx, 16);
1210 sess_crypt_blob(&out, &in, &session_key, true);
1211 u.info21.nt_owf_password.array = (uint16_t *)out.data;
1215 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
1218 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
1221 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
1222 memcpy(&u.info25.password.data[516], confounder, 16);
1225 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
1226 memcpy(&u.info26.password.data[516], confounder, 16);
1231 status = dcerpc_samr_SetUserInfo2(p, tctx, &s2);
1233 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1236 if (!NT_STATUS_IS_OK(status)) {
1237 if (fields_present == 0) {
1238 expected_error = NT_STATUS_INVALID_PARAMETER;
1240 if (fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
1241 expected_error = NT_STATUS_ACCESS_DENIED;
1245 if (!NT_STATUS_IS_OK(expected_error)) {
1247 torture_assert_ntstatus_equal(tctx,
1249 expected_error, "SetUserInfo2 failed");
1251 torture_assert_ntstatus_equal(tctx,
1253 expected_error, "SetUserInfo failed");
1255 *matched_expected_error = true;
1259 if (!NT_STATUS_IS_OK(status)) {
1260 printf("SetUserInfo%s level %u failed - %s\n",
1261 use_setinfo2 ? "2":"", level, nt_errstr(status));
1264 *password = newpass;
1270 static bool test_SetAliasInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1271 struct policy_handle *handle)
1274 struct samr_SetAliasInfo r;
1275 struct samr_QueryAliasInfo q;
1276 union samr_AliasInfo *info;
1277 uint16_t levels[] = {2, 3};
1281 /* Ignoring switch level 1, as that includes the number of members for the alias
1282 * and setting this to a wrong value might have negative consequences
1285 for (i=0;i<ARRAY_SIZE(levels);i++) {
1286 torture_comment(tctx, "Testing SetAliasInfo level %u\n", levels[i]);
1288 r.in.alias_handle = handle;
1289 r.in.level = levels[i];
1290 r.in.info = talloc(tctx, union samr_AliasInfo);
1291 switch (r.in.level) {
1292 case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
1293 case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
1294 "Test Description, should test I18N as well"); break;
1295 case ALIASINFOALL: printf("ALIASINFOALL ignored\n"); break;
1298 status = dcerpc_samr_SetAliasInfo(p, tctx, &r);
1299 if (!NT_STATUS_IS_OK(status)) {
1300 printf("SetAliasInfo level %u failed - %s\n",
1301 levels[i], nt_errstr(status));
1305 q.in.alias_handle = handle;
1306 q.in.level = levels[i];
1309 status = dcerpc_samr_QueryAliasInfo(p, tctx, &q);
1310 if (!NT_STATUS_IS_OK(status)) {
1311 printf("QueryAliasInfo level %u failed - %s\n",
1312 levels[i], nt_errstr(status));
1320 static bool test_GetGroupsForUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1321 struct policy_handle *user_handle)
1323 struct samr_GetGroupsForUser r;
1324 struct samr_RidWithAttributeArray *rids = NULL;
1327 torture_comment(tctx, "testing GetGroupsForUser\n");
1329 r.in.user_handle = user_handle;
1332 status = dcerpc_samr_GetGroupsForUser(p, tctx, &r);
1333 torture_assert_ntstatus_ok(tctx, status, "GetGroupsForUser");
1339 static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1340 struct lsa_String *domain_name)
1343 struct samr_GetDomPwInfo r;
1344 struct samr_PwInfo info;
1346 r.in.domain_name = domain_name;
1349 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1351 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1352 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1354 r.in.domain_name->string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1355 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1357 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1358 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1360 r.in.domain_name->string = "\\\\__NONAME__";
1361 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1363 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1364 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1366 r.in.domain_name->string = "\\\\Builtin";
1367 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1369 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1370 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1375 static bool test_GetUserPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1376 struct policy_handle *handle)
1379 struct samr_GetUserPwInfo r;
1380 struct samr_PwInfo info;
1382 torture_comment(tctx, "Testing GetUserPwInfo\n");
1384 r.in.user_handle = handle;
1387 status = dcerpc_samr_GetUserPwInfo(p, tctx, &r);
1388 torture_assert_ntstatus_ok(tctx, status, "GetUserPwInfo");
1393 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, struct torture_context *tctx,
1394 struct policy_handle *domain_handle, const char *name,
1398 struct samr_LookupNames n;
1399 struct lsa_String sname[2];
1400 struct samr_Ids rids, types;
1402 init_lsa_String(&sname[0], name);
1404 n.in.domain_handle = domain_handle;
1408 n.out.types = &types;
1409 status = dcerpc_samr_LookupNames(p, tctx, &n);
1410 if (NT_STATUS_IS_OK(status)) {
1411 *rid = n.out.rids->ids[0];
1416 init_lsa_String(&sname[1], "xxNONAMExx");
1418 status = dcerpc_samr_LookupNames(p, tctx, &n);
1419 if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
1420 printf("LookupNames[2] failed - %s\n", nt_errstr(status));
1421 if (NT_STATUS_IS_OK(status)) {
1422 return NT_STATUS_UNSUCCESSFUL;
1428 status = dcerpc_samr_LookupNames(p, tctx, &n);
1429 if (!NT_STATUS_IS_OK(status)) {
1430 printf("LookupNames[0] failed - %s\n", nt_errstr(status));
1434 init_lsa_String(&sname[0], "xxNONAMExx");
1436 status = dcerpc_samr_LookupNames(p, tctx, &n);
1437 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1438 printf("LookupNames[1 bad name] failed - %s\n", nt_errstr(status));
1439 if (NT_STATUS_IS_OK(status)) {
1440 return NT_STATUS_UNSUCCESSFUL;
1445 init_lsa_String(&sname[0], "xxNONAMExx");
1446 init_lsa_String(&sname[1], "xxNONAME2xx");
1448 status = dcerpc_samr_LookupNames(p, tctx, &n);
1449 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1450 printf("LookupNames[2 bad names] failed - %s\n", nt_errstr(status));
1451 if (NT_STATUS_IS_OK(status)) {
1452 return NT_STATUS_UNSUCCESSFUL;
1457 return NT_STATUS_OK;
1460 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1461 struct policy_handle *domain_handle,
1462 const char *name, struct policy_handle *user_handle)
1465 struct samr_OpenUser r;
1468 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
1469 if (!NT_STATUS_IS_OK(status)) {
1473 r.in.domain_handle = domain_handle;
1474 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1476 r.out.user_handle = user_handle;
1477 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
1478 if (!NT_STATUS_IS_OK(status)) {
1479 printf("OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(status));
1486 static bool test_ChangePasswordNT3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1487 struct policy_handle *handle)
1490 struct samr_ChangePasswordUser r;
1492 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1493 struct policy_handle user_handle;
1494 char *oldpass = "test";
1495 char *newpass = "test2";
1496 uint8_t old_nt_hash[16], new_nt_hash[16];
1497 uint8_t old_lm_hash[16], new_lm_hash[16];
1499 status = test_OpenUser_byname(p, mem_ctx, handle, "testuser", &user_handle);
1500 if (!NT_STATUS_IS_OK(status)) {
1504 printf("Testing ChangePasswordUser for user 'testuser'\n");
1506 printf("old password: %s\n", oldpass);
1507 printf("new password: %s\n", newpass);
1509 E_md4hash(oldpass, old_nt_hash);
1510 E_md4hash(newpass, new_nt_hash);
1511 E_deshash(oldpass, old_lm_hash);
1512 E_deshash(newpass, new_lm_hash);
1514 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1515 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1516 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1517 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1518 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1519 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1521 r.in.handle = &user_handle;
1522 r.in.lm_present = 1;
1523 r.in.old_lm_crypted = &hash1;
1524 r.in.new_lm_crypted = &hash2;
1525 r.in.nt_present = 1;
1526 r.in.old_nt_crypted = &hash3;
1527 r.in.new_nt_crypted = &hash4;
1528 r.in.cross1_present = 1;
1529 r.in.nt_cross = &hash5;
1530 r.in.cross2_present = 1;
1531 r.in.lm_cross = &hash6;
1533 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1534 if (!NT_STATUS_IS_OK(status)) {
1535 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1539 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1547 static bool test_ChangePasswordUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1548 const char *acct_name,
1549 struct policy_handle *handle, char **password)
1552 struct samr_ChangePasswordUser r;
1554 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1555 struct policy_handle user_handle;
1557 uint8_t old_nt_hash[16], new_nt_hash[16];
1558 uint8_t old_lm_hash[16], new_lm_hash[16];
1559 bool changed = true;
1562 struct samr_GetUserPwInfo pwp;
1563 struct samr_PwInfo info;
1564 int policy_min_pw_len = 0;
1566 status = test_OpenUser_byname(p, tctx, handle, acct_name, &user_handle);
1567 if (!NT_STATUS_IS_OK(status)) {
1570 pwp.in.user_handle = &user_handle;
1571 pwp.out.info = &info;
1573 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1574 if (NT_STATUS_IS_OK(status)) {
1575 policy_min_pw_len = pwp.out.info->min_password_length;
1577 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1579 torture_comment(tctx, "Testing ChangePasswordUser\n");
1581 torture_assert(tctx, *password != NULL,
1582 "Failing ChangePasswordUser as old password was NULL. Previous test failed?");
1584 oldpass = *password;
1586 E_md4hash(oldpass, old_nt_hash);
1587 E_md4hash(newpass, new_nt_hash);
1588 E_deshash(oldpass, old_lm_hash);
1589 E_deshash(newpass, new_lm_hash);
1591 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1592 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1593 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1594 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1595 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1596 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1598 r.in.user_handle = &user_handle;
1599 r.in.lm_present = 1;
1600 /* Break the LM hash */
1602 r.in.old_lm_crypted = &hash1;
1603 r.in.new_lm_crypted = &hash2;
1604 r.in.nt_present = 1;
1605 r.in.old_nt_crypted = &hash3;
1606 r.in.new_nt_crypted = &hash4;
1607 r.in.cross1_present = 1;
1608 r.in.nt_cross = &hash5;
1609 r.in.cross2_present = 1;
1610 r.in.lm_cross = &hash6;
1612 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1613 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1614 "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash");
1616 /* Unbreak the LM hash */
1619 r.in.user_handle = &user_handle;
1620 r.in.lm_present = 1;
1621 r.in.old_lm_crypted = &hash1;
1622 r.in.new_lm_crypted = &hash2;
1623 /* Break the NT hash */
1625 r.in.nt_present = 1;
1626 r.in.old_nt_crypted = &hash3;
1627 r.in.new_nt_crypted = &hash4;
1628 r.in.cross1_present = 1;
1629 r.in.nt_cross = &hash5;
1630 r.in.cross2_present = 1;
1631 r.in.lm_cross = &hash6;
1633 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1634 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1635 "expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash");
1637 /* Unbreak the NT hash */
1640 r.in.user_handle = &user_handle;
1641 r.in.lm_present = 1;
1642 r.in.old_lm_crypted = &hash1;
1643 r.in.new_lm_crypted = &hash2;
1644 r.in.nt_present = 1;
1645 r.in.old_nt_crypted = &hash3;
1646 r.in.new_nt_crypted = &hash4;
1647 r.in.cross1_present = 1;
1648 r.in.nt_cross = &hash5;
1649 r.in.cross2_present = 1;
1650 /* Break the LM cross */
1652 r.in.lm_cross = &hash6;
1654 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1655 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1656 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status));
1660 /* Unbreak the LM cross */
1663 r.in.user_handle = &user_handle;
1664 r.in.lm_present = 1;
1665 r.in.old_lm_crypted = &hash1;
1666 r.in.new_lm_crypted = &hash2;
1667 r.in.nt_present = 1;
1668 r.in.old_nt_crypted = &hash3;
1669 r.in.new_nt_crypted = &hash4;
1670 r.in.cross1_present = 1;
1671 /* Break the NT cross */
1673 r.in.nt_cross = &hash5;
1674 r.in.cross2_present = 1;
1675 r.in.lm_cross = &hash6;
1677 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1678 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1679 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status));
1683 /* Unbreak the NT cross */
1687 /* Reset the hashes to not broken values */
1688 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1689 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1690 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1691 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1692 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1693 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1695 r.in.user_handle = &user_handle;
1696 r.in.lm_present = 1;
1697 r.in.old_lm_crypted = &hash1;
1698 r.in.new_lm_crypted = &hash2;
1699 r.in.nt_present = 1;
1700 r.in.old_nt_crypted = &hash3;
1701 r.in.new_nt_crypted = &hash4;
1702 r.in.cross1_present = 1;
1703 r.in.nt_cross = &hash5;
1704 r.in.cross2_present = 0;
1705 r.in.lm_cross = NULL;
1707 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1708 if (NT_STATUS_IS_OK(status)) {
1710 *password = newpass;
1711 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1712 printf("ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(status));
1717 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1719 E_md4hash(oldpass, old_nt_hash);
1720 E_md4hash(newpass, new_nt_hash);
1721 E_deshash(oldpass, old_lm_hash);
1722 E_deshash(newpass, new_lm_hash);
1725 /* Reset the hashes to not broken values */
1726 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1727 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1728 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1729 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1730 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1731 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1733 r.in.user_handle = &user_handle;
1734 r.in.lm_present = 1;
1735 r.in.old_lm_crypted = &hash1;
1736 r.in.new_lm_crypted = &hash2;
1737 r.in.nt_present = 1;
1738 r.in.old_nt_crypted = &hash3;
1739 r.in.new_nt_crypted = &hash4;
1740 r.in.cross1_present = 0;
1741 r.in.nt_cross = NULL;
1742 r.in.cross2_present = 1;
1743 r.in.lm_cross = &hash6;
1745 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1746 if (NT_STATUS_IS_OK(status)) {
1748 *password = newpass;
1749 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1750 printf("ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status));
1755 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1757 E_md4hash(oldpass, old_nt_hash);
1758 E_md4hash(newpass, new_nt_hash);
1759 E_deshash(oldpass, old_lm_hash);
1760 E_deshash(newpass, new_lm_hash);
1763 /* Reset the hashes to not broken values */
1764 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1765 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1766 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1767 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1768 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1769 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1771 r.in.user_handle = &user_handle;
1772 r.in.lm_present = 1;
1773 r.in.old_lm_crypted = &hash1;
1774 r.in.new_lm_crypted = &hash2;
1775 r.in.nt_present = 1;
1776 r.in.old_nt_crypted = &hash3;
1777 r.in.new_nt_crypted = &hash4;
1778 r.in.cross1_present = 1;
1779 r.in.nt_cross = &hash5;
1780 r.in.cross2_present = 1;
1781 r.in.lm_cross = &hash6;
1783 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1784 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1785 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1786 } else if (!NT_STATUS_IS_OK(status)) {
1787 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1791 *password = newpass;
1794 r.in.user_handle = &user_handle;
1795 r.in.lm_present = 1;
1796 r.in.old_lm_crypted = &hash1;
1797 r.in.new_lm_crypted = &hash2;
1798 r.in.nt_present = 1;
1799 r.in.old_nt_crypted = &hash3;
1800 r.in.new_nt_crypted = &hash4;
1801 r.in.cross1_present = 1;
1802 r.in.nt_cross = &hash5;
1803 r.in.cross2_present = 1;
1804 r.in.lm_cross = &hash6;
1807 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1808 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1809 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1810 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1811 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status));
1817 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
1825 static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
1826 const char *acct_name,
1827 struct policy_handle *handle, char **password)
1830 struct samr_OemChangePasswordUser2 r;
1832 struct samr_Password lm_verifier;
1833 struct samr_CryptPassword lm_pass;
1834 struct lsa_AsciiString server, account, account_bad;
1837 uint8_t old_lm_hash[16], new_lm_hash[16];
1839 struct samr_GetDomPwInfo dom_pw_info;
1840 struct samr_PwInfo info;
1841 int policy_min_pw_len = 0;
1843 struct lsa_String domain_name;
1845 domain_name.string = "";
1846 dom_pw_info.in.domain_name = &domain_name;
1847 dom_pw_info.out.info = &info;
1849 torture_comment(tctx, "Testing OemChangePasswordUser2\n");
1851 torture_assert(tctx, *password != NULL,
1852 "Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?");
1854 oldpass = *password;
1856 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
1857 if (NT_STATUS_IS_OK(status)) {
1858 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
1861 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1863 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1864 account.string = acct_name;
1866 E_deshash(oldpass, old_lm_hash);
1867 E_deshash(newpass, new_lm_hash);
1869 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1870 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1871 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1873 r.in.server = &server;
1874 r.in.account = &account;
1875 r.in.password = &lm_pass;
1876 r.in.hash = &lm_verifier;
1878 /* Break the verification */
1879 lm_verifier.hash[0]++;
1881 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1883 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1884 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1885 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1890 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1891 /* Break the old password */
1893 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1894 /* unbreak it for the next operation */
1896 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1898 r.in.server = &server;
1899 r.in.account = &account;
1900 r.in.password = &lm_pass;
1901 r.in.hash = &lm_verifier;
1903 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1905 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1906 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1907 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1912 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1913 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1915 r.in.server = &server;
1916 r.in.account = &account;
1917 r.in.password = &lm_pass;
1920 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1922 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1923 && !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1924 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
1929 /* This shouldn't be a valid name */
1930 account_bad.string = TEST_ACCOUNT_NAME "XX";
1931 r.in.account = &account_bad;
1933 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1935 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1936 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
1941 /* This shouldn't be a valid name */
1942 account_bad.string = TEST_ACCOUNT_NAME "XX";
1943 r.in.account = &account_bad;
1944 r.in.password = &lm_pass;
1945 r.in.hash = &lm_verifier;
1947 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1949 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1950 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1955 /* This shouldn't be a valid name */
1956 account_bad.string = TEST_ACCOUNT_NAME "XX";
1957 r.in.account = &account_bad;
1958 r.in.password = NULL;
1959 r.in.hash = &lm_verifier;
1961 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1963 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1964 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
1969 E_deshash(oldpass, old_lm_hash);
1970 E_deshash(newpass, new_lm_hash);
1972 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1973 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1974 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1976 r.in.server = &server;
1977 r.in.account = &account;
1978 r.in.password = &lm_pass;
1979 r.in.hash = &lm_verifier;
1981 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1982 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1983 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1984 } else if (!NT_STATUS_IS_OK(status)) {
1985 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
1988 *password = newpass;
1995 static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
1996 const char *acct_name,
1998 char *newpass, bool allow_password_restriction)
2001 struct samr_ChangePasswordUser2 r;
2003 struct lsa_String server, account;
2004 struct samr_CryptPassword nt_pass, lm_pass;
2005 struct samr_Password nt_verifier, lm_verifier;
2007 uint8_t old_nt_hash[16], new_nt_hash[16];
2008 uint8_t old_lm_hash[16], new_lm_hash[16];
2010 struct samr_GetDomPwInfo dom_pw_info;
2011 struct samr_PwInfo info;
2013 struct lsa_String domain_name;
2015 domain_name.string = "";
2016 dom_pw_info.in.domain_name = &domain_name;
2017 dom_pw_info.out.info = &info;
2019 torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name);
2021 torture_assert(tctx, *password != NULL,
2022 "Failing ChangePasswordUser2 as old password was NULL. Previous test failed?");
2023 oldpass = *password;
2026 int policy_min_pw_len = 0;
2027 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
2028 if (NT_STATUS_IS_OK(status)) {
2029 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
2032 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2035 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2036 init_lsa_String(&account, acct_name);
2038 E_md4hash(oldpass, old_nt_hash);
2039 E_md4hash(newpass, new_nt_hash);
2041 E_deshash(oldpass, old_lm_hash);
2042 E_deshash(newpass, new_lm_hash);
2044 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
2045 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2046 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2048 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2049 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2050 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2052 r.in.server = &server;
2053 r.in.account = &account;
2054 r.in.nt_password = &nt_pass;
2055 r.in.nt_verifier = &nt_verifier;
2057 r.in.lm_password = &lm_pass;
2058 r.in.lm_verifier = &lm_verifier;
2060 status = dcerpc_samr_ChangePasswordUser2(p, tctx, &r);
2061 if (allow_password_restriction && NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2062 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
2063 } else if (!NT_STATUS_IS_OK(status)) {
2064 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
2067 *password = newpass;
2074 bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tctx,
2075 const char *account_string,
2076 int policy_min_pw_len,
2078 const char *newpass,
2079 NTTIME last_password_change,
2080 bool handle_reject_reason)
2083 struct samr_ChangePasswordUser3 r;
2085 struct lsa_String server, account, account_bad;
2086 struct samr_CryptPassword nt_pass, lm_pass;
2087 struct samr_Password nt_verifier, lm_verifier;
2089 uint8_t old_nt_hash[16], new_nt_hash[16];
2090 uint8_t old_lm_hash[16], new_lm_hash[16];
2092 struct samr_DomInfo1 *dominfo = NULL;
2093 struct samr_ChangeReject *reject = NULL;
2095 torture_comment(tctx, "Testing ChangePasswordUser3\n");
2097 if (newpass == NULL) {
2099 if (policy_min_pw_len == 0) {
2100 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2102 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len);
2104 } while (check_password_quality(newpass) == false);
2106 torture_comment(tctx, "Using password '%s'\n", newpass);
2109 torture_assert(tctx, *password != NULL,
2110 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2112 oldpass = *password;
2113 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2114 init_lsa_String(&account, account_string);
2116 E_md4hash(oldpass, old_nt_hash);
2117 E_md4hash(newpass, new_nt_hash);
2119 E_deshash(oldpass, old_lm_hash);
2120 E_deshash(newpass, new_lm_hash);
2122 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2123 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2124 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2126 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2127 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2128 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2130 /* Break the verification */
2131 nt_verifier.hash[0]++;
2133 r.in.server = &server;
2134 r.in.account = &account;
2135 r.in.nt_password = &nt_pass;
2136 r.in.nt_verifier = &nt_verifier;
2138 r.in.lm_password = &lm_pass;
2139 r.in.lm_verifier = &lm_verifier;
2140 r.in.password3 = NULL;
2141 r.out.dominfo = &dominfo;
2142 r.out.reject = &reject;
2144 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2145 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
2146 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
2147 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
2152 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2153 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2154 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2156 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2157 /* Break the NT hash */
2159 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2160 /* Unbreak it again */
2162 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2164 r.in.server = &server;
2165 r.in.account = &account;
2166 r.in.nt_password = &nt_pass;
2167 r.in.nt_verifier = &nt_verifier;
2169 r.in.lm_password = &lm_pass;
2170 r.in.lm_verifier = &lm_verifier;
2171 r.in.password3 = NULL;
2172 r.out.dominfo = &dominfo;
2173 r.out.reject = &reject;
2175 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2176 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
2177 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
2178 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
2183 /* This shouldn't be a valid name */
2184 init_lsa_String(&account_bad, talloc_asprintf(tctx, "%sXX", account_string));
2186 r.in.account = &account_bad;
2187 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2188 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
2189 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
2194 E_md4hash(oldpass, old_nt_hash);
2195 E_md4hash(newpass, new_nt_hash);
2197 E_deshash(oldpass, old_lm_hash);
2198 E_deshash(newpass, new_lm_hash);
2200 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2201 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2202 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2204 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2205 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2206 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2208 r.in.server = &server;
2209 r.in.account = &account;
2210 r.in.nt_password = &nt_pass;
2211 r.in.nt_verifier = &nt_verifier;
2213 r.in.lm_password = &lm_pass;
2214 r.in.lm_verifier = &lm_verifier;
2215 r.in.password3 = NULL;
2216 r.out.dominfo = &dominfo;
2217 r.out.reject = &reject;
2219 unix_to_nt_time(&t, time(NULL));
2221 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2223 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
2226 && handle_reject_reason
2227 && (!null_nttime(last_password_change) || !dominfo->min_password_age)) {
2228 if (dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
2230 if (reject && (reject->reason != SAMR_REJECT_OTHER)) {
2231 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2232 SAMR_REJECT_OTHER, reject->reason);
2237 /* We tested the order of precendence which is as follows:
2246 if ((dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
2247 (last_password_change + dominfo->min_password_age > t)) {
2249 if (reject->reason != SAMR_REJECT_OTHER) {
2250 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2251 SAMR_REJECT_OTHER, reject->reason);
2255 } else if ((dominfo->min_password_length > 0) &&
2256 (strlen(newpass) < dominfo->min_password_length)) {
2258 if (reject->reason != SAMR_REJECT_TOO_SHORT) {
2259 printf("expected SAMR_REJECT_TOO_SHORT (%d), got %d\n",
2260 SAMR_REJECT_TOO_SHORT, reject->reason);
2264 } else if ((dominfo->password_history_length > 0) &&
2265 strequal(oldpass, newpass)) {
2267 if (reject->reason != SAMR_REJECT_IN_HISTORY) {
2268 printf("expected SAMR_REJECT_IN_HISTORY (%d), got %d\n",
2269 SAMR_REJECT_IN_HISTORY, reject->reason);
2272 } else if (dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
2274 if (reject->reason != SAMR_REJECT_COMPLEXITY) {
2275 printf("expected SAMR_REJECT_COMPLEXITY (%d), got %d\n",
2276 SAMR_REJECT_COMPLEXITY, reject->reason);
2282 if (reject->reason == SAMR_REJECT_TOO_SHORT) {
2283 /* retry with adjusted size */
2284 return test_ChangePasswordUser3(p, tctx, account_string,
2285 dominfo->min_password_length,
2286 password, NULL, 0, false);
2290 } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2291 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2292 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2293 SAMR_REJECT_OTHER, reject->reason);
2296 /* Perhaps the server has a 'min password age' set? */
2299 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3");
2300 *password = talloc_strdup(tctx, newpass);
2306 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_context *tctx,
2307 const char *account_string,
2308 struct policy_handle *handle,
2312 struct samr_ChangePasswordUser3 r;
2313 struct samr_SetUserInfo s;
2314 union samr_UserInfo u;
2315 DATA_BLOB session_key;
2316 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
2317 uint8_t confounder[16];
2318 struct MD5Context ctx;
2321 struct lsa_String server, account;
2322 struct samr_CryptPassword nt_pass;
2323 struct samr_Password nt_verifier;
2324 DATA_BLOB new_random_pass;
2327 uint8_t old_nt_hash[16], new_nt_hash[16];
2329 struct samr_DomInfo1 *dominfo = NULL;
2330 struct samr_ChangeReject *reject = NULL;
2332 new_random_pass = samr_very_rand_pass(tctx, 128);
2334 torture_assert(tctx, *password != NULL,
2335 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2337 oldpass = *password;
2338 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2339 init_lsa_String(&account, account_string);
2341 s.in.user_handle = handle;
2347 u.info25.info.fields_present = SAMR_FIELD_NT_PASSWORD_PRESENT;
2349 set_pw_in_buffer(u.info25.password.data, &new_random_pass);
2351 status = dcerpc_fetch_session_key(p, &session_key);
2352 if (!NT_STATUS_IS_OK(status)) {
2353 printf("SetUserInfo level %u - no session key - %s\n",
2354 s.in.level, nt_errstr(status));
2358 generate_random_buffer((uint8_t *)confounder, 16);
2361 MD5Update(&ctx, confounder, 16);
2362 MD5Update(&ctx, session_key.data, session_key.length);
2363 MD5Final(confounded_session_key.data, &ctx);
2365 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
2366 memcpy(&u.info25.password.data[516], confounder, 16);
2368 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
2370 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
2371 if (!NT_STATUS_IS_OK(status)) {
2372 printf("SetUserInfo level %u failed - %s\n",
2373 s.in.level, nt_errstr(status));
2377 torture_comment(tctx, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
2379 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2381 new_random_pass = samr_very_rand_pass(tctx, 128);
2383 mdfour(new_nt_hash, new_random_pass.data, new_random_pass.length);
2385 set_pw_in_buffer(nt_pass.data, &new_random_pass);
2386 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2387 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2389 r.in.server = &server;
2390 r.in.account = &account;
2391 r.in.nt_password = &nt_pass;
2392 r.in.nt_verifier = &nt_verifier;
2394 r.in.lm_password = NULL;
2395 r.in.lm_verifier = NULL;
2396 r.in.password3 = NULL;
2397 r.out.dominfo = &dominfo;
2398 r.out.reject = &reject;
2400 unix_to_nt_time(&t, time(NULL));
2402 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2404 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2405 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2406 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2407 SAMR_REJECT_OTHER, reject->reason);
2410 /* Perhaps the server has a 'min password age' set? */
2412 } else if (!NT_STATUS_IS_OK(status)) {
2413 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
2417 newpass = samr_rand_pass(tctx, 128);
2419 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2421 E_md4hash(newpass, new_nt_hash);
2423 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2424 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2425 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2427 r.in.server = &server;
2428 r.in.account = &account;
2429 r.in.nt_password = &nt_pass;
2430 r.in.nt_verifier = &nt_verifier;
2432 r.in.lm_password = NULL;
2433 r.in.lm_verifier = NULL;
2434 r.in.password3 = NULL;
2435 r.out.dominfo = &dominfo;
2436 r.out.reject = &reject;
2438 unix_to_nt_time(&t, time(NULL));
2440 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2442 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2443 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2444 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2445 SAMR_REJECT_OTHER, reject->reason);
2448 /* Perhaps the server has a 'min password age' set? */
2451 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3 (on second random password)");
2452 *password = talloc_strdup(tctx, newpass);
2459 static bool test_GetMembersInAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2460 struct policy_handle *alias_handle)
2462 struct samr_GetMembersInAlias r;
2463 struct lsa_SidArray sids;
2466 torture_comment(tctx, "Testing GetMembersInAlias\n");
2468 r.in.alias_handle = alias_handle;
2471 status = dcerpc_samr_GetMembersInAlias(p, tctx, &r);
2472 torture_assert_ntstatus_ok(tctx, status, "GetMembersInAlias");
2477 static bool test_AddMemberToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2478 struct policy_handle *alias_handle,
2479 const struct dom_sid *domain_sid)
2481 struct samr_AddAliasMember r;
2482 struct samr_DeleteAliasMember d;
2484 struct dom_sid *sid;
2486 sid = dom_sid_add_rid(tctx, domain_sid, 512);
2488 torture_comment(tctx, "testing AddAliasMember\n");
2489 r.in.alias_handle = alias_handle;
2492 status = dcerpc_samr_AddAliasMember(p, tctx, &r);
2493 torture_assert_ntstatus_ok(tctx, status, "AddAliasMember");
2495 d.in.alias_handle = alias_handle;
2498 status = dcerpc_samr_DeleteAliasMember(p, tctx, &d);
2499 torture_assert_ntstatus_ok(tctx, status, "DelAliasMember");
2504 static bool test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2505 struct policy_handle *alias_handle)
2507 struct samr_AddMultipleMembersToAlias a;
2508 struct samr_RemoveMultipleMembersFromAlias r;
2510 struct lsa_SidArray sids;
2512 torture_comment(tctx, "testing AddMultipleMembersToAlias\n");
2513 a.in.alias_handle = alias_handle;
2517 sids.sids = talloc_array(tctx, struct lsa_SidPtr, 3);
2519 sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2520 sids.sids[1].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-2");
2521 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-3");
2523 status = dcerpc_samr_AddMultipleMembersToAlias(p, tctx, &a);
2524 torture_assert_ntstatus_ok(tctx, status, "AddMultipleMembersToAlias");
2527 torture_comment(tctx, "testing RemoveMultipleMembersFromAlias\n");
2528 r.in.alias_handle = alias_handle;
2531 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2532 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2534 /* strange! removing twice doesn't give any error */
2535 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2536 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2538 /* but removing an alias that isn't there does */
2539 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-4");
2541 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2542 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, "RemoveMultipleMembersFromAlias");
2547 static bool test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2548 struct policy_handle *user_handle)
2550 struct samr_TestPrivateFunctionsUser r;
2553 torture_comment(tctx, "Testing TestPrivateFunctionsUser\n");
2555 r.in.user_handle = user_handle;
2557 status = dcerpc_samr_TestPrivateFunctionsUser(p, tctx, &r);
2558 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsUser");
2563 static bool test_QueryUserInfo_pwdlastset(struct dcerpc_pipe *p,
2564 struct torture_context *tctx,
2565 struct policy_handle *handle,
2570 uint16_t levels[] = { /* 3, */ 5, 21 };
2572 NTTIME pwdlastset3 = 0;
2573 NTTIME pwdlastset5 = 0;
2574 NTTIME pwdlastset21 = 0;
2576 torture_comment(tctx, "Testing QueryUserInfo%s level 5 and 21 call ",
2577 use_info2 ? "2":"");
2579 for (i=0; i<ARRAY_SIZE(levels); i++) {
2581 struct samr_QueryUserInfo r;
2582 struct samr_QueryUserInfo2 r2;
2583 union samr_UserInfo *info;
2586 r2.in.user_handle = handle;
2587 r2.in.level = levels[i];
2588 r2.out.info = &info;
2589 status = dcerpc_samr_QueryUserInfo2(p, tctx, &r2);
2592 r.in.user_handle = handle;
2593 r.in.level = levels[i];
2595 status = dcerpc_samr_QueryUserInfo(p, tctx, &r);
2598 if (!NT_STATUS_IS_OK(status) &&
2599 !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
2600 printf("QueryUserInfo%s level %u failed - %s\n",
2601 use_info2 ? "2":"", levels[i], nt_errstr(status));
2605 switch (levels[i]) {
2607 pwdlastset3 = info->info3.last_password_change;
2610 pwdlastset5 = info->info5.last_password_change;
2613 pwdlastset21 = info->info21.last_password_change;
2619 /* torture_assert_int_equal(tctx, pwdlastset3, pwdlastset5,
2620 "pwdlastset mixup"); */
2621 torture_assert_int_equal(tctx, pwdlastset5, pwdlastset21,
2622 "pwdlastset mixup");
2624 *pwdlastset = pwdlastset21;
2626 torture_comment(tctx, "(pwdlastset: %lld)\n", *pwdlastset);
2631 static bool test_SamLogon_Creds(struct dcerpc_pipe *p, struct torture_context *tctx,
2632 struct cli_credentials *machine_credentials,
2633 struct cli_credentials *test_credentials,
2634 struct creds_CredentialState *creds,
2635 NTSTATUS expected_result)
2638 struct netr_LogonSamLogon r;
2639 struct netr_Authenticator auth, auth2;
2640 union netr_LogonLevel logon;
2641 union netr_Validation validation;
2642 uint8_t authoritative;
2643 struct netr_NetworkInfo ninfo;
2644 DATA_BLOB names_blob, chal, lm_resp, nt_resp;
2646 int flags = CLI_CRED_NTLM_AUTH;
2648 if (lp_client_lanman_auth(tctx->lp_ctx)) {
2649 flags |= CLI_CRED_LANMAN_AUTH;
2652 if (lp_client_ntlmv2_auth(tctx->lp_ctx)) {
2653 flags |= CLI_CRED_NTLMv2_AUTH;
2656 cli_credentials_get_ntlm_username_domain(test_credentials, tctx,
2657 &ninfo.identity_info.account_name.string,
2658 &ninfo.identity_info.domain_name.string);
2660 generate_random_buffer(ninfo.challenge,
2661 sizeof(ninfo.challenge));
2662 chal = data_blob_const(ninfo.challenge,
2663 sizeof(ninfo.challenge));
2665 names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(machine_credentials),
2666 cli_credentials_get_domain(machine_credentials));
2668 status = cli_credentials_get_ntlm_response(test_credentials, tctx,
2674 torture_assert_ntstatus_ok(tctx, status, "cli_credentials_get_ntlm_response failed");
2676 ninfo.lm.data = lm_resp.data;
2677 ninfo.lm.length = lm_resp.length;
2679 ninfo.nt.data = nt_resp.data;
2680 ninfo.nt.length = nt_resp.length;
2682 ninfo.identity_info.parameter_control =
2683 MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT |
2684 MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;
2685 ninfo.identity_info.logon_id_low = 0;
2686 ninfo.identity_info.logon_id_high = 0;
2687 ninfo.identity_info.workstation.string = cli_credentials_get_workstation(machine_credentials);
2689 logon.network = &ninfo;
2691 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2692 r.in.computer_name = cli_credentials_get_workstation(machine_credentials);
2693 r.in.credential = &auth;
2694 r.in.return_authenticator = &auth2;
2695 r.in.logon_level = 2;
2696 r.in.logon = &logon;
2697 r.out.validation = &validation;
2698 r.out.authoritative = &authoritative;
2700 d_printf("Testing LogonSamLogon with name %s\n", ninfo.identity_info.account_name.string);
2703 creds_client_authenticator(creds, &auth);
2705 r.in.validation_level = 2;
2707 status = dcerpc_netr_LogonSamLogon(p, tctx, &r);
2708 if (!NT_STATUS_IS_OK(status)) {
2709 torture_assert_ntstatus_equal(tctx, status, expected_result, "LogonSamLogon failed");
2712 torture_assert_ntstatus_ok(tctx, status, "LogonSamLogon failed");
2715 torture_assert(tctx, creds_client_check(creds, &r.out.return_authenticator->cred),
2716 "Credential chaining failed");
2721 static bool test_SamLogon(struct torture_context *tctx,
2722 struct dcerpc_pipe *p,
2723 struct cli_credentials *machine_credentials,
2724 struct cli_credentials *test_credentials,
2725 NTSTATUS expected_result)
2727 struct creds_CredentialState *creds;
2729 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
2733 return test_SamLogon_Creds(p, tctx, machine_credentials, test_credentials,
2734 creds, expected_result);
2737 static bool test_SamLogon_with_creds(struct torture_context *tctx,
2738 struct dcerpc_pipe *p,
2739 struct cli_credentials *machine_creds,
2740 const char *acct_name,
2742 NTSTATUS expected_samlogon_result)
2745 struct cli_credentials *test_credentials;
2747 test_credentials = cli_credentials_init(tctx);
2749 cli_credentials_set_workstation(test_credentials,
2750 TEST_ACCOUNT_NAME_PWD, CRED_SPECIFIED);
2751 cli_credentials_set_domain(test_credentials,
2752 lp_workgroup(tctx->lp_ctx), CRED_SPECIFIED);
2753 cli_credentials_set_username(test_credentials,
2754 acct_name, CRED_SPECIFIED);
2755 cli_credentials_set_password(test_credentials,
2756 password, CRED_SPECIFIED);
2757 cli_credentials_set_secure_channel_type(test_credentials, SEC_CHAN_BDC);
2759 printf("testing samlogon as %s@%s password: %s\n",
2760 acct_name, TEST_ACCOUNT_NAME_PWD, password);
2762 if (!test_SamLogon(tctx, p, machine_creds, test_credentials,
2763 expected_samlogon_result)) {
2764 torture_warning(tctx, "new password did not work\n");
2771 static bool test_SetPassword_level(struct dcerpc_pipe *p,
2772 struct dcerpc_pipe *np,
2773 struct torture_context *tctx,
2774 struct policy_handle *handle,
2776 uint32_t fields_present,
2777 uint8_t password_expired,
2778 bool *matched_expected_error,
2780 const char *acct_name,
2782 struct cli_credentials *machine_creds,
2783 bool use_queryinfo2,
2785 NTSTATUS expected_samlogon_result)
2787 const char *fields = NULL;
2789 struct cli_credentials *test_credentials;
2795 fields = talloc_asprintf(tctx, "(fields_present: 0x%08x)",
2802 torture_comment(tctx, "Testing SetUserInfo%s level %d call "
2803 "(password_expired: %d) %s\n",
2804 use_setinfo2 ? "2":"", level, password_expired,
2805 fields ? fields : "");
2807 if (!test_SetUserPass_level_ex(p, tctx, handle, level,
2812 matched_expected_error)) {
2816 if (!test_QueryUserInfo_pwdlastset(p, tctx, handle,
2822 if (*matched_expected_error == true) {
2826 if (!test_SamLogon_with_creds(tctx, np,
2830 expected_samlogon_result)) {
2837 static bool test_SetPassword_pwdlastset(struct dcerpc_pipe *p,
2838 struct torture_context *tctx,
2839 uint32_t acct_flags,
2840 const char *acct_name,
2841 struct policy_handle *handle,
2843 struct cli_credentials *machine_credentials)
2845 int s = 0, q = 0, f = 0, l = 0, z = 0;
2848 bool set_levels[] = { false, true };
2849 bool query_levels[] = { false, true };
2850 uint32_t levels[] = { 18, 21, 23, 24, 25, 26 };
2851 uint32_t nonzeros[] = { 1, 24 };
2852 uint32_t fields_present[] = {
2854 SAMR_FIELD_EXPIRED_FLAG,
2855 SAMR_FIELD_LAST_PWD_CHANGE,
2856 SAMR_FIELD_EXPIRED_FLAG | SAMR_FIELD_LAST_PWD_CHANGE,
2858 SAMR_FIELD_NT_PASSWORD_PRESENT,
2859 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
2860 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
2861 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
2862 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
2863 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
2864 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE | SAMR_FIELD_EXPIRED_FLAG
2867 struct dcerpc_pipe *np = NULL;
2869 if (torture_setting_bool(tctx, "samba3", false)) {
2871 printf("Samba3 has second granularity, setting delay to: %d\n",
2875 status = torture_rpc_connection(tctx, &np, &ndr_table_netlogon);
2876 if (!NT_STATUS_IS_OK(status)) {
2880 /* set to 1 to enable testing for all possible opcode
2881 (SetUserInfo, SetUserInfo2, QueryUserInfo, QueryUserInfo2)
2884 #define TEST_SET_LEVELS 1
2885 #define TEST_QUERY_LEVELS 1
2887 for (l=0; l<ARRAY_SIZE(levels); l++) {
2888 for (z=0; z<ARRAY_SIZE(nonzeros); z++) {
2889 for (f=0; f<ARRAY_SIZE(fields_present); f++) {
2890 #ifdef TEST_SET_LEVELS
2891 for (s=0; s<ARRAY_SIZE(set_levels); s++) {
2893 #ifdef TEST_QUERY_LEVELS
2894 for (q=0; q<ARRAY_SIZE(query_levels); q++) {
2896 NTTIME pwdlastset_old = 0;
2897 NTTIME pwdlastset_new = 0;
2898 bool matched_expected_error = false;
2899 NTSTATUS expected_samlogon_result = NT_STATUS_ACCOUNT_DISABLED;
2901 torture_comment(tctx, "------------------------------\n"
2902 "Testing pwdLastSet attribute for flags: 0x%08x "
2903 "(s: %d (l: %d), q: %d)\n",
2904 acct_flags, s, levels[l], q);
2906 switch (levels[l]) {
2910 if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
2911 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT))) {
2912 expected_samlogon_result = NT_STATUS_WRONG_PASSWORD;
2920 /* set a password and force password change (pwdlastset 0) by
2921 * setting the password expired flag to a non-0 value */
2923 if (!test_SetPassword_level(p, np, tctx, handle,
2927 &matched_expected_error,
2931 machine_credentials,
2934 expected_samlogon_result)) {
2938 if (matched_expected_error == true) {
2939 /* skipping on expected failure */
2943 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
2944 * set without the SAMR_FIELD_EXPIRED_FLAG */
2946 switch (levels[l]) {
2950 if ((pwdlastset_new != 0) &&
2951 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
2952 torture_comment(tctx, "not considering a non-0 "
2953 "pwdLastSet as a an error as the "
2954 "SAMR_FIELD_EXPIRED_FLAG has not "
2959 if (pwdlastset_new != 0) {
2960 torture_warning(tctx, "pwdLastSet test failed: "
2961 "expected pwdLastSet 0 but got %lld\n",
2968 switch (levels[l]) {
2972 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
2973 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
2974 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
2975 (pwdlastset_old >= pwdlastset_new)) {
2976 torture_warning(tctx, "pwdlastset not increasing\n");
2981 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
2982 (pwdlastset_old >= pwdlastset_new)) {
2983 torture_warning(tctx, "pwdlastset not increasing\n");
2993 /* set a password, pwdlastset needs to get updated (increased
2994 * value), password_expired value used here is 0 */
2996 if (!test_SetPassword_level(p, np, tctx, handle,
3000 &matched_expected_error,
3004 machine_credentials,
3007 expected_samlogon_result)) {
3011 /* when a password has been changed, pwdlastset must not be 0 afterwards
3012 * and must be larger then the old value */
3014 switch (levels[l]) {
3019 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3020 * password has been changed, old and new pwdlastset
3021 * need to be the same value */
3023 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3024 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3025 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3027 torture_assert_int_equal(tctx, pwdlastset_old,
3028 pwdlastset_new, "pwdlastset must be equal");
3032 if (pwdlastset_old >= pwdlastset_new) {
3033 torture_warning(tctx, "pwdLastSet test failed: "
3034 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
3035 pwdlastset_old, pwdlastset_new);
3038 if (pwdlastset_new == 0) {
3039 torture_warning(tctx, "pwdLastSet test failed: "
3040 "expected non-0 pwdlastset, got: %lld\n",
3046 switch (levels[l]) {
3050 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3051 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3052 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3053 (pwdlastset_old >= pwdlastset_new)) {
3054 torture_warning(tctx, "pwdlastset not increasing\n");
3059 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3060 (pwdlastset_old >= pwdlastset_new)) {
3061 torture_warning(tctx, "pwdlastset not increasing\n");
3067 pwdlastset_old = pwdlastset_new;
3073 /* set a password, pwdlastset needs to get updated (increased
3074 * value), password_expired value used here is 0 */
3076 if (!test_SetPassword_level(p, np, tctx, handle,
3080 &matched_expected_error,
3084 machine_credentials,
3087 expected_samlogon_result)) {
3091 /* when a password has been changed, pwdlastset must not be 0 afterwards
3092 * and must be larger then the old value */
3094 switch (levels[l]) {
3099 /* if no password has been changed, old and new pwdlastset
3100 * need to be the same value */
3102 if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3103 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3105 torture_assert_int_equal(tctx, pwdlastset_old,
3106 pwdlastset_new, "pwdlastset must be equal");
3110 if (pwdlastset_old >= pwdlastset_new) {
3111 torture_warning(tctx, "pwdLastSet test failed: "
3112 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
3113 pwdlastset_old, pwdlastset_new);
3116 if (pwdlastset_new == 0) {
3117 torture_warning(tctx, "pwdLastSet test failed: "
3118 "expected non-0 pwdlastset, got: %lld\n",
3126 /* set a password and force password change (pwdlastset 0) by
3127 * setting the password expired flag to a non-0 value */
3129 if (!test_SetPassword_level(p, np, tctx, handle,
3133 &matched_expected_error,
3137 machine_credentials,
3140 expected_samlogon_result)) {
3144 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3145 * set without the SAMR_FIELD_EXPIRED_FLAG */
3147 switch (levels[l]) {
3151 if ((pwdlastset_new != 0) &&
3152 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
3153 torture_comment(tctx, "not considering a non-0 "
3154 "pwdLastSet as a an error as the "
3155 "SAMR_FIELD_EXPIRED_FLAG has not "
3160 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3161 * password has been changed, old and new pwdlastset
3162 * need to be the same value */
3164 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3165 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3166 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3168 torture_assert_int_equal(tctx, pwdlastset_old,
3169 pwdlastset_new, "pwdlastset must be equal");
3174 if (pwdlastset_old == pwdlastset_new) {
3175 torture_warning(tctx, "pwdLastSet test failed: "
3176 "expected last pwdlastset (%lld) != new pwdlastset (%lld)\n",
3177 pwdlastset_old, pwdlastset_new);
3181 if (pwdlastset_new != 0) {
3182 torture_warning(tctx, "pwdLastSet test failed: "
3183 "expected pwdLastSet 0, got %lld\n",
3190 switch (levels[l]) {
3194 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3195 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3196 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3197 (pwdlastset_old >= pwdlastset_new)) {
3198 torture_warning(tctx, "pwdlastset not increasing\n");
3203 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3204 (pwdlastset_old >= pwdlastset_new)) {
3205 torture_warning(tctx, "pwdlastset not increasing\n");
3211 /* if the level we are testing does not have a fields_present
3212 * field, skip all fields present tests by setting f to to
3214 switch (levels[l]) {
3218 f = ARRAY_SIZE(fields_present);
3222 #ifdef TEST_QUERY_LEVELS
3225 #ifdef TEST_SET_LEVELS
3228 } /* fields present */
3232 #undef TEST_SET_LEVELS
3233 #undef TEST_QUERY_LEVELS
3238 static bool test_user_ops(struct dcerpc_pipe *p,
3239 struct torture_context *tctx,
3240 struct policy_handle *user_handle,
3241 struct policy_handle *domain_handle,
3242 uint32_t base_acct_flags,
3243 const char *base_acct_name, enum torture_samr_choice which_ops,
3244 struct cli_credentials *machine_credentials)
3246 char *password = NULL;
3247 struct samr_QueryUserInfo q;
3248 union samr_UserInfo *info;
3254 const uint32_t password_fields[] = {
3255 SAMR_FIELD_NT_PASSWORD_PRESENT,
3256 SAMR_FIELD_LM_PASSWORD_PRESENT,
3257 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
3261 status = test_LookupName(p, tctx, domain_handle, base_acct_name, &rid);
3262 if (!NT_STATUS_IS_OK(status)) {
3266 switch (which_ops) {
3267 case TORTURE_SAMR_USER_ATTRIBUTES:
3268 if (!test_QuerySecurity(p, tctx, user_handle)) {
3272 if (!test_QueryUserInfo(p, tctx, user_handle)) {
3276 if (!test_QueryUserInfo2(p, tctx, user_handle)) {
3280 if (!test_SetUserInfo(p, tctx, user_handle, base_acct_flags,
3285 if (!test_GetUserPwInfo(p, tctx, user_handle)) {
3289 if (!test_TestPrivateFunctionsUser(p, tctx, user_handle)) {
3293 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
3297 case TORTURE_SAMR_PASSWORDS:
3298 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
3299 char simple_pass[9];
3300 char *v = generate_random_str(tctx, 1);
3302 ZERO_STRUCT(simple_pass);
3303 memset(simple_pass, *v, sizeof(simple_pass) - 1);
3305 printf("Testing machine account password policy rules\n");
3307 /* Workstation trust accounts don't seem to need to honour password quality policy */
3308 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
3312 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
3316 /* reset again, to allow another 'user' password change */
3317 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
3321 /* Try a 'short' password */
3322 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
3326 /* Try a compleatly random password */
3327 if (!test_ChangePasswordRandomBytes(p, tctx, base_acct_name, user_handle, &password)) {
3332 for (i = 0; password_fields[i]; i++) {
3333 if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
3337 /* check it was set right */
3338 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3343 for (i = 0; password_fields[i]; i++) {
3344 if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
3348 /* check it was set right */
3349 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3354 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
3358 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
3362 if (torture_setting_bool(tctx, "samba4", false)) {
3363 printf("skipping Set Password level 18 and 21 against Samba4\n");
3366 if (!test_SetUserPass_18(p, tctx, user_handle, &password)) {
3370 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3374 for (i = 0; password_fields[i]; i++) {
3376 if (password_fields[i] == SAMR_FIELD_LM_PASSWORD_PRESENT) {
3377 /* we need to skip as that would break
3378 * the ChangePasswordUser3 verify */
3382 if (!test_SetUserPass_21(p, tctx, user_handle, password_fields[i], &password)) {
3386 /* check it was set right */
3387 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3393 q.in.user_handle = user_handle;
3397 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
3398 if (!NT_STATUS_IS_OK(status)) {
3399 printf("QueryUserInfo level %u failed - %s\n",
3400 q.in.level, nt_errstr(status));
3403 uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
3404 if ((info->info5.acct_flags) != expected_flags) {
3405 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
3406 info->info5.acct_flags,
3410 if (info->info5.rid != rid) {
3411 printf("QuerUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
3412 info->info5.rid, rid);
3419 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
3421 /* test last password change timestamp behaviour */
3422 if (!test_SetPassword_pwdlastset(p, tctx, base_acct_flags,
3424 user_handle, &password,
3425 machine_credentials)) {
3430 torture_comment(tctx, "pwdLastSet test succeeded\n");
3432 torture_warning(tctx, "pwdLastSet test failed\n");
3437 case TORTURE_SAMR_OTHER:
3438 /* We just need the account to exist */
3444 static bool test_alias_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
3445 struct policy_handle *alias_handle,
3446 const struct dom_sid *domain_sid)
3450 if (!test_QuerySecurity(p, tctx, alias_handle)) {
3454 if (!test_QueryAliasInfo(p, tctx, alias_handle)) {
3458 if (!test_SetAliasInfo(p, tctx, alias_handle)) {
3462 if (!test_AddMemberToAlias(p, tctx, alias_handle, domain_sid)) {
3466 if (torture_setting_bool(tctx, "samba4", false)) {
3467 printf("skipping MultipleMembers Alias tests against Samba4\n");
3471 if (!test_AddMultipleMembersToAlias(p, tctx, alias_handle)) {
3479 static bool test_DeleteUser(struct dcerpc_pipe *p, struct torture_context *tctx,
3480 struct policy_handle *user_handle)
3482 struct samr_DeleteUser d;
3484 torture_comment(tctx, "Testing DeleteUser\n");
3486 d.in.user_handle = user_handle;
3487 d.out.user_handle = user_handle;
3489 status = dcerpc_samr_DeleteUser(p, tctx, &d);
3490 torture_assert_ntstatus_ok(tctx, status, "DeleteUser");
3495 bool test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3496 struct policy_handle *handle, const char *name)
3499 struct samr_DeleteUser d;
3500 struct policy_handle user_handle;
3503 status = test_LookupName(p, mem_ctx, handle, name, &rid);
3504 if (!NT_STATUS_IS_OK(status)) {
3508 status = test_OpenUser_byname(p, mem_ctx, handle, name, &user_handle);
3509 if (!NT_STATUS_IS_OK(status)) {
3513 d.in.user_handle = &user_handle;
3514 d.out.user_handle = &user_handle;
3515 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
3516 if (!NT_STATUS_IS_OK(status)) {
3523 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
3528 static bool test_DeleteGroup_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3529 struct policy_handle *handle, const char *name)
3532 struct samr_OpenGroup r;
3533 struct samr_DeleteDomainGroup d;
3534 struct policy_handle group_handle;
3537 status = test_LookupName(p, mem_ctx, handle, name, &rid);
3538 if (!NT_STATUS_IS_OK(status)) {
3542 r.in.domain_handle = handle;
3543 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3545 r.out.group_handle = &group_handle;
3546 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
3547 if (!NT_STATUS_IS_OK(status)) {
3551 d.in.group_handle = &group_handle;
3552 d.out.group_handle = &group_handle;
3553 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
3554 if (!NT_STATUS_IS_OK(status)) {
3561 printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
3566 static bool test_DeleteAlias_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3567 struct policy_handle *domain_handle, const char *name)
3570 struct samr_OpenAlias r;
3571 struct samr_DeleteDomAlias d;
3572 struct policy_handle alias_handle;
3575 printf("testing DeleteAlias_byname\n");
3577 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
3578 if (!NT_STATUS_IS_OK(status)) {
3582 r.in.domain_handle = domain_handle;
3583 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3585 r.out.alias_handle = &alias_handle;
3586 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
3587 if (!NT_STATUS_IS_OK(status)) {
3591 d.in.alias_handle = &alias_handle;
3592 d.out.alias_handle = &alias_handle;
3593 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
3594 if (!NT_STATUS_IS_OK(status)) {
3601 printf("DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
3605 static bool test_DeleteAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3606 struct policy_handle *alias_handle)
3608 struct samr_DeleteDomAlias d;
3611 printf("Testing DeleteAlias\n");
3613 d.in.alias_handle = alias_handle;
3614 d.out.alias_handle = alias_handle;
3616 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
3617 if (!NT_STATUS_IS_OK(status)) {
3618 printf("DeleteAlias failed - %s\n", nt_errstr(status));
3625 static bool test_CreateAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
3626 struct policy_handle *domain_handle,
3627 struct policy_handle *alias_handle,
3628 const struct dom_sid *domain_sid)
3631 struct samr_CreateDomAlias r;
3632 struct lsa_String name;
3636 init_lsa_String(&name, TEST_ALIASNAME);
3637 r.in.domain_handle = domain_handle;
3638 r.in.alias_name = &name;
3639 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3640 r.out.alias_handle = alias_handle;
3643 printf("Testing CreateAlias (%s)\n", r.in.alias_name->string);
3645 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
3647 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
3648 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
3649 printf("Server correctly refused create of '%s'\n", r.in.alias_name->string);
3652 printf("Server should have refused create of '%s', got %s instead\n", r.in.alias_name->string,
3658 if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
3659 if (!test_DeleteAlias_byname(p, tctx, domain_handle, r.in.alias_name->string)) {
3662 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
3665 if (!NT_STATUS_IS_OK(status)) {
3666 printf("CreateAlias failed - %s\n", nt_errstr(status));
3670 if (!test_alias_ops(p, tctx, alias_handle, domain_sid)) {
3677 static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3678 const char *acct_name,
3679 struct policy_handle *domain_handle, char **password)
3687 if (!test_ChangePasswordUser(p, mem_ctx, acct_name, domain_handle, password)) {
3691 if (!test_ChangePasswordUser2(p, mem_ctx, acct_name, password, 0, true)) {
3695 if (!test_OemChangePasswordUser2(p, mem_ctx, acct_name, domain_handle, password)) {
3699 /* test what happens when setting the old password again */
3700 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, *password, 0, true)) {
3705 char simple_pass[9];
3706 char *v = generate_random_str(mem_ctx, 1);
3708 ZERO_STRUCT(simple_pass);
3709 memset(simple_pass, *v, sizeof(simple_pass) - 1);
3711 /* test what happens when picking a simple password */
3712 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, simple_pass, 0, true)) {
3717 /* set samr_SetDomainInfo level 1 with min_length 5 */
3719 struct samr_QueryDomainInfo r;
3720 union samr_DomainInfo *info = NULL;
3721 struct samr_SetDomainInfo s;
3722 uint16_t len_old, len;
3723 uint32_t pwd_prop_old;
3724 int64_t min_pwd_age_old;
3729 r.in.domain_handle = domain_handle;
3733 printf("testing samr_QueryDomainInfo level 1\n");
3734 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
3735 if (!NT_STATUS_IS_OK(status)) {
3739 s.in.domain_handle = domain_handle;
3743 /* remember the old min length, so we can reset it */
3744 len_old = s.in.info->info1.min_password_length;
3745 s.in.info->info1.min_password_length = len;
3746 pwd_prop_old = s.in.info->info1.password_properties;
3747 /* turn off password complexity checks for this test */
3748 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
3750 min_pwd_age_old = s.in.info->info1.min_password_age;
3751 s.in.info->info1.min_password_age = 0;
3753 printf("testing samr_SetDomainInfo level 1\n");
3754 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
3755 if (!NT_STATUS_IS_OK(status)) {
3759 printf("calling test_ChangePasswordUser3 with too short password\n");
3761 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, len - 1, password, NULL, 0, true)) {
3765 s.in.info->info1.min_password_length = len_old;
3766 s.in.info->info1.password_properties = pwd_prop_old;
3767 s.in.info->info1.min_password_age = min_pwd_age_old;
3769 printf("testing samr_SetDomainInfo level 1\n");
3770 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
3771 if (!NT_STATUS_IS_OK(status)) {
3779 struct samr_OpenUser r;
3780 struct samr_QueryUserInfo q;
3781 union samr_UserInfo *info;
3782 struct samr_LookupNames n;
3783 struct policy_handle user_handle;
3784 struct samr_Ids rids, types;
3786 n.in.domain_handle = domain_handle;
3788 n.in.names = talloc_array(mem_ctx, struct lsa_String, 1);
3789 n.in.names[0].string = acct_name;
3791 n.out.types = &types;
3793 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
3794 if (!NT_STATUS_IS_OK(status)) {
3795 printf("LookupNames failed - %s\n", nt_errstr(status));
3799 r.in.domain_handle = domain_handle;
3800 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3801 r.in.rid = n.out.rids->ids[0];
3802 r.out.user_handle = &user_handle;
3804 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3805 if (!NT_STATUS_IS_OK(status)) {
3806 printf("OpenUser(%u) failed - %s\n", n.out.rids->ids[0], nt_errstr(status));
3810 q.in.user_handle = &user_handle;
3814 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
3815 if (!NT_STATUS_IS_OK(status)) {
3816 printf("QueryUserInfo failed - %s\n", nt_errstr(status));
3820 printf("calling test_ChangePasswordUser3 with too early password change\n");
3822 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL,
3823 info->info5.last_password_change, true)) {
3828 /* we change passwords twice - this has the effect of verifying
3829 they were changed correctly for the final call */
3830 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, true)) {
3834 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, true)) {
3841 static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
3842 struct policy_handle *domain_handle,
3843 struct policy_handle *user_handle_out,
3844 struct dom_sid *domain_sid,
3845 enum torture_samr_choice which_ops,
3846 struct cli_credentials *machine_credentials)
3849 TALLOC_CTX *user_ctx;
3852 struct samr_CreateUser r;
3853 struct samr_QueryUserInfo q;
3854 union samr_UserInfo *info;
3855 struct samr_DeleteUser d;
3858 /* This call creates a 'normal' account - check that it really does */
3859 const uint32_t acct_flags = ACB_NORMAL;
3860 struct lsa_String name;
3863 struct policy_handle user_handle;
3864 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
3865 init_lsa_String(&name, TEST_ACCOUNT_NAME);
3867 r.in.domain_handle = domain_handle;
3868 r.in.account_name = &name;
3869 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3870 r.out.user_handle = &user_handle;
3873 printf("Testing CreateUser(%s)\n", r.in.account_name->string);
3875 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
3877 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
3878 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
3879 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
3882 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
3888 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
3889 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
3890 talloc_free(user_ctx);
3893 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
3895 if (!NT_STATUS_IS_OK(status)) {
3896 talloc_free(user_ctx);
3897 printf("CreateUser failed - %s\n", nt_errstr(status));
3900 q.in.user_handle = &user_handle;
3904 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
3905 if (!NT_STATUS_IS_OK(status)) {
3906 printf("QueryUserInfo level %u failed - %s\n",
3907 q.in.level, nt_errstr(status));
3910 if ((info->info16.acct_flags & acct_flags) != acct_flags) {
3911 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
3912 info->info16.acct_flags,
3918 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
3919 acct_flags, name.string, which_ops,
3920 machine_credentials)) {
3924 if (user_handle_out) {
3925 *user_handle_out = user_handle;
3927 printf("Testing DeleteUser (createuser test)\n");
3929 d.in.user_handle = &user_handle;
3930 d.out.user_handle = &user_handle;
3932 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
3933 if (!NT_STATUS_IS_OK(status)) {
3934 printf("DeleteUser failed - %s\n", nt_errstr(status));
3941 talloc_free(user_ctx);
3947 static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
3948 struct policy_handle *domain_handle,
3949 struct dom_sid *domain_sid,
3950 enum torture_samr_choice which_ops,
3951 struct cli_credentials *machine_credentials)
3954 struct samr_CreateUser2 r;
3955 struct samr_QueryUserInfo q;
3956 union samr_UserInfo *info;
3957 struct samr_DeleteUser d;
3958 struct policy_handle user_handle;
3960 struct lsa_String name;
3965 uint32_t acct_flags;
3966 const char *account_name;
3968 } account_types[] = {
3969 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
3970 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
3971 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
3972 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
3973 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
3974 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
3975 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
3976 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
3977 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
3978 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
3979 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
3980 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
3981 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
3982 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
3983 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
3986 for (i = 0; account_types[i].account_name; i++) {
3987 TALLOC_CTX *user_ctx;
3988 uint32_t acct_flags = account_types[i].acct_flags;
3989 uint32_t access_granted;
3990 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
3991 init_lsa_String(&name, account_types[i].account_name);
3993 r.in.domain_handle = domain_handle;
3994 r.in.account_name = &name;
3995 r.in.acct_flags = acct_flags;
3996 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3997 r.out.user_handle = &user_handle;
3998 r.out.access_granted = &access_granted;
4001 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
4003 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
4005 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
4006 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
4007 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
4010 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
4017 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
4018 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
4019 talloc_free(user_ctx);
4023 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
4026 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
4027 printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
4028 nt_errstr(status), nt_errstr(account_types[i].nt_status));
4032 if (NT_STATUS_IS_OK(status)) {
4033 q.in.user_handle = &user_handle;
4037 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
4038 if (!NT_STATUS_IS_OK(status)) {
4039 printf("QueryUserInfo level %u failed - %s\n",
4040 q.in.level, nt_errstr(status));
4043 uint32_t expected_flags = (acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
4044 if (acct_flags == ACB_NORMAL) {
4045 expected_flags |= ACB_PW_EXPIRED;
4047 if ((info->info5.acct_flags) != expected_flags) {
4048 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
4049 info->info5.acct_flags,
4053 switch (acct_flags) {
4055 if (info->info5.primary_gid != DOMAIN_RID_DCS) {
4056 printf("QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n",
4057 DOMAIN_RID_DCS, info->info5.primary_gid);
4062 if (info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
4063 printf("QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
4064 DOMAIN_RID_DOMAIN_MEMBERS, info->info5.primary_gid);
4069 if (info->info5.primary_gid != DOMAIN_RID_USERS) {
4070 printf("QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n",
4071 DOMAIN_RID_USERS, info->info5.primary_gid);
4078 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
4079 acct_flags, name.string, which_ops,
4080 machine_credentials)) {
4084 printf("Testing DeleteUser (createuser2 test)\n");
4086 d.in.user_handle = &user_handle;
4087 d.out.user_handle = &user_handle;
4089 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
4090 if (!NT_STATUS_IS_OK(status)) {
4091 printf("DeleteUser failed - %s\n", nt_errstr(status));
4095 talloc_free(user_ctx);
4101 static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4102 struct policy_handle *handle)
4105 struct samr_QueryAliasInfo r;
4106 union samr_AliasInfo *info;
4107 uint16_t levels[] = {1, 2, 3};
4111 for (i=0;i<ARRAY_SIZE(levels);i++) {
4112 printf("Testing QueryAliasInfo level %u\n", levels[i]);
4114 r.in.alias_handle = handle;
4115 r.in.level = levels[i];
4118 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
4119 if (!NT_STATUS_IS_OK(status)) {
4120 printf("QueryAliasInfo level %u failed - %s\n",
4121 levels[i], nt_errstr(status));
4129 static bool test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4130 struct policy_handle *handle)
4133 struct samr_QueryGroupInfo r;
4134 union samr_GroupInfo *info;
4135 uint16_t levels[] = {1, 2, 3, 4, 5};
4139 for (i=0;i<ARRAY_SIZE(levels);i++) {
4140 printf("Testing QueryGroupInfo level %u\n", levels[i]);
4142 r.in.group_handle = handle;
4143 r.in.level = levels[i];
4146 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
4147 if (!NT_STATUS_IS_OK(status)) {
4148 printf("QueryGroupInfo level %u failed - %s\n",
4149 levels[i], nt_errstr(status));
4157 static bool test_QueryGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4158 struct policy_handle *handle)
4161 struct samr_QueryGroupMember r;
4162 struct samr_RidTypeArray *rids = NULL;
4165 printf("Testing QueryGroupMember\n");
4167 r.in.group_handle = handle;
4170 status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &r);
4171 if (!NT_STATUS_IS_OK(status)) {
4172 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
4180 static bool test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4181 struct policy_handle *handle)
4184 struct samr_QueryGroupInfo r;
4185 union samr_GroupInfo *info;
4186 struct samr_SetGroupInfo s;
4187 uint16_t levels[] = {1, 2, 3, 4};
4188 uint16_t set_ok[] = {0, 1, 1, 1};
4192 for (i=0;i<ARRAY_SIZE(levels);i++) {
4193 printf("Testing QueryGroupInfo level %u\n", levels[i]);
4195 r.in.group_handle = handle;
4196 r.in.level = levels[i];
4199 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
4200 if (!NT_STATUS_IS_OK(status)) {
4201 printf("QueryGroupInfo level %u failed - %s\n",
4202 levels[i], nt_errstr(status));
4206 printf("Testing SetGroupInfo level %u\n", levels[i]);
4208 s.in.group_handle = handle;
4209 s.in.level = levels[i];
4210 s.in.info = *r.out.info;
4213 /* disabled this, as it changes the name only from the point of view of samr,
4214 but leaves the name from the point of view of w2k3 internals (and ldap). This means
4215 the name is still reserved, so creating the old name fails, but deleting by the old name
4217 if (s.in.level == 2) {
4218 init_lsa_String(&s.in.info->string, "NewName");
4222 if (s.in.level == 4) {
4223 init_lsa_String(&s.in.info->description, "test description");
4226 status = dcerpc_samr_SetGroupInfo(p, mem_ctx, &s);
4228 if (!NT_STATUS_IS_OK(status)) {
4229 printf("SetGroupInfo level %u failed - %s\n",
4230 r.in.level, nt_errstr(status));
4235 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
4236 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
4237 r.in.level, nt_errstr(status));
4247 static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4248 struct policy_handle *handle)
4251 struct samr_QueryUserInfo r;
4252 union samr_UserInfo *info;
4253 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
4254 11, 12, 13, 14, 16, 17, 20, 21};
4258 for (i=0;i<ARRAY_SIZE(levels);i++) {
4259 printf("Testing QueryUserInfo level %u\n", levels[i]);
4261 r.in.user_handle = handle;
4262 r.in.level = levels[i];
4265 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
4266 if (!NT_STATUS_IS_OK(status)) {
4267 printf("QueryUserInfo level %u failed - %s\n",
4268 levels[i], nt_errstr(status));
4276 static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4277 struct policy_handle *handle)
4280 struct samr_QueryUserInfo2 r;
4281 union samr_UserInfo *info;
4282 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
4283 11, 12, 13, 14, 16, 17, 20, 21};
4287 for (i=0;i<ARRAY_SIZE(levels);i++) {
4288 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
4290 r.in.user_handle = handle;
4291 r.in.level = levels[i];
4294 status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r);
4295 if (!NT_STATUS_IS_OK(status)) {
4296 printf("QueryUserInfo2 level %u failed - %s\n",
4297 levels[i], nt_errstr(status));
4305 static bool test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4306 struct policy_handle *handle, uint32_t rid)
4309 struct samr_OpenUser r;
4310 struct policy_handle user_handle;
4313 printf("Testing OpenUser(%u)\n", rid);
4315 r.in.domain_handle = handle;
4316 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4318 r.out.user_handle = &user_handle;
4320 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
4321 if (!NT_STATUS_IS_OK(status)) {
4322 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
4326 if (!test_QuerySecurity(p, mem_ctx, &user_handle)) {
4330 if (!test_QueryUserInfo(p, mem_ctx, &user_handle)) {
4334 if (!test_QueryUserInfo2(p, mem_ctx, &user_handle)) {
4338 if (!test_GetUserPwInfo(p, mem_ctx, &user_handle)) {
4342 if (!test_GetGroupsForUser(p,mem_ctx, &user_handle)) {
4346 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
4353 static bool test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4354 struct policy_handle *handle, uint32_t rid)
4357 struct samr_OpenGroup r;
4358 struct policy_handle group_handle;
4361 printf("Testing OpenGroup(%u)\n", rid);
4363 r.in.domain_handle = handle;
4364 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4366 r.out.group_handle = &group_handle;
4368 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
4369 if (!NT_STATUS_IS_OK(status)) {
4370 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
4374 if (!test_QuerySecurity(p, mem_ctx, &group_handle)) {
4378 if (!test_QueryGroupInfo(p, mem_ctx, &group_handle)) {
4382 if (!test_QueryGroupMember(p, mem_ctx, &group_handle)) {
4386 if (!test_samr_handle_Close(p, mem_ctx, &group_handle)) {
4393 static bool test_OpenAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
4394 struct policy_handle *handle, uint32_t rid)
4397 struct samr_OpenAlias r;
4398 struct policy_handle alias_handle;
4401 torture_comment(tctx, "Testing OpenAlias(%u)\n", rid);
4403 r.in.domain_handle = handle;
4404 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4406 r.out.alias_handle = &alias_handle;
4408 status = dcerpc_samr_OpenAlias(p, tctx, &r);
4409 if (!NT_STATUS_IS_OK(status)) {
4410 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
4414 if (!test_QuerySecurity(p, tctx, &alias_handle)) {
4418 if (!test_QueryAliasInfo(p, tctx, &alias_handle)) {
4422 if (!test_GetMembersInAlias(p, tctx, &alias_handle)) {
4426 if (!test_samr_handle_Close(p, tctx, &alias_handle)) {
4433 static bool check_mask(struct dcerpc_pipe *p, struct torture_context *tctx,
4434 struct policy_handle *handle, uint32_t rid,
4435 uint32_t acct_flag_mask)
4438 struct samr_OpenUser r;
4439 struct samr_QueryUserInfo q;
4440 union samr_UserInfo *info;
4441 struct policy_handle user_handle;
4444 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
4446 r.in.domain_handle = handle;
4447 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4449 r.out.user_handle = &user_handle;
4451 status = dcerpc_samr_OpenUser(p, tctx, &r);
4452 if (!NT_STATUS_IS_OK(status)) {
4453 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
4457 q.in.user_handle = &user_handle;
4461 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
4462 if (!NT_STATUS_IS_OK(status)) {
4463 printf("QueryUserInfo level 16 failed - %s\n",
4467 if ((acct_flag_mask & info->info16.acct_flags) == 0) {
4468 printf("Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
4469 acct_flag_mask, info->info16.acct_flags, rid);
4474 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
4481 static bool test_EnumDomainUsers(struct dcerpc_pipe *p, struct torture_context *tctx,
4482 struct policy_handle *handle)
4484 NTSTATUS status = STATUS_MORE_ENTRIES;
4485 struct samr_EnumDomainUsers r;
4486 uint32_t mask, resume_handle=0;
4489 struct samr_LookupNames n;
4490 struct samr_LookupRids lr ;
4491 struct lsa_Strings names;
4492 struct samr_Ids rids, types;
4493 struct samr_SamArray *sam = NULL;
4494 uint32_t num_entries = 0;
4496 uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
4497 ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
4498 ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
4501 printf("Testing EnumDomainUsers\n");
4503 for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
4504 r.in.domain_handle = handle;
4505 r.in.resume_handle = &resume_handle;
4506 r.in.acct_flags = mask = masks[mask_idx];
4507 r.in.max_size = (uint32_t)-1;
4508 r.out.resume_handle = &resume_handle;
4509 r.out.num_entries = &num_entries;
4512 status = dcerpc_samr_EnumDomainUsers(p, tctx, &r);
4513 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
4514 !NT_STATUS_IS_OK(status)) {
4515 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
4519 torture_assert(tctx, sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
4521 if (sam->count == 0) {
4525 for (i=0;i<sam->count;i++) {
4527 if (!check_mask(p, tctx, handle, sam->entries[i].idx, mask)) {
4530 } else if (!test_OpenUser(p, tctx, handle, sam->entries[i].idx)) {
4536 printf("Testing LookupNames\n");
4537 n.in.domain_handle = handle;
4538 n.in.num_names = sam->count;
4539 n.in.names = talloc_array(tctx, struct lsa_String, sam->count);
4541 n.out.types = &types;
4542 for (i=0;i<sam->count;i++) {
4543 n.in.names[i].string = sam->entries[i].name.string;
4545 status = dcerpc_samr_LookupNames(p, tctx, &n);
4546 if (!NT_STATUS_IS_OK(status)) {
4547 printf("LookupNames failed - %s\n", nt_errstr(status));
4552 printf("Testing LookupRids\n");
4553 lr.in.domain_handle = handle;
4554 lr.in.num_rids = sam->count;
4555 lr.in.rids = talloc_array(tctx, uint32_t, sam->count);
4556 lr.out.names = &names;
4557 lr.out.types = &types;
4558 for (i=0;i<sam->count;i++) {
4559 lr.in.rids[i] = sam->entries[i].idx;
4561 status = dcerpc_samr_LookupRids(p, tctx, &lr);
4562 torture_assert_ntstatus_ok(tctx, status, "LookupRids");
4568 try blasting the server with a bunch of sync requests
4570 static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, struct torture_context *tctx,
4571 struct policy_handle *handle)
4574 struct samr_EnumDomainUsers r;
4575 uint32_t resume_handle=0;
4577 #define ASYNC_COUNT 100
4578 struct rpc_request *req[ASYNC_COUNT];
4580 if (!torture_setting_bool(tctx, "dangerous", false)) {
4581 torture_skip(tctx, "samr async test disabled - enable dangerous tests to use\n");
4584 torture_comment(tctx, "Testing EnumDomainUsers_async\n");
4586 r.in.domain_handle = handle;
4587 r.in.resume_handle = &resume_handle;
4588 r.in.acct_flags = 0;
4589 r.in.max_size = (uint32_t)-1;
4590 r.out.resume_handle = &resume_handle;
4592 for (i=0;i<ASYNC_COUNT;i++) {
4593 req[i] = dcerpc_samr_EnumDomainUsers_send(p, tctx, &r);
4596 for (i=0;i<ASYNC_COUNT;i++) {
4597 status = dcerpc_ndr_request_recv(req[i]);
4598 if (!NT_STATUS_IS_OK(status)) {
4599 printf("EnumDomainUsers[%d] failed - %s\n",
4600 i, nt_errstr(status));
4605 torture_comment(tctx, "%d async requests OK\n", i);
4610 static bool test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4611 struct policy_handle *handle)
4614 struct samr_EnumDomainGroups r;
4615 uint32_t resume_handle=0;
4616 struct samr_SamArray *sam = NULL;
4617 uint32_t num_entries = 0;
4621 printf("Testing EnumDomainGroups\n");
4623 r.in.domain_handle = handle;
4624 r.in.resume_handle = &resume_handle;
4625 r.in.max_size = (uint32_t)-1;
4626 r.out.resume_handle = &resume_handle;
4627 r.out.num_entries = &num_entries;
4630 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
4631 if (!NT_STATUS_IS_OK(status)) {
4632 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
4640 for (i=0;i<sam->count;i++) {
4641 if (!test_OpenGroup(p, mem_ctx, handle, sam->entries[i].idx)) {
4649 static bool test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4650 struct policy_handle *handle)
4653 struct samr_EnumDomainAliases r;
4654 uint32_t resume_handle=0;
4655 struct samr_SamArray *sam = NULL;
4656 uint32_t num_entries = 0;
4660 printf("Testing EnumDomainAliases\n");
4662 r.in.domain_handle = handle;
4663 r.in.resume_handle = &resume_handle;
4664 r.in.max_size = (uint32_t)-1;
4666 r.out.num_entries = &num_entries;
4667 r.out.resume_handle = &resume_handle;
4669 status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
4670 if (!NT_STATUS_IS_OK(status)) {
4671 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
4679 for (i=0;i<sam->count;i++) {
4680 if (!test_OpenAlias(p, mem_ctx, handle, sam->entries[i].idx)) {
4688 static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4689 struct policy_handle *handle)
4692 struct samr_GetDisplayEnumerationIndex r;
4694 uint16_t levels[] = {1, 2, 3, 4, 5};
4695 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
4696 struct lsa_String name;
4700 for (i=0;i<ARRAY_SIZE(levels);i++) {
4701 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
4703 init_lsa_String(&name, TEST_ACCOUNT_NAME);
4705 r.in.domain_handle = handle;
4706 r.in.level = levels[i];
4710 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
4713 !NT_STATUS_IS_OK(status) &&
4714 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
4715 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
4716 levels[i], nt_errstr(status));
4720 init_lsa_String(&name, "zzzzzzzz");
4722 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
4724 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
4725 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
4726 levels[i], nt_errstr(status));
4734 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4735 struct policy_handle *handle)
4738 struct samr_GetDisplayEnumerationIndex2 r;
4740 uint16_t levels[] = {1, 2, 3, 4, 5};
4741 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
4742 struct lsa_String name;
4746 for (i=0;i<ARRAY_SIZE(levels);i++) {
4747 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
4749 init_lsa_String(&name, TEST_ACCOUNT_NAME);
4751 r.in.domain_handle = handle;
4752 r.in.level = levels[i];
4756 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
4758 !NT_STATUS_IS_OK(status) &&
4759 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
4760 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
4761 levels[i], nt_errstr(status));
4765 init_lsa_String(&name, "zzzzzzzz");
4767 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
4768 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
4769 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
4770 levels[i], nt_errstr(status));
4778 #define STRING_EQUAL_QUERY(s1, s2, user) \
4779 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
4780 /* odd, but valid */ \
4781 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
4782 printf("%s mismatch for %s: %s != %s (%s)\n", \
4783 #s1, user.string, s1.string, s2.string, __location__); \
4786 #define INT_EQUAL_QUERY(s1, s2, user) \
4788 printf("%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
4789 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
4793 static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4794 struct samr_QueryDisplayInfo *querydisplayinfo,
4795 bool *seen_testuser)
4797 struct samr_OpenUser r;
4798 struct samr_QueryUserInfo q;
4799 union samr_UserInfo *info;
4800 struct policy_handle user_handle;
4803 r.in.domain_handle = querydisplayinfo->in.domain_handle;
4804 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4805 for (i = 0; ; i++) {
4806 switch (querydisplayinfo->in.level) {
4808 if (i >= querydisplayinfo->out.info->info1.count) {
4811 r.in.rid = querydisplayinfo->out.info->info1.entries[i].rid;
4814 if (i >= querydisplayinfo->out.info->info2.count) {
4817 r.in.rid = querydisplayinfo->out.info->info2.entries[i].rid;
4823 /* Not interested in validating just the account name */
4827 r.out.user_handle = &user_handle;
4829 switch (querydisplayinfo->in.level) {
4832 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
4833 if (!NT_STATUS_IS_OK(status)) {
4834 printf("OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(status));
4839 q.in.user_handle = &user_handle;
4842 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
4843 if (!NT_STATUS_IS_OK(status)) {
4844 printf("QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(status));
4848 switch (querydisplayinfo->in.level) {
4850 if (seen_testuser && strcmp(info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
4851 *seen_testuser = true;
4853 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].full_name,
4854 info->info21.full_name, info->info21.account_name);
4855 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].account_name,
4856 info->info21.account_name, info->info21.account_name);
4857 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].description,
4858 info->info21.description, info->info21.account_name);
4859 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].rid,
4860 info->info21.rid, info->info21.account_name);
4861 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].acct_flags,
4862 info->info21.acct_flags, info->info21.account_name);
4866 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].account_name,
4867 info->info21.account_name, info->info21.account_name);
4868 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].description,
4869 info->info21.description, info->info21.account_name);
4870 INT_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].rid,
4871 info->info21.rid, info->info21.account_name);
4872 INT_EQUAL_QUERY((querydisplayinfo->out.info->info2.entries[i].acct_flags & ~ACB_NORMAL),
4873 info->info21.acct_flags, info->info21.account_name);
4875 if (!(querydisplayinfo->out.info->info2.entries[i].acct_flags & ACB_NORMAL)) {
4876 printf("Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
4877 info->info21.account_name.string);
4880 if (!(info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
4881 printf("Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
4882 info->info21.account_name.string,
4883 querydisplayinfo->out.info->info2.entries[i].acct_flags,
4884 info->info21.acct_flags);
4891 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
4898 static bool test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4899 struct policy_handle *handle)
4902 struct samr_QueryDisplayInfo r;
4903 struct samr_QueryDomainInfo dom_info;
4904 union samr_DomainInfo *info = NULL;
4906 uint16_t levels[] = {1, 2, 3, 4, 5};
4908 bool seen_testuser = false;
4909 uint32_t total_size;
4910 uint32_t returned_size;
4911 union samr_DispInfo disp_info;
4914 for (i=0;i<ARRAY_SIZE(levels);i++) {
4915 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
4918 status = STATUS_MORE_ENTRIES;
4919 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
4920 r.in.domain_handle = handle;
4921 r.in.level = levels[i];
4922 r.in.max_entries = 2;
4923 r.in.buf_size = (uint32_t)-1;
4924 r.out.total_size = &total_size;
4925 r.out.returned_size = &returned_size;
4926 r.out.info = &disp_info;
4928 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
4929 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(status)) {
4930 printf("QueryDisplayInfo level %u failed - %s\n",
4931 levels[i], nt_errstr(status));
4934 switch (r.in.level) {
4936 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, &seen_testuser)) {
4939 r.in.start_idx += r.out.info->info1.count;
4942 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, NULL)) {
4945 r.in.start_idx += r.out.info->info2.count;
4948 r.in.start_idx += r.out.info->info3.count;
4951 r.in.start_idx += r.out.info->info4.count;
4954 r.in.start_idx += r.out.info->info5.count;
4958 dom_info.in.domain_handle = handle;
4959 dom_info.in.level = 2;
4960 dom_info.out.info = &info;
4962 /* Check number of users returned is correct */
4963 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &dom_info);
4964 if (!NT_STATUS_IS_OK(status)) {
4965 printf("QueryDomainInfo level %u failed - %s\n",
4966 r.in.level, nt_errstr(status));
4970 switch (r.in.level) {
4973 if (info->general.num_users < r.in.start_idx) {
4974 printf("QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
4975 r.in.start_idx, info->general.num_groups,
4976 info->general.domain_name.string);
4979 if (!seen_testuser) {
4980 struct policy_handle user_handle;
4981 if (NT_STATUS_IS_OK(test_OpenUser_byname(p, mem_ctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
4982 printf("Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
4983 info->general.domain_name.string);
4985 test_samr_handle_Close(p, mem_ctx, &user_handle);
4991 if (info->general.num_groups != r.in.start_idx) {
4992 printf("QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
4993 r.in.start_idx, info->general.num_groups,
4994 info->general.domain_name.string);
5006 static bool test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
5007 struct policy_handle *handle)
5010 struct samr_QueryDisplayInfo2 r;
5012 uint16_t levels[] = {1, 2, 3, 4, 5};
5014 uint32_t total_size;
5015 uint32_t returned_size;
5016 union samr_DispInfo info;
5018 for (i=0;i<ARRAY_SIZE(levels);i++) {
5019 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
5021 r.in.domain_handle = handle;
5022 r.in.level = levels[i];
5024 r.in.max_entries = 1000;
5025 r.in.buf_size = (uint32_t)-1;
5026 r.out.total_size = &total_size;
5027 r.out.returned_size = &returned_size;
5030 status = dcerpc_samr_QueryDisplayInfo2(p, mem_ctx, &r);
5031 if (!NT_STATUS_IS_OK(status)) {
5032 printf("QueryDisplayInfo2 level %u failed - %s\n",
5033 levels[i], nt_errstr(status));
5041 static bool test_QueryDisplayInfo3(struct dcerpc_pipe *p, struct torture_context *tctx,
5042 struct policy_handle *handle)
5045 struct samr_QueryDisplayInfo3 r;
5047 uint16_t levels[] = {1, 2, 3, 4, 5};
5049 uint32_t total_size;
5050 uint32_t returned_size;
5051 union samr_DispInfo info;
5053 for (i=0;i<ARRAY_SIZE(levels);i++) {
5054 torture_comment(tctx, "Testing QueryDisplayInfo3 level %u\n", levels[i]);
5056 r.in.domain_handle = handle;
5057 r.in.level = levels[i];
5059 r.in.max_entries = 1000;
5060 r.in.buf_size = (uint32_t)-1;
5061 r.out.total_size = &total_size;
5062 r.out.returned_size = &returned_size;
5065 status = dcerpc_samr_QueryDisplayInfo3(p, tctx, &r);
5066 if (!NT_STATUS_IS_OK(status)) {
5067 printf("QueryDisplayInfo3 level %u failed - %s\n",
5068 levels[i], nt_errstr(status));
5077 static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
5078 struct policy_handle *handle)
5081 struct samr_QueryDisplayInfo r;
5083 uint32_t total_size;
5084 uint32_t returned_size;
5085 union samr_DispInfo info;
5087 printf("Testing QueryDisplayInfo continuation\n");
5089 r.in.domain_handle = handle;
5092 r.in.max_entries = 1;
5093 r.in.buf_size = (uint32_t)-1;
5094 r.out.total_size = &total_size;
5095 r.out.returned_size = &returned_size;
5099 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
5100 if (NT_STATUS_IS_OK(status) && *r.out.returned_size != 0) {
5101 if (r.out.info->info1.entries[0].idx != r.in.start_idx + 1) {
5102 printf("expected idx %d but got %d\n",
5104 r.out.info->info1.entries[0].idx);
5108 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
5109 !NT_STATUS_IS_OK(status)) {
5110 printf("QueryDisplayInfo level %u failed - %s\n",
5111 r.in.level, nt_errstr(status));
5116 } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
5117 NT_STATUS_IS_OK(status)) &&
5118 *r.out.returned_size != 0);
5123 static bool test_QueryDomainInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
5124 struct policy_handle *handle)
5127 struct samr_QueryDomainInfo r;
5128 union samr_DomainInfo *info = NULL;
5129 struct samr_SetDomainInfo s;
5130 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
5131 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
5134 const char *domain_comment = talloc_asprintf(tctx,
5135 "Tortured by Samba4 RPC-SAMR: %s",
5136 timestring(tctx, time(NULL)));
5138 s.in.domain_handle = handle;
5140 s.in.info = talloc(tctx, union samr_DomainInfo);
5142 s.in.info->oem.oem_information.string = domain_comment;
5143 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
5144 if (!NT_STATUS_IS_OK(status)) {
5145 printf("SetDomainInfo level %u (set comment) failed - %s\n",
5146 r.in.level, nt_errstr(status));
5150 for (i=0;i<ARRAY_SIZE(levels);i++) {
5151 torture_comment(tctx, "Testing QueryDomainInfo level %u\n", levels[i]);
5153 r.in.domain_handle = handle;
5154 r.in.level = levels[i];
5157 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
5158 if (!NT_STATUS_IS_OK(status)) {
5159 printf("QueryDomainInfo level %u failed - %s\n",
5160 r.in.level, nt_errstr(status));
5165 switch (levels[i]) {
5167 if (strcmp(info->general.oem_information.string, domain_comment) != 0) {
5168 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
5169 levels[i], info->general.oem_information.string, domain_comment);
5172 if (!info->general.primary.string) {
5173 printf("QueryDomainInfo level %u returned no PDC name\n",
5176 } else if (info->general.role == SAMR_ROLE_DOMAIN_PDC) {
5177 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), info->general.primary.string) != 0) {
5178 printf("QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
5179 levels[i], info->general.primary.string, dcerpc_server_name(p));
5184 if (strcmp(info->oem.oem_information.string, domain_comment) != 0) {
5185 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
5186 levels[i], info->oem.oem_information.string, domain_comment);
5191 if (!info->info6.primary.string) {
5192 printf("QueryDomainInfo level %u returned no PDC name\n",
5198 if (strcmp(info->general2.general.oem_information.string, domain_comment) != 0) {
5199 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
5200 levels[i], info->general2.general.oem_information.string, domain_comment);
5206 torture_comment(tctx, "Testing SetDomainInfo level %u\n", levels[i]);
5208 s.in.domain_handle = handle;
5209 s.in.level = levels[i];
5212 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
5214 if (!NT_STATUS_IS_OK(status)) {
5215 printf("SetDomainInfo level %u failed - %s\n",
5216 r.in.level, nt_errstr(status));
5221 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
5222 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
5223 r.in.level, nt_errstr(status));
5229 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
5230 if (!NT_STATUS_IS_OK(status)) {
5231 printf("QueryDomainInfo level %u failed - %s\n",
5232 r.in.level, nt_errstr(status));
5242 static bool test_QueryDomainInfo2(struct dcerpc_pipe *p, struct torture_context *tctx,
5243 struct policy_handle *handle)
5246 struct samr_QueryDomainInfo2 r;
5247 union samr_DomainInfo *info = NULL;
5248 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
5252 for (i=0;i<ARRAY_SIZE(levels);i++) {
5253 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
5255 r.in.domain_handle = handle;
5256 r.in.level = levels[i];
5259 status = dcerpc_samr_QueryDomainInfo2(p, tctx, &r);
5260 if (!NT_STATUS_IS_OK(status)) {
5261 printf("QueryDomainInfo2 level %u failed - %s\n",
5262 r.in.level, nt_errstr(status));
5271 /* Test whether querydispinfo level 5 and enumdomgroups return the same
5272 set of group names. */
5273 static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx,
5274 struct policy_handle *handle)
5276 struct samr_EnumDomainGroups q1;
5277 struct samr_QueryDisplayInfo q2;
5279 uint32_t resume_handle=0;
5280 struct samr_SamArray *sam = NULL;
5281 uint32_t num_entries = 0;
5284 uint32_t total_size;
5285 uint32_t returned_size;
5286 union samr_DispInfo info;
5289 const char **names = NULL;
5291 torture_comment(tctx, "Testing coherency of querydispinfo vs enumdomgroups\n");
5293 q1.in.domain_handle = handle;
5294 q1.in.resume_handle = &resume_handle;
5296 q1.out.resume_handle = &resume_handle;
5297 q1.out.num_entries = &num_entries;
5300 status = STATUS_MORE_ENTRIES;
5301 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
5302 status = dcerpc_samr_EnumDomainGroups(p, tctx, &q1);
5304 if (!NT_STATUS_IS_OK(status) &&
5305 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
5308 for (i=0; i<*q1.out.num_entries; i++) {
5309 add_string_to_array(tctx,
5310 sam->entries[i].name.string,
5311 &names, &num_names);
5315 torture_assert_ntstatus_ok(tctx, status, "EnumDomainGroups");
5317 torture_assert(tctx, sam, "EnumDomainGroups failed to return sam");
5319 q2.in.domain_handle = handle;
5321 q2.in.start_idx = 0;
5322 q2.in.max_entries = 5;
5323 q2.in.buf_size = (uint32_t)-1;
5324 q2.out.total_size = &total_size;
5325 q2.out.returned_size = &returned_size;
5326 q2.out.info = &info;
5328 status = STATUS_MORE_ENTRIES;
5329 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
5330 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &q2);
5332 if (!NT_STATUS_IS_OK(status) &&
5333 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
5336 for (i=0; i<q2.out.info->info5.count; i++) {
5338 const char *name = q2.out.info->info5.entries[i].account_name.string;
5340 for (j=0; j<num_names; j++) {
5341 if (names[j] == NULL)
5343 if (strequal(names[j], name)) {
5351 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
5356 q2.in.start_idx += q2.out.info->info5.count;
5359 if (!NT_STATUS_IS_OK(status)) {
5360 printf("QueryDisplayInfo level 5 failed - %s\n",
5365 for (i=0; i<num_names; i++) {
5366 if (names[i] != NULL) {
5367 printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
5376 static bool test_DeleteDomainGroup(struct dcerpc_pipe *p, struct torture_context *tctx,
5377 struct policy_handle *group_handle)
5379 struct samr_DeleteDomainGroup d;
5382 torture_comment(tctx, "Testing DeleteDomainGroup\n");
5384 d.in.group_handle = group_handle;
5385 d.out.group_handle = group_handle;
5387 status = dcerpc_samr_DeleteDomainGroup(p, tctx, &d);
5388 torture_assert_ntstatus_ok(tctx, status, "DeleteDomainGroup");
5393 static bool test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
5394 struct policy_handle *domain_handle)
5396 struct samr_TestPrivateFunctionsDomain r;
5400 torture_comment(tctx, "Testing TestPrivateFunctionsDomain\n");
5402 r.in.domain_handle = domain_handle;
5404 status = dcerpc_samr_TestPrivateFunctionsDomain(p, tctx, &r);
5405 torture_assert_ntstatus_equal(tctx, NT_STATUS_NOT_IMPLEMENTED, status, "TestPrivateFunctionsDomain");
5410 static bool test_RidToSid(struct dcerpc_pipe *p, struct torture_context *tctx,
5411 struct dom_sid *domain_sid,
5412 struct policy_handle *domain_handle)
5414 struct samr_RidToSid r;
5417 struct dom_sid *calc_sid, *out_sid;
5418 int rids[] = { 0, 42, 512, 10200 };
5421 for (i=0;i<ARRAY_SIZE(rids);i++) {
5422 torture_comment(tctx, "Testing RidToSid\n");
5424 calc_sid = dom_sid_dup(tctx, domain_sid);
5425 r.in.domain_handle = domain_handle;
5427 r.out.sid = &out_sid;
5429 status = dcerpc_samr_RidToSid(p, tctx, &r);
5430 if (!NT_STATUS_IS_OK(status)) {
5431 printf("RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
5434 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
5436 if (!dom_sid_equal(calc_sid, out_sid)) {
5437 printf("RidToSid for %d failed - got %s, expected %s\n", rids[i],
5438 dom_sid_string(tctx, out_sid),
5439 dom_sid_string(tctx, calc_sid));
5448 static bool test_GetBootKeyInformation(struct dcerpc_pipe *p, struct torture_context *tctx,
5449 struct policy_handle *domain_handle)
5451 struct samr_GetBootKeyInformation r;
5454 uint32_t unknown = 0;
5456 torture_comment(tctx, "Testing GetBootKeyInformation\n");
5458 r.in.domain_handle = domain_handle;
5459 r.out.unknown = &unknown;
5461 status = dcerpc_samr_GetBootKeyInformation(p, tctx, &r);
5462 if (!NT_STATUS_IS_OK(status)) {
5463 /* w2k3 seems to fail this sometimes and pass it sometimes */
5464 torture_comment(tctx, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
5470 static bool test_AddGroupMember(struct dcerpc_pipe *p, struct torture_context *tctx,
5471 struct policy_handle *domain_handle,
5472 struct policy_handle *group_handle)
5475 struct samr_AddGroupMember r;
5476 struct samr_DeleteGroupMember d;
5477 struct samr_QueryGroupMember q;
5478 struct samr_RidTypeArray *rids = NULL;
5479 struct samr_SetMemberAttributesOfGroup s;
5482 status = test_LookupName(p, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
5483 torture_assert_ntstatus_ok(tctx, status, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME);
5485 r.in.group_handle = group_handle;
5487 r.in.flags = 0; /* ??? */
5489 torture_comment(tctx, "Testing AddGroupMember and DeleteGroupMember\n");
5491 d.in.group_handle = group_handle;
5494 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
5495 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_NOT_IN_GROUP, status, "DeleteGroupMember");
5497 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5498 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
5500 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5501 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_IN_GROUP, status, "AddGroupMember");
5503 if (torture_setting_bool(tctx, "samba4", false)) {
5504 torture_comment(tctx, "skipping SetMemberAttributesOfGroup test against Samba4\n");
5506 /* this one is quite strange. I am using random inputs in the
5507 hope of triggering an error that might give us a clue */
5509 s.in.group_handle = group_handle;
5510 s.in.unknown1 = random();
5511 s.in.unknown2 = random();
5513 status = dcerpc_samr_SetMemberAttributesOfGroup(p, tctx, &s);
5514 torture_assert_ntstatus_ok(tctx, status, "SetMemberAttributesOfGroup");
5517 q.in.group_handle = group_handle;
5520 status = dcerpc_samr_QueryGroupMember(p, tctx, &q);
5521 torture_assert_ntstatus_ok(tctx, status, "QueryGroupMember");
5523 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
5524 torture_assert_ntstatus_ok(tctx, status, "DeleteGroupMember");
5526 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5527 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
5533 static bool test_CreateDomainGroup(struct dcerpc_pipe *p,
5534 struct torture_context *tctx,
5535 struct policy_handle *domain_handle,
5536 struct policy_handle *group_handle,
5537 struct dom_sid *domain_sid)
5540 struct samr_CreateDomainGroup r;
5542 struct lsa_String name;
5545 init_lsa_String(&name, TEST_GROUPNAME);
5547 r.in.domain_handle = domain_handle;
5549 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5550 r.out.group_handle = group_handle;
5553 printf("Testing CreateDomainGroup(%s)\n", r.in.name->string);
5555 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
5557 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5558 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5559 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.name->string);
5562 printf("Server should have refused create of '%s', got %s instead\n", r.in.name->string,
5568 if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS)) {
5569 if (!test_DeleteGroup_byname(p, tctx, domain_handle, r.in.name->string)) {
5570 printf("CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
5574 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
5576 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
5577 if (!test_DeleteUser_byname(p, tctx, domain_handle, r.in.name->string)) {
5579 printf("CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
5583 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
5585 torture_assert_ntstatus_ok(tctx, status, "CreateDomainGroup");
5587 if (!test_AddGroupMember(p, tctx, domain_handle, group_handle)) {
5588 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
5592 if (!test_SetGroupInfo(p, tctx, group_handle)) {
5601 its not totally clear what this does. It seems to accept any sid you like.
5603 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p,
5604 struct torture_context *tctx,
5605 struct policy_handle *domain_handle)
5608 struct samr_RemoveMemberFromForeignDomain r;
5610 r.in.domain_handle = domain_handle;
5611 r.in.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-12-34-56-78");
5613 status = dcerpc_samr_RemoveMemberFromForeignDomain(p, tctx, &r);
5614 torture_assert_ntstatus_ok(tctx, status, "RemoveMemberFromForeignDomain");
5621 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
5622 struct policy_handle *handle);
5624 static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
5625 struct policy_handle *handle, struct dom_sid *sid,
5626 enum torture_samr_choice which_ops,
5627 struct cli_credentials *machine_credentials)
5630 struct samr_OpenDomain r;
5631 struct policy_handle domain_handle;
5632 struct policy_handle alias_handle;
5633 struct policy_handle user_handle;
5634 struct policy_handle group_handle;
5637 ZERO_STRUCT(alias_handle);
5638 ZERO_STRUCT(user_handle);
5639 ZERO_STRUCT(group_handle);
5640 ZERO_STRUCT(domain_handle);
5642 torture_comment(tctx, "Testing OpenDomain of %s\n", dom_sid_string(tctx, sid));
5644 r.in.connect_handle = handle;
5645 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5647 r.out.domain_handle = &domain_handle;
5649 status = dcerpc_samr_OpenDomain(p, tctx, &r);
5650 torture_assert_ntstatus_ok(tctx, status, "OpenDomain");
5652 /* run the domain tests with the main handle closed - this tests
5653 the servers reference counting */
5654 ret &= test_samr_handle_Close(p, tctx, handle);
5656 switch (which_ops) {
5657 case TORTURE_SAMR_USER_ATTRIBUTES:
5658 case TORTURE_SAMR_PASSWORDS:
5659 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops, NULL);
5660 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops, NULL);
5661 /* This test needs 'complex' users to validate */
5662 ret &= test_QueryDisplayInfo(p, tctx, &domain_handle);
5664 printf("Testing PASSWORDS or ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
5667 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
5668 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops, machine_credentials);
5669 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops, machine_credentials);
5671 printf("Testing PASSWORDS PWDLASTSET on domain %s failed!\n", dom_sid_string(tctx, sid));
5674 case TORTURE_SAMR_OTHER:
5675 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops, NULL);
5677 printf("Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid));
5679 ret &= test_QuerySecurity(p, tctx, &domain_handle);
5680 ret &= test_RemoveMemberFromForeignDomain(p, tctx, &domain_handle);
5681 ret &= test_CreateAlias(p, tctx, &domain_handle, &alias_handle, sid);
5682 ret &= test_CreateDomainGroup(p, tctx, &domain_handle, &group_handle, sid);
5683 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
5684 ret &= test_QueryDomainInfo2(p, tctx, &domain_handle);
5685 ret &= test_EnumDomainUsers(p, tctx, &domain_handle);
5686 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
5687 ret &= test_EnumDomainGroups(p, tctx, &domain_handle);
5688 ret &= test_EnumDomainAliases(p, tctx, &domain_handle);
5689 ret &= test_QueryDisplayInfo2(p, tctx, &domain_handle);
5690 ret &= test_QueryDisplayInfo3(p, tctx, &domain_handle);
5691 ret &= test_QueryDisplayInfo_continue(p, tctx, &domain_handle);
5693 if (torture_setting_bool(tctx, "samba4", false)) {
5694 torture_comment(tctx, "skipping GetDisplayEnumerationIndex test against Samba4\n");
5696 ret &= test_GetDisplayEnumerationIndex(p, tctx, &domain_handle);
5697 ret &= test_GetDisplayEnumerationIndex2(p, tctx, &domain_handle);
5699 ret &= test_GroupList(p, tctx, &domain_handle);
5700 ret &= test_TestPrivateFunctionsDomain(p, tctx, &domain_handle);
5701 ret &= test_RidToSid(p, tctx, sid, &domain_handle);
5702 ret &= test_GetBootKeyInformation(p, tctx, &domain_handle);
5704 torture_comment(tctx, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx, sid));
5709 if (!policy_handle_empty(&user_handle) &&
5710 !test_DeleteUser(p, tctx, &user_handle)) {
5714 if (!policy_handle_empty(&alias_handle) &&
5715 !test_DeleteAlias(p, tctx, &alias_handle)) {
5719 if (!policy_handle_empty(&group_handle) &&
5720 !test_DeleteDomainGroup(p, tctx, &group_handle)) {
5724 ret &= test_samr_handle_Close(p, tctx, &domain_handle);
5726 /* reconnect the main handle */
5727 ret &= test_Connect(p, tctx, handle);
5730 printf("Testing domain %s failed!\n", dom_sid_string(tctx, sid));
5736 static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
5737 struct policy_handle *handle, const char *domain,
5738 enum torture_samr_choice which_ops,
5739 struct cli_credentials *machine_credentials)
5742 struct samr_LookupDomain r;
5743 struct dom_sid2 *sid = NULL;
5744 struct lsa_String n1;
5745 struct lsa_String n2;
5748 torture_comment(tctx, "Testing LookupDomain(%s)\n", domain);
5750 /* check for correct error codes */
5751 r.in.connect_handle = handle;
5752 r.in.domain_name = &n2;
5756 status = dcerpc_samr_LookupDomain(p, tctx, &r);
5757 torture_assert_ntstatus_equal(tctx, NT_STATUS_INVALID_PARAMETER, status, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
5759 init_lsa_String(&n2, "xxNODOMAINxx");
5761 status = dcerpc_samr_LookupDomain(p, tctx, &r);
5762 torture_assert_ntstatus_equal(tctx, NT_STATUS_NO_SUCH_DOMAIN, status, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
5764 r.in.connect_handle = handle;
5766 init_lsa_String(&n1, domain);
5767 r.in.domain_name = &n1;
5769 status = dcerpc_samr_LookupDomain(p, tctx, &r);
5770 torture_assert_ntstatus_ok(tctx, status, "LookupDomain");
5772 if (!test_GetDomPwInfo(p, tctx, &n1)) {
5776 if (!test_OpenDomain(p, tctx, handle, *r.out.sid, which_ops,
5777 machine_credentials)) {
5785 static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
5786 struct policy_handle *handle, enum torture_samr_choice which_ops,
5787 struct cli_credentials *machine_credentials)
5790 struct samr_EnumDomains r;
5791 uint32_t resume_handle = 0;
5792 uint32_t num_entries = 0;
5793 struct samr_SamArray *sam = NULL;
5797 r.in.connect_handle = handle;
5798 r.in.resume_handle = &resume_handle;
5799 r.in.buf_size = (uint32_t)-1;
5800 r.out.resume_handle = &resume_handle;
5801 r.out.num_entries = &num_entries;
5804 status = dcerpc_samr_EnumDomains(p, tctx, &r);
5805 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
5811 for (i=0;i<sam->count;i++) {
5812 if (!test_LookupDomain(p, tctx, handle,
5813 sam->entries[i].name.string, which_ops,
5814 machine_credentials)) {
5819 status = dcerpc_samr_EnumDomains(p, tctx, &r);
5820 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
5826 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
5827 struct policy_handle *handle)
5830 struct samr_Connect r;
5831 struct samr_Connect2 r2;
5832 struct samr_Connect3 r3;
5833 struct samr_Connect4 r4;
5834 struct samr_Connect5 r5;
5835 union samr_ConnectInfo info;
5836 struct policy_handle h;
5837 uint32_t level_out = 0;
5838 bool ret = true, got_handle = false;
5840 torture_comment(tctx, "testing samr_Connect\n");
5842 r.in.system_name = 0;
5843 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5844 r.out.connect_handle = &h;
5846 status = dcerpc_samr_Connect(p, tctx, &r);
5847 if (!NT_STATUS_IS_OK(status)) {
5848 torture_comment(tctx, "Connect failed - %s\n", nt_errstr(status));
5855 torture_comment(tctx, "testing samr_Connect2\n");
5857 r2.in.system_name = NULL;
5858 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5859 r2.out.connect_handle = &h;
5861 status = dcerpc_samr_Connect2(p, tctx, &r2);
5862 if (!NT_STATUS_IS_OK(status)) {
5863 torture_comment(tctx, "Connect2 failed - %s\n", nt_errstr(status));
5867 test_samr_handle_Close(p, tctx, handle);
5873 torture_comment(tctx, "testing samr_Connect3\n");
5875 r3.in.system_name = NULL;
5877 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5878 r3.out.connect_handle = &h;
5880 status = dcerpc_samr_Connect3(p, tctx, &r3);
5881 if (!NT_STATUS_IS_OK(status)) {
5882 printf("Connect3 failed - %s\n", nt_errstr(status));
5886 test_samr_handle_Close(p, tctx, handle);
5892 torture_comment(tctx, "testing samr_Connect4\n");
5894 r4.in.system_name = "";
5895 r4.in.client_version = 0;
5896 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5897 r4.out.connect_handle = &h;
5899 status = dcerpc_samr_Connect4(p, tctx, &r4);
5900 if (!NT_STATUS_IS_OK(status)) {
5901 printf("Connect4 failed - %s\n", nt_errstr(status));
5905 test_samr_handle_Close(p, tctx, handle);
5911 torture_comment(tctx, "testing samr_Connect5\n");
5913 info.info1.client_version = 0;
5914 info.info1.unknown2 = 0;
5916 r5.in.system_name = "";
5917 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5919 r5.out.level_out = &level_out;
5920 r5.in.info_in = &info;
5921 r5.out.info_out = &info;
5922 r5.out.connect_handle = &h;
5924 status = dcerpc_samr_Connect5(p, tctx, &r5);
5925 if (!NT_STATUS_IS_OK(status)) {
5926 printf("Connect5 failed - %s\n", nt_errstr(status));
5930 test_samr_handle_Close(p, tctx, handle);
5940 bool torture_rpc_samr(struct torture_context *torture)
5943 struct dcerpc_pipe *p;
5945 struct policy_handle handle;
5947 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
5948 if (!NT_STATUS_IS_OK(status)) {
5952 ret &= test_Connect(p, torture, &handle);
5954 ret &= test_QuerySecurity(p, torture, &handle);
5956 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_OTHER, NULL);
5958 ret &= test_SetDsrmPassword(p, torture, &handle);
5960 ret &= test_Shutdown(p, torture, &handle);
5962 ret &= test_samr_handle_Close(p, torture, &handle);
5968 bool torture_rpc_samr_users(struct torture_context *torture)
5971 struct dcerpc_pipe *p;
5973 struct policy_handle handle;
5975 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
5976 if (!NT_STATUS_IS_OK(status)) {
5980 ret &= test_Connect(p, torture, &handle);
5982 ret &= test_QuerySecurity(p, torture, &handle);
5984 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_USER_ATTRIBUTES, NULL);
5986 ret &= test_SetDsrmPassword(p, torture, &handle);
5988 ret &= test_Shutdown(p, torture, &handle);
5990 ret &= test_samr_handle_Close(p, torture, &handle);
5996 bool torture_rpc_samr_passwords(struct torture_context *torture)
5999 struct dcerpc_pipe *p;
6001 struct policy_handle handle;
6003 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6004 if (!NT_STATUS_IS_OK(status)) {
6008 ret &= test_Connect(p, torture, &handle);
6010 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_PASSWORDS, NULL);
6012 ret &= test_samr_handle_Close(p, torture, &handle);
6017 static bool torture_rpc_samr_pwdlastset(struct torture_context *torture,
6018 struct dcerpc_pipe *p2,
6019 struct cli_credentials *machine_credentials)
6022 struct dcerpc_pipe *p;
6024 struct policy_handle handle;
6026 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6027 if (!NT_STATUS_IS_OK(status)) {
6031 ret &= test_Connect(p, torture, &handle);
6033 ret &= test_EnumDomains(p, torture, &handle,
6034 TORTURE_SAMR_PASSWORDS_PWDLASTSET,
6035 machine_credentials);
6037 ret &= test_samr_handle_Close(p, torture, &handle);
6042 struct torture_suite *torture_rpc_samr_passwords_pwdlastset(TALLOC_CTX *mem_ctx)
6044 struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-PASSWORDS-PWDLASTSET");
6045 struct torture_rpc_tcase *tcase;
6047 tcase = torture_suite_add_machine_rpc_iface_tcase(suite, "samr",
6049 TEST_ACCOUNT_NAME_PWD);
6051 torture_rpc_tcase_add_test_creds(tcase, "pwdLastSet",
6052 torture_rpc_samr_pwdlastset);