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
7 Copyright (C) Guenther Deschner 2008,2009
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "torture/torture.h"
25 #include "system/time.h"
26 #include "librpc/gen_ndr/lsa.h"
27 #include "librpc/gen_ndr/ndr_netlogon.h"
28 #include "librpc/gen_ndr/ndr_netlogon_c.h"
29 #include "librpc/gen_ndr/ndr_samr_c.h"
30 #include "librpc/gen_ndr/ndr_lsa_c.h"
31 #include "../lib/crypto/crypto.h"
32 #include "libcli/auth/libcli_auth.h"
33 #include "libcli/security/security.h"
34 #include "torture/rpc/rpc.h"
35 #include "param/param.h"
39 #define TEST_ACCOUNT_NAME "samrtorturetest"
40 #define TEST_ACCOUNT_NAME_PWD "samrpwdlastset"
41 #define TEST_ALIASNAME "samrtorturetestalias"
42 #define TEST_GROUPNAME "samrtorturetestgroup"
43 #define TEST_MACHINENAME "samrtestmach$"
44 #define TEST_DOMAINNAME "samrtestdom$"
46 enum torture_samr_choice {
47 TORTURE_SAMR_PASSWORDS,
48 TORTURE_SAMR_PASSWORDS_PWDLASTSET,
49 TORTURE_SAMR_USER_ATTRIBUTES,
50 TORTURE_SAMR_USER_PRIVILEGES,
52 TORTURE_SAMR_MANY_ACCOUNTS,
53 TORTURE_SAMR_MANY_GROUPS,
54 TORTURE_SAMR_MANY_ALIASES
57 static bool test_QueryUserInfo(struct dcerpc_pipe *p,
58 struct torture_context *tctx,
59 struct policy_handle *handle);
61 static bool test_QueryUserInfo2(struct dcerpc_pipe *p,
62 struct torture_context *tctx,
63 struct policy_handle *handle);
65 static bool test_QueryAliasInfo(struct dcerpc_pipe *p,
66 struct torture_context *tctx,
67 struct policy_handle *handle);
69 static bool test_ChangePassword(struct dcerpc_pipe *p,
70 struct torture_context *tctx,
71 const char *acct_name,
72 struct policy_handle *domain_handle, char **password);
74 static void init_lsa_String(struct lsa_String *string, const char *s)
79 static void init_lsa_StringLarge(struct lsa_StringLarge *string, const char *s)
84 static void init_lsa_BinaryString(struct lsa_BinaryString *string, const char *s, uint32_t length)
86 string->length = length;
87 string->size = length;
88 string->array = (uint16_t *)discard_const(s);
91 bool test_samr_handle_Close(struct dcerpc_pipe *p, struct torture_context *tctx,
92 struct policy_handle *handle)
98 r.out.handle = handle;
100 status = dcerpc_samr_Close(p, tctx, &r);
101 torture_assert_ntstatus_ok(tctx, status, "Close");
106 static bool test_Shutdown(struct dcerpc_pipe *p, struct torture_context *tctx,
107 struct policy_handle *handle)
110 struct samr_Shutdown r;
112 if (!torture_setting_bool(tctx, "dangerous", false)) {
113 torture_skip(tctx, "samr_Shutdown disabled - enable dangerous tests to use\n");
117 r.in.connect_handle = handle;
119 torture_comment(tctx, "testing samr_Shutdown\n");
121 status = dcerpc_samr_Shutdown(p, tctx, &r);
122 torture_assert_ntstatus_ok(tctx, status, "samr_Shutdown");
127 static bool test_SetDsrmPassword(struct dcerpc_pipe *p, struct torture_context *tctx,
128 struct policy_handle *handle)
131 struct samr_SetDsrmPassword r;
132 struct lsa_String string;
133 struct samr_Password hash;
135 if (!torture_setting_bool(tctx, "dangerous", false)) {
136 torture_skip(tctx, "samr_SetDsrmPassword disabled - enable dangerous tests to use");
139 E_md4hash("TeSTDSRM123", hash.hash);
141 init_lsa_String(&string, "Administrator");
147 torture_comment(tctx, "testing samr_SetDsrmPassword\n");
149 status = dcerpc_samr_SetDsrmPassword(p, tctx, &r);
150 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_SUPPORTED, "samr_SetDsrmPassword");
156 static bool test_QuerySecurity(struct dcerpc_pipe *p,
157 struct torture_context *tctx,
158 struct policy_handle *handle)
161 struct samr_QuerySecurity r;
162 struct samr_SetSecurity s;
163 struct sec_desc_buf *sdbuf = NULL;
165 r.in.handle = handle;
167 r.out.sdbuf = &sdbuf;
169 status = dcerpc_samr_QuerySecurity(p, tctx, &r);
170 torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
172 torture_assert(tctx, sdbuf != NULL, "sdbuf is NULL");
174 s.in.handle = handle;
178 if (torture_setting_bool(tctx, "samba4", false)) {
179 torture_skip(tctx, "skipping SetSecurity test against Samba4\n");
182 status = dcerpc_samr_SetSecurity(p, tctx, &s);
183 torture_assert_ntstatus_ok(tctx, status, "SetSecurity");
185 status = dcerpc_samr_QuerySecurity(p, tctx, &r);
186 torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
192 static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
193 struct policy_handle *handle, uint32_t base_acct_flags,
194 const char *base_account_name)
197 struct samr_SetUserInfo s;
198 struct samr_SetUserInfo2 s2;
199 struct samr_QueryUserInfo q;
200 struct samr_QueryUserInfo q0;
201 union samr_UserInfo u;
202 union samr_UserInfo *info;
204 const char *test_account_name;
206 uint32_t user_extra_flags = 0;
208 if (!torture_setting_bool(tctx, "samba3", false)) {
209 if (base_acct_flags == ACB_NORMAL) {
210 /* When created, accounts are expired by default */
211 user_extra_flags = ACB_PW_EXPIRED;
215 s.in.user_handle = handle;
218 s2.in.user_handle = handle;
221 q.in.user_handle = handle;
225 #define TESTCALL(call, r) \
226 status = dcerpc_samr_ ##call(p, tctx, &r); \
227 if (!NT_STATUS_IS_OK(status)) { \
228 torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
229 r.in.level, nt_errstr(status), __location__); \
234 #define STRING_EQUAL(s1, s2, field) \
235 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
236 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
237 #field, s2, __location__); \
242 #define MEM_EQUAL(s1, s2, length, field) \
243 if ((s1 && !s2) || (s2 && !s1) || memcmp(s1, s2, length)) { \
244 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
245 #field, (const char *)s2, __location__); \
250 #define INT_EQUAL(i1, i2, field) \
252 torture_comment(tctx, "Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \
253 #field, (unsigned long long)i2, (unsigned long long)i1, __location__); \
258 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
259 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
261 TESTCALL(QueryUserInfo, q) \
263 s2.in.level = lvl1; \
266 ZERO_STRUCT(u.info21); \
267 u.info21.fields_present = fpval; \
269 init_lsa_String(&u.info ## lvl1.field1, value); \
270 TESTCALL(SetUserInfo, s) \
271 TESTCALL(SetUserInfo2, s2) \
272 init_lsa_String(&u.info ## lvl1.field1, ""); \
273 TESTCALL(QueryUserInfo, q); \
275 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
277 TESTCALL(QueryUserInfo, q) \
279 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
282 #define TEST_USERINFO_BINARYSTRING(lvl1, field1, lvl2, field2, value, fpval) do { \
283 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
285 TESTCALL(QueryUserInfo, q) \
287 s2.in.level = lvl1; \
290 ZERO_STRUCT(u.info21); \
291 u.info21.fields_present = fpval; \
293 init_lsa_BinaryString(&u.info ## lvl1.field1, value, strlen(value)); \
294 TESTCALL(SetUserInfo, s) \
295 TESTCALL(SetUserInfo2, s2) \
296 init_lsa_BinaryString(&u.info ## lvl1.field1, "", 1); \
297 TESTCALL(QueryUserInfo, q); \
299 MEM_EQUAL(u.info ## lvl1.field1.array, value, strlen(value), field1); \
301 TESTCALL(QueryUserInfo, q) \
303 MEM_EQUAL(u.info ## lvl2.field2.array, value, strlen(value), field2); \
306 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
307 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
309 TESTCALL(QueryUserInfo, q) \
311 s2.in.level = lvl1; \
314 uint8_t *bits = u.info21.logon_hours.bits; \
315 ZERO_STRUCT(u.info21); \
316 if (fpval == SAMR_FIELD_LOGON_HOURS) { \
317 u.info21.logon_hours.units_per_week = 168; \
318 u.info21.logon_hours.bits = bits; \
320 u.info21.fields_present = fpval; \
322 u.info ## lvl1.field1 = value; \
323 TESTCALL(SetUserInfo, s) \
324 TESTCALL(SetUserInfo2, s2) \
325 u.info ## lvl1.field1 = 0; \
326 TESTCALL(QueryUserInfo, q); \
328 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
330 TESTCALL(QueryUserInfo, q) \
332 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
335 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
336 TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
340 do { TESTCALL(QueryUserInfo, q0) } while (0);
342 /* Samba 3 cannot store comment fields atm. - gd */
343 if (!torture_setting_bool(tctx, "samba3", false)) {
344 TEST_USERINFO_STRING(2, comment, 1, comment, "xx2-1 comment", 0);
345 TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
346 TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment",
350 test_account_name = talloc_asprintf(tctx, "%sxx7-1", base_account_name);
351 TEST_USERINFO_STRING(7, account_name, 1, account_name, base_account_name, 0);
352 test_account_name = talloc_asprintf(tctx, "%sxx7-3", base_account_name);
353 TEST_USERINFO_STRING(7, account_name, 3, account_name, base_account_name, 0);
354 test_account_name = talloc_asprintf(tctx, "%sxx7-5", base_account_name);
355 TEST_USERINFO_STRING(7, account_name, 5, account_name, base_account_name, 0);
356 test_account_name = talloc_asprintf(tctx, "%sxx7-6", base_account_name);
357 TEST_USERINFO_STRING(7, account_name, 6, account_name, base_account_name, 0);
358 test_account_name = talloc_asprintf(tctx, "%sxx7-7", base_account_name);
359 TEST_USERINFO_STRING(7, account_name, 7, account_name, base_account_name, 0);
360 test_account_name = talloc_asprintf(tctx, "%sxx7-21", base_account_name);
361 TEST_USERINFO_STRING(7, account_name, 21, account_name, base_account_name, 0);
362 test_account_name = base_account_name;
363 TEST_USERINFO_STRING(21, account_name, 21, account_name, base_account_name,
364 SAMR_FIELD_ACCOUNT_NAME);
366 TEST_USERINFO_STRING(6, full_name, 1, full_name, "xx6-1 full_name", 0);
367 TEST_USERINFO_STRING(6, full_name, 3, full_name, "xx6-3 full_name", 0);
368 TEST_USERINFO_STRING(6, full_name, 5, full_name, "xx6-5 full_name", 0);
369 TEST_USERINFO_STRING(6, full_name, 6, full_name, "xx6-6 full_name", 0);
370 TEST_USERINFO_STRING(6, full_name, 8, full_name, "xx6-8 full_name", 0);
371 TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
372 TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
373 TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name",
374 SAMR_FIELD_FULL_NAME);
376 TEST_USERINFO_STRING(6, full_name, 1, full_name, "", 0);
377 TEST_USERINFO_STRING(6, full_name, 3, full_name, "", 0);
378 TEST_USERINFO_STRING(6, full_name, 5, full_name, "", 0);
379 TEST_USERINFO_STRING(6, full_name, 6, full_name, "", 0);
380 TEST_USERINFO_STRING(6, full_name, 8, full_name, "", 0);
381 TEST_USERINFO_STRING(6, full_name, 21, full_name, "", 0);
382 TEST_USERINFO_STRING(8, full_name, 21, full_name, "", 0);
383 TEST_USERINFO_STRING(21, full_name, 21, full_name, "",
384 SAMR_FIELD_FULL_NAME);
386 TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
387 TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
388 TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
389 TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script",
390 SAMR_FIELD_LOGON_SCRIPT);
392 TEST_USERINFO_STRING(12, profile_path, 3, profile_path, "xx12-3 profile_path", 0);
393 TEST_USERINFO_STRING(12, profile_path, 5, profile_path, "xx12-5 profile_path", 0);
394 TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
395 TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path",
396 SAMR_FIELD_PROFILE_PATH);
398 TEST_USERINFO_STRING(10, home_directory, 3, home_directory, "xx10-3 home_directory", 0);
399 TEST_USERINFO_STRING(10, home_directory, 5, home_directory, "xx10-5 home_directory", 0);
400 TEST_USERINFO_STRING(10, home_directory, 21, home_directory, "xx10-21 home_directory", 0);
401 TEST_USERINFO_STRING(21, home_directory, 21, home_directory, "xx21-21 home_directory",
402 SAMR_FIELD_HOME_DIRECTORY);
403 TEST_USERINFO_STRING(21, home_directory, 10, home_directory, "xx21-10 home_directory",
404 SAMR_FIELD_HOME_DIRECTORY);
406 TEST_USERINFO_STRING(10, home_drive, 3, home_drive, "xx10-3 home_drive", 0);
407 TEST_USERINFO_STRING(10, home_drive, 5, home_drive, "xx10-5 home_drive", 0);
408 TEST_USERINFO_STRING(10, home_drive, 21, home_drive, "xx10-21 home_drive", 0);
409 TEST_USERINFO_STRING(21, home_drive, 21, home_drive, "xx21-21 home_drive",
410 SAMR_FIELD_HOME_DRIVE);
411 TEST_USERINFO_STRING(21, home_drive, 10, home_drive, "xx21-10 home_drive",
412 SAMR_FIELD_HOME_DRIVE);
414 TEST_USERINFO_STRING(13, description, 1, description, "xx13-1 description", 0);
415 TEST_USERINFO_STRING(13, description, 5, description, "xx13-5 description", 0);
416 TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
417 TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description",
418 SAMR_FIELD_DESCRIPTION);
420 TEST_USERINFO_STRING(14, workstations, 3, workstations, "14workstation3", 0);
421 TEST_USERINFO_STRING(14, workstations, 5, workstations, "14workstation4", 0);
422 TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
423 TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21",
424 SAMR_FIELD_WORKSTATIONS);
425 TEST_USERINFO_STRING(21, workstations, 3, workstations, "21workstation3",
426 SAMR_FIELD_WORKSTATIONS);
427 TEST_USERINFO_STRING(21, workstations, 5, workstations, "21workstation5",
428 SAMR_FIELD_WORKSTATIONS);
429 TEST_USERINFO_STRING(21, workstations, 14, workstations, "21workstation14",
430 SAMR_FIELD_WORKSTATIONS);
432 TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
433 TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "xx21-21 parameters",
434 SAMR_FIELD_PARAMETERS);
435 TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "xx21-20 parameters",
436 SAMR_FIELD_PARAMETERS);
437 /* also empty user parameters are allowed */
438 TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "", 0);
439 TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "",
440 SAMR_FIELD_PARAMETERS);
441 TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "",
442 SAMR_FIELD_PARAMETERS);
444 /* Samba 3 cannot store country_code and copy_page atm. - gd */
445 if (!torture_setting_bool(tctx, "samba3", false)) {
446 TEST_USERINFO_INT(2, country_code, 2, country_code, __LINE__, 0);
447 TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
448 TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__,
449 SAMR_FIELD_COUNTRY_CODE);
450 TEST_USERINFO_INT(21, country_code, 2, country_code, __LINE__,
451 SAMR_FIELD_COUNTRY_CODE);
453 TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
454 TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__,
455 SAMR_FIELD_CODE_PAGE);
456 TEST_USERINFO_INT(21, code_page, 2, code_page, __LINE__,
457 SAMR_FIELD_CODE_PAGE);
460 if (!torture_setting_bool(tctx, "samba3", false)) {
461 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, __LINE__, 0);
462 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, __LINE__, 0);
463 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, __LINE__,
464 SAMR_FIELD_ACCT_EXPIRY);
465 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, __LINE__,
466 SAMR_FIELD_ACCT_EXPIRY);
467 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, __LINE__,
468 SAMR_FIELD_ACCT_EXPIRY);
470 /* Samba 3 can only store seconds / time_t in passdb - gd */
472 unix_to_nt_time(&nt, time(NULL) + __LINE__);
473 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, nt, 0);
474 unix_to_nt_time(&nt, time(NULL) + __LINE__);
475 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, nt, 0);
476 unix_to_nt_time(&nt, time(NULL) + __LINE__);
477 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
478 unix_to_nt_time(&nt, time(NULL) + __LINE__);
479 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
480 unix_to_nt_time(&nt, time(NULL) + __LINE__);
481 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
484 TEST_USERINFO_INT(4, logon_hours.bits[3], 3, logon_hours.bits[3], 1, 0);
485 TEST_USERINFO_INT(4, logon_hours.bits[3], 5, logon_hours.bits[3], 2, 0);
486 TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
487 TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4,
488 SAMR_FIELD_LOGON_HOURS);
490 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
491 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
492 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
494 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
495 (base_acct_flags | ACB_DISABLED),
496 (base_acct_flags | ACB_DISABLED | user_extra_flags),
499 /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
500 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
501 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
502 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
504 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
505 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
506 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
510 /* The 'autolock' flag doesn't stick - check this */
511 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
512 (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK),
513 (base_acct_flags | ACB_DISABLED | user_extra_flags),
516 /* Removing the 'disabled' flag doesn't stick - check this */
517 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
519 (base_acct_flags | ACB_DISABLED | user_extra_flags),
523 /* Samba3 cannot store these atm */
524 if (!torture_setting_bool(tctx, "samba3", false)) {
525 /* The 'store plaintext' flag does stick */
526 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
527 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED),
528 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags),
530 /* The 'use DES' flag does stick */
531 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
532 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY),
533 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags),
535 /* The 'don't require kerberos pre-authentication flag does stick */
536 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
537 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH),
538 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags),
540 /* The 'no kerberos PAC required' flag sticks */
541 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
542 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD),
543 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags),
546 TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags,
547 (base_acct_flags | ACB_DISABLED),
548 (base_acct_flags | ACB_DISABLED | user_extra_flags),
549 SAMR_FIELD_ACCT_FLAGS);
552 /* these fail with win2003 - it appears you can't set the primary gid?
553 the set succeeds, but the gid isn't changed. Very weird! */
554 TEST_USERINFO_INT(9, primary_gid, 1, primary_gid, 513);
555 TEST_USERINFO_INT(9, primary_gid, 3, primary_gid, 513);
556 TEST_USERINFO_INT(9, primary_gid, 5, primary_gid, 513);
557 TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
564 generate a random password for password change tests
566 static char *samr_rand_pass_silent(TALLOC_CTX *mem_ctx, int min_len)
568 size_t len = MAX(8, min_len) + (random() % 6);
569 char *s = generate_random_str(mem_ctx, len);
573 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
575 char *s = samr_rand_pass_silent(mem_ctx, min_len);
576 printf("Generated password '%s'\n", s);
582 generate a random password for password change tests
584 static DATA_BLOB samr_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
587 DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
588 generate_random_buffer(password.data, password.length);
590 for (i=0; i < len; i++) {
591 if (((uint16_t *)password.data)[i] == 0) {
592 ((uint16_t *)password.data)[i] = 1;
600 generate a random password for password change tests (fixed length)
602 static char *samr_rand_pass_fixed_len(TALLOC_CTX *mem_ctx, int len)
604 char *s = generate_random_str(mem_ctx, len);
605 printf("Generated password '%s'\n", s);
609 static bool test_SetUserPass(struct dcerpc_pipe *p, struct torture_context *tctx,
610 struct policy_handle *handle, char **password)
613 struct samr_SetUserInfo s;
614 union samr_UserInfo u;
616 DATA_BLOB session_key;
618 struct samr_GetUserPwInfo pwp;
619 struct samr_PwInfo info;
620 int policy_min_pw_len = 0;
621 pwp.in.user_handle = handle;
622 pwp.out.info = &info;
624 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
625 if (NT_STATUS_IS_OK(status)) {
626 policy_min_pw_len = pwp.out.info->min_password_length;
628 newpass = samr_rand_pass(tctx, policy_min_pw_len);
630 s.in.user_handle = handle;
634 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
635 u.info24.password_expired = 0;
637 status = dcerpc_fetch_session_key(p, &session_key);
638 if (!NT_STATUS_IS_OK(status)) {
639 printf("SetUserInfo level %u - no session key - %s\n",
640 s.in.level, nt_errstr(status));
644 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
646 torture_comment(tctx, "Testing SetUserInfo level 24 (set password)\n");
648 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
649 if (!NT_STATUS_IS_OK(status)) {
650 printf("SetUserInfo level %u failed - %s\n",
651 s.in.level, nt_errstr(status));
661 static bool test_SetUserPass_23(struct dcerpc_pipe *p, struct torture_context *tctx,
662 struct policy_handle *handle, uint32_t fields_present,
666 struct samr_SetUserInfo s;
667 union samr_UserInfo u;
669 DATA_BLOB session_key;
671 struct samr_GetUserPwInfo pwp;
672 struct samr_PwInfo info;
673 int policy_min_pw_len = 0;
674 pwp.in.user_handle = handle;
675 pwp.out.info = &info;
677 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
678 if (NT_STATUS_IS_OK(status)) {
679 policy_min_pw_len = pwp.out.info->min_password_length;
681 newpass = samr_rand_pass(tctx, policy_min_pw_len);
683 s.in.user_handle = handle;
689 u.info23.info.fields_present = fields_present;
691 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
693 status = dcerpc_fetch_session_key(p, &session_key);
694 if (!NT_STATUS_IS_OK(status)) {
695 printf("SetUserInfo level %u - no session key - %s\n",
696 s.in.level, nt_errstr(status));
700 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
702 torture_comment(tctx, "Testing SetUserInfo level 23 (set password)\n");
704 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
705 if (!NT_STATUS_IS_OK(status)) {
706 printf("SetUserInfo level %u failed - %s\n",
707 s.in.level, nt_errstr(status));
713 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
715 status = dcerpc_fetch_session_key(p, &session_key);
716 if (!NT_STATUS_IS_OK(status)) {
717 printf("SetUserInfo level %u - no session key - %s\n",
718 s.in.level, nt_errstr(status));
722 /* This should break the key nicely */
723 session_key.length--;
724 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
726 torture_comment(tctx, "Testing SetUserInfo level 23 (set password) with wrong password\n");
728 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
729 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
730 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
731 s.in.level, nt_errstr(status));
739 static bool test_SetUserPassEx(struct dcerpc_pipe *p, struct torture_context *tctx,
740 struct policy_handle *handle, bool makeshort,
744 struct samr_SetUserInfo s;
745 union samr_UserInfo u;
747 DATA_BLOB session_key;
748 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
749 uint8_t confounder[16];
751 struct MD5Context ctx;
752 struct samr_GetUserPwInfo pwp;
753 struct samr_PwInfo info;
754 int policy_min_pw_len = 0;
755 pwp.in.user_handle = handle;
756 pwp.out.info = &info;
758 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
759 if (NT_STATUS_IS_OK(status)) {
760 policy_min_pw_len = pwp.out.info->min_password_length;
762 if (makeshort && policy_min_pw_len) {
763 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len - 1);
765 newpass = samr_rand_pass(tctx, policy_min_pw_len);
768 s.in.user_handle = handle;
772 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
773 u.info26.password_expired = 0;
775 status = dcerpc_fetch_session_key(p, &session_key);
776 if (!NT_STATUS_IS_OK(status)) {
777 printf("SetUserInfo level %u - no session key - %s\n",
778 s.in.level, nt_errstr(status));
782 generate_random_buffer((uint8_t *)confounder, 16);
785 MD5Update(&ctx, confounder, 16);
786 MD5Update(&ctx, session_key.data, session_key.length);
787 MD5Final(confounded_session_key.data, &ctx);
789 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
790 memcpy(&u.info26.password.data[516], confounder, 16);
792 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex)\n");
794 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
795 if (!NT_STATUS_IS_OK(status)) {
796 printf("SetUserInfo level %u failed - %s\n",
797 s.in.level, nt_errstr(status));
803 /* This should break the key nicely */
804 confounded_session_key.data[0]++;
806 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
807 memcpy(&u.info26.password.data[516], confounder, 16);
809 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
811 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
812 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
813 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
814 s.in.level, nt_errstr(status));
823 static bool test_SetUserPass_25(struct dcerpc_pipe *p, struct torture_context *tctx,
824 struct policy_handle *handle, uint32_t fields_present,
828 struct samr_SetUserInfo s;
829 union samr_UserInfo u;
831 DATA_BLOB session_key;
832 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
833 struct MD5Context ctx;
834 uint8_t confounder[16];
836 struct samr_GetUserPwInfo pwp;
837 struct samr_PwInfo info;
838 int policy_min_pw_len = 0;
839 pwp.in.user_handle = handle;
840 pwp.out.info = &info;
842 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
843 if (NT_STATUS_IS_OK(status)) {
844 policy_min_pw_len = pwp.out.info->min_password_length;
846 newpass = samr_rand_pass(tctx, policy_min_pw_len);
848 s.in.user_handle = handle;
854 u.info25.info.fields_present = fields_present;
856 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
858 status = dcerpc_fetch_session_key(p, &session_key);
859 if (!NT_STATUS_IS_OK(status)) {
860 printf("SetUserInfo level %u - no session key - %s\n",
861 s.in.level, nt_errstr(status));
865 generate_random_buffer((uint8_t *)confounder, 16);
868 MD5Update(&ctx, confounder, 16);
869 MD5Update(&ctx, session_key.data, session_key.length);
870 MD5Final(confounded_session_key.data, &ctx);
872 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
873 memcpy(&u.info25.password.data[516], confounder, 16);
875 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex)\n");
877 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
878 if (!NT_STATUS_IS_OK(status)) {
879 printf("SetUserInfo level %u failed - %s\n",
880 s.in.level, nt_errstr(status));
886 /* This should break the key nicely */
887 confounded_session_key.data[0]++;
889 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
890 memcpy(&u.info25.password.data[516], confounder, 16);
892 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
894 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
895 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
896 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
897 s.in.level, nt_errstr(status));
904 static bool test_SetUserPass_18(struct dcerpc_pipe *p, struct torture_context *tctx,
905 struct policy_handle *handle, char **password)
908 struct samr_SetUserInfo s;
909 union samr_UserInfo u;
911 DATA_BLOB session_key;
913 struct samr_GetUserPwInfo pwp;
914 struct samr_PwInfo info;
915 int policy_min_pw_len = 0;
916 uint8_t lm_hash[16], nt_hash[16];
918 pwp.in.user_handle = handle;
919 pwp.out.info = &info;
921 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
922 if (NT_STATUS_IS_OK(status)) {
923 policy_min_pw_len = pwp.out.info->min_password_length;
925 newpass = samr_rand_pass(tctx, policy_min_pw_len);
927 s.in.user_handle = handle;
933 u.info18.nt_pwd_active = true;
934 u.info18.lm_pwd_active = true;
936 E_md4hash(newpass, nt_hash);
937 E_deshash(newpass, lm_hash);
939 status = dcerpc_fetch_session_key(p, &session_key);
940 if (!NT_STATUS_IS_OK(status)) {
941 printf("SetUserInfo level %u - no session key - %s\n",
942 s.in.level, nt_errstr(status));
948 in = data_blob_const(nt_hash, 16);
949 out = data_blob_talloc_zero(tctx, 16);
950 sess_crypt_blob(&out, &in, &session_key, true);
951 memcpy(u.info18.nt_pwd.hash, out.data, out.length);
955 in = data_blob_const(lm_hash, 16);
956 out = data_blob_talloc_zero(tctx, 16);
957 sess_crypt_blob(&out, &in, &session_key, true);
958 memcpy(u.info18.lm_pwd.hash, out.data, out.length);
961 torture_comment(tctx, "Testing SetUserInfo level 18 (set password hash)\n");
963 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
964 if (!NT_STATUS_IS_OK(status)) {
965 printf("SetUserInfo level %u failed - %s\n",
966 s.in.level, nt_errstr(status));
975 static bool test_SetUserPass_21(struct dcerpc_pipe *p, struct torture_context *tctx,
976 struct policy_handle *handle, uint32_t fields_present,
980 struct samr_SetUserInfo s;
981 union samr_UserInfo u;
983 DATA_BLOB session_key;
985 struct samr_GetUserPwInfo pwp;
986 struct samr_PwInfo info;
987 int policy_min_pw_len = 0;
988 uint8_t lm_hash[16], nt_hash[16];
990 pwp.in.user_handle = handle;
991 pwp.out.info = &info;
993 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
994 if (NT_STATUS_IS_OK(status)) {
995 policy_min_pw_len = pwp.out.info->min_password_length;
997 newpass = samr_rand_pass(tctx, policy_min_pw_len);
999 s.in.user_handle = handle;
1003 E_md4hash(newpass, nt_hash);
1004 E_deshash(newpass, lm_hash);
1008 u.info21.fields_present = fields_present;
1010 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1011 u.info21.lm_owf_password.length = 16;
1012 u.info21.lm_owf_password.size = 16;
1013 u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
1014 u.info21.lm_password_set = true;
1017 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1018 u.info21.nt_owf_password.length = 16;
1019 u.info21.nt_owf_password.size = 16;
1020 u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
1021 u.info21.nt_password_set = true;
1024 status = dcerpc_fetch_session_key(p, &session_key);
1025 if (!NT_STATUS_IS_OK(status)) {
1026 printf("SetUserInfo level %u - no session key - %s\n",
1027 s.in.level, nt_errstr(status));
1031 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1033 in = data_blob_const(u.info21.lm_owf_password.array,
1034 u.info21.lm_owf_password.length);
1035 out = data_blob_talloc_zero(tctx, 16);
1036 sess_crypt_blob(&out, &in, &session_key, true);
1037 u.info21.lm_owf_password.array = (uint16_t *)out.data;
1040 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1042 in = data_blob_const(u.info21.nt_owf_password.array,
1043 u.info21.nt_owf_password.length);
1044 out = data_blob_talloc_zero(tctx, 16);
1045 sess_crypt_blob(&out, &in, &session_key, true);
1046 u.info21.nt_owf_password.array = (uint16_t *)out.data;
1049 torture_comment(tctx, "Testing SetUserInfo level 21 (set password hash)\n");
1051 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1052 if (!NT_STATUS_IS_OK(status)) {
1053 printf("SetUserInfo level %u failed - %s\n",
1054 s.in.level, nt_errstr(status));
1057 *password = newpass;
1060 /* try invalid length */
1061 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1063 u.info21.nt_owf_password.length++;
1065 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1067 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1068 printf("SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1069 s.in.level, nt_errstr(status));
1074 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1076 u.info21.lm_owf_password.length++;
1078 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1080 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1081 printf("SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1082 s.in.level, nt_errstr(status));
1090 static bool test_SetUserPass_level_ex(struct dcerpc_pipe *p,
1091 struct torture_context *tctx,
1092 struct policy_handle *handle,
1094 uint32_t fields_present,
1095 char **password, uint8_t password_expired,
1097 bool *matched_expected_error)
1100 NTSTATUS expected_error = NT_STATUS_OK;
1101 struct samr_SetUserInfo s;
1102 struct samr_SetUserInfo2 s2;
1103 union samr_UserInfo u;
1105 DATA_BLOB session_key;
1106 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
1107 struct MD5Context ctx;
1108 uint8_t confounder[16];
1110 struct samr_GetUserPwInfo pwp;
1111 struct samr_PwInfo info;
1112 int policy_min_pw_len = 0;
1113 const char *comment = NULL;
1114 uint8_t lm_hash[16], nt_hash[16];
1116 pwp.in.user_handle = handle;
1117 pwp.out.info = &info;
1119 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1120 if (NT_STATUS_IS_OK(status)) {
1121 policy_min_pw_len = pwp.out.info->min_password_length;
1123 newpass = samr_rand_pass_silent(tctx, policy_min_pw_len);
1126 s2.in.user_handle = handle;
1128 s2.in.level = level;
1130 s.in.user_handle = handle;
1135 if (fields_present & SAMR_FIELD_COMMENT) {
1136 comment = talloc_asprintf(tctx, "comment: %ld\n", time(NULL));
1143 E_md4hash(newpass, nt_hash);
1144 E_deshash(newpass, lm_hash);
1146 u.info18.nt_pwd_active = true;
1147 u.info18.lm_pwd_active = true;
1148 u.info18.password_expired = password_expired;
1150 memcpy(u.info18.lm_pwd.hash, lm_hash, 16);
1151 memcpy(u.info18.nt_pwd.hash, nt_hash, 16);
1155 E_md4hash(newpass, nt_hash);
1156 E_deshash(newpass, lm_hash);
1158 u.info21.fields_present = fields_present;
1159 u.info21.password_expired = password_expired;
1160 u.info21.comment.string = comment;
1162 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1163 u.info21.lm_owf_password.length = 16;
1164 u.info21.lm_owf_password.size = 16;
1165 u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
1166 u.info21.lm_password_set = true;
1169 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1170 u.info21.nt_owf_password.length = 16;
1171 u.info21.nt_owf_password.size = 16;
1172 u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
1173 u.info21.nt_password_set = true;
1178 u.info23.info.fields_present = fields_present;
1179 u.info23.info.password_expired = password_expired;
1180 u.info23.info.comment.string = comment;
1182 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
1186 u.info24.password_expired = password_expired;
1188 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
1192 u.info25.info.fields_present = fields_present;
1193 u.info25.info.password_expired = password_expired;
1194 u.info25.info.comment.string = comment;
1196 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
1200 u.info26.password_expired = password_expired;
1202 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
1207 status = dcerpc_fetch_session_key(p, &session_key);
1208 if (!NT_STATUS_IS_OK(status)) {
1209 printf("SetUserInfo level %u - no session key - %s\n",
1210 s.in.level, nt_errstr(status));
1214 generate_random_buffer((uint8_t *)confounder, 16);
1217 MD5Update(&ctx, confounder, 16);
1218 MD5Update(&ctx, session_key.data, session_key.length);
1219 MD5Final(confounded_session_key.data, &ctx);
1225 in = data_blob_const(u.info18.nt_pwd.hash, 16);
1226 out = data_blob_talloc_zero(tctx, 16);
1227 sess_crypt_blob(&out, &in, &session_key, true);
1228 memcpy(u.info18.nt_pwd.hash, out.data, out.length);
1232 in = data_blob_const(u.info18.lm_pwd.hash, 16);
1233 out = data_blob_talloc_zero(tctx, 16);
1234 sess_crypt_blob(&out, &in, &session_key, true);
1235 memcpy(u.info18.lm_pwd.hash, out.data, out.length);
1240 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1242 in = data_blob_const(u.info21.lm_owf_password.array,
1243 u.info21.lm_owf_password.length);
1244 out = data_blob_talloc_zero(tctx, 16);
1245 sess_crypt_blob(&out, &in, &session_key, true);
1246 u.info21.lm_owf_password.array = (uint16_t *)out.data;
1248 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1250 in = data_blob_const(u.info21.nt_owf_password.array,
1251 u.info21.nt_owf_password.length);
1252 out = data_blob_talloc_zero(tctx, 16);
1253 sess_crypt_blob(&out, &in, &session_key, true);
1254 u.info21.nt_owf_password.array = (uint16_t *)out.data;
1258 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
1261 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
1264 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
1265 memcpy(&u.info25.password.data[516], confounder, 16);
1268 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
1269 memcpy(&u.info26.password.data[516], confounder, 16);
1274 status = dcerpc_samr_SetUserInfo2(p, tctx, &s2);
1276 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1279 if (!NT_STATUS_IS_OK(status)) {
1280 if (fields_present == 0) {
1281 expected_error = NT_STATUS_INVALID_PARAMETER;
1283 if (fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
1284 expected_error = NT_STATUS_ACCESS_DENIED;
1288 if (!NT_STATUS_IS_OK(expected_error)) {
1290 torture_assert_ntstatus_equal(tctx,
1292 expected_error, "SetUserInfo2 failed");
1294 torture_assert_ntstatus_equal(tctx,
1296 expected_error, "SetUserInfo failed");
1298 *matched_expected_error = true;
1302 if (!NT_STATUS_IS_OK(status)) {
1303 printf("SetUserInfo%s level %u failed - %s\n",
1304 use_setinfo2 ? "2":"", level, nt_errstr(status));
1307 *password = newpass;
1313 static bool test_SetAliasInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1314 struct policy_handle *handle)
1317 struct samr_SetAliasInfo r;
1318 struct samr_QueryAliasInfo q;
1319 union samr_AliasInfo *info;
1320 uint16_t levels[] = {2, 3};
1324 /* Ignoring switch level 1, as that includes the number of members for the alias
1325 * and setting this to a wrong value might have negative consequences
1328 for (i=0;i<ARRAY_SIZE(levels);i++) {
1329 torture_comment(tctx, "Testing SetAliasInfo level %u\n", levels[i]);
1331 r.in.alias_handle = handle;
1332 r.in.level = levels[i];
1333 r.in.info = talloc(tctx, union samr_AliasInfo);
1334 switch (r.in.level) {
1335 case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
1336 case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
1337 "Test Description, should test I18N as well"); break;
1338 case ALIASINFOALL: printf("ALIASINFOALL ignored\n"); break;
1341 status = dcerpc_samr_SetAliasInfo(p, tctx, &r);
1342 if (!NT_STATUS_IS_OK(status)) {
1343 printf("SetAliasInfo level %u failed - %s\n",
1344 levels[i], nt_errstr(status));
1348 q.in.alias_handle = handle;
1349 q.in.level = levels[i];
1352 status = dcerpc_samr_QueryAliasInfo(p, tctx, &q);
1353 if (!NT_STATUS_IS_OK(status)) {
1354 printf("QueryAliasInfo level %u failed - %s\n",
1355 levels[i], nt_errstr(status));
1363 static bool test_GetGroupsForUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1364 struct policy_handle *user_handle)
1366 struct samr_GetGroupsForUser r;
1367 struct samr_RidWithAttributeArray *rids = NULL;
1370 torture_comment(tctx, "testing GetGroupsForUser\n");
1372 r.in.user_handle = user_handle;
1375 status = dcerpc_samr_GetGroupsForUser(p, tctx, &r);
1376 torture_assert_ntstatus_ok(tctx, status, "GetGroupsForUser");
1382 static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1383 struct lsa_String *domain_name)
1386 struct samr_GetDomPwInfo r;
1387 struct samr_PwInfo info;
1389 r.in.domain_name = domain_name;
1392 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1394 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1395 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1397 r.in.domain_name->string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1398 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1400 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1401 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1403 r.in.domain_name->string = "\\\\__NONAME__";
1404 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1406 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1407 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1409 r.in.domain_name->string = "\\\\Builtin";
1410 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1412 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1413 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1418 static bool test_GetUserPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1419 struct policy_handle *handle)
1422 struct samr_GetUserPwInfo r;
1423 struct samr_PwInfo info;
1425 torture_comment(tctx, "Testing GetUserPwInfo\n");
1427 r.in.user_handle = handle;
1430 status = dcerpc_samr_GetUserPwInfo(p, tctx, &r);
1431 torture_assert_ntstatus_ok(tctx, status, "GetUserPwInfo");
1436 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, struct torture_context *tctx,
1437 struct policy_handle *domain_handle, const char *name,
1441 struct samr_LookupNames n;
1442 struct lsa_String sname[2];
1443 struct samr_Ids rids, types;
1445 init_lsa_String(&sname[0], name);
1447 n.in.domain_handle = domain_handle;
1451 n.out.types = &types;
1452 status = dcerpc_samr_LookupNames(p, tctx, &n);
1453 if (NT_STATUS_IS_OK(status)) {
1454 *rid = n.out.rids->ids[0];
1459 init_lsa_String(&sname[1], "xxNONAMExx");
1461 status = dcerpc_samr_LookupNames(p, tctx, &n);
1462 if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
1463 printf("LookupNames[2] failed - %s\n", nt_errstr(status));
1464 if (NT_STATUS_IS_OK(status)) {
1465 return NT_STATUS_UNSUCCESSFUL;
1471 status = dcerpc_samr_LookupNames(p, tctx, &n);
1472 if (!NT_STATUS_IS_OK(status)) {
1473 printf("LookupNames[0] failed - %s\n", nt_errstr(status));
1477 init_lsa_String(&sname[0], "xxNONAMExx");
1479 status = dcerpc_samr_LookupNames(p, tctx, &n);
1480 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1481 printf("LookupNames[1 bad name] failed - %s\n", nt_errstr(status));
1482 if (NT_STATUS_IS_OK(status)) {
1483 return NT_STATUS_UNSUCCESSFUL;
1488 init_lsa_String(&sname[0], "xxNONAMExx");
1489 init_lsa_String(&sname[1], "xxNONAME2xx");
1491 status = dcerpc_samr_LookupNames(p, tctx, &n);
1492 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1493 printf("LookupNames[2 bad names] failed - %s\n", nt_errstr(status));
1494 if (NT_STATUS_IS_OK(status)) {
1495 return NT_STATUS_UNSUCCESSFUL;
1500 return NT_STATUS_OK;
1503 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p,
1504 struct torture_context *tctx,
1505 struct policy_handle *domain_handle,
1506 const char *name, struct policy_handle *user_handle)
1509 struct samr_OpenUser r;
1512 status = test_LookupName(p, tctx, domain_handle, name, &rid);
1513 if (!NT_STATUS_IS_OK(status)) {
1517 r.in.domain_handle = domain_handle;
1518 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1520 r.out.user_handle = user_handle;
1521 status = dcerpc_samr_OpenUser(p, tctx, &r);
1522 if (!NT_STATUS_IS_OK(status)) {
1523 printf("OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(status));
1530 static bool test_ChangePasswordNT3(struct dcerpc_pipe *p,
1531 struct torture_context *tctx,
1532 struct policy_handle *handle)
1535 struct samr_ChangePasswordUser r;
1537 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1538 struct policy_handle user_handle;
1539 char *oldpass = "test";
1540 char *newpass = "test2";
1541 uint8_t old_nt_hash[16], new_nt_hash[16];
1542 uint8_t old_lm_hash[16], new_lm_hash[16];
1544 status = test_OpenUser_byname(p, tctx, handle, "testuser", &user_handle);
1545 if (!NT_STATUS_IS_OK(status)) {
1549 printf("Testing ChangePasswordUser for user 'testuser'\n");
1551 printf("old password: %s\n", oldpass);
1552 printf("new password: %s\n", newpass);
1554 E_md4hash(oldpass, old_nt_hash);
1555 E_md4hash(newpass, new_nt_hash);
1556 E_deshash(oldpass, old_lm_hash);
1557 E_deshash(newpass, new_lm_hash);
1559 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1560 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1561 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1562 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1563 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1564 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1566 r.in.handle = &user_handle;
1567 r.in.lm_present = 1;
1568 r.in.old_lm_crypted = &hash1;
1569 r.in.new_lm_crypted = &hash2;
1570 r.in.nt_present = 1;
1571 r.in.old_nt_crypted = &hash3;
1572 r.in.new_nt_crypted = &hash4;
1573 r.in.cross1_present = 1;
1574 r.in.nt_cross = &hash5;
1575 r.in.cross2_present = 1;
1576 r.in.lm_cross = &hash6;
1578 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1579 if (!NT_STATUS_IS_OK(status)) {
1580 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1584 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
1592 static bool test_ChangePasswordUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1593 const char *acct_name,
1594 struct policy_handle *handle, char **password)
1597 struct samr_ChangePasswordUser r;
1599 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1600 struct policy_handle user_handle;
1602 uint8_t old_nt_hash[16], new_nt_hash[16];
1603 uint8_t old_lm_hash[16], new_lm_hash[16];
1604 bool changed = true;
1607 struct samr_GetUserPwInfo pwp;
1608 struct samr_PwInfo info;
1609 int policy_min_pw_len = 0;
1611 status = test_OpenUser_byname(p, tctx, handle, acct_name, &user_handle);
1612 if (!NT_STATUS_IS_OK(status)) {
1615 pwp.in.user_handle = &user_handle;
1616 pwp.out.info = &info;
1618 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1619 if (NT_STATUS_IS_OK(status)) {
1620 policy_min_pw_len = pwp.out.info->min_password_length;
1622 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1624 torture_comment(tctx, "Testing ChangePasswordUser\n");
1626 torture_assert(tctx, *password != NULL,
1627 "Failing ChangePasswordUser as old password was NULL. Previous test failed?");
1629 oldpass = *password;
1631 E_md4hash(oldpass, old_nt_hash);
1632 E_md4hash(newpass, new_nt_hash);
1633 E_deshash(oldpass, old_lm_hash);
1634 E_deshash(newpass, new_lm_hash);
1636 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1637 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1638 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1639 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1640 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1641 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1643 r.in.user_handle = &user_handle;
1644 r.in.lm_present = 1;
1645 /* Break the LM hash */
1647 r.in.old_lm_crypted = &hash1;
1648 r.in.new_lm_crypted = &hash2;
1649 r.in.nt_present = 1;
1650 r.in.old_nt_crypted = &hash3;
1651 r.in.new_nt_crypted = &hash4;
1652 r.in.cross1_present = 1;
1653 r.in.nt_cross = &hash5;
1654 r.in.cross2_present = 1;
1655 r.in.lm_cross = &hash6;
1657 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1658 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1659 "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash");
1661 /* Unbreak the LM hash */
1664 r.in.user_handle = &user_handle;
1665 r.in.lm_present = 1;
1666 r.in.old_lm_crypted = &hash1;
1667 r.in.new_lm_crypted = &hash2;
1668 /* Break the NT hash */
1670 r.in.nt_present = 1;
1671 r.in.old_nt_crypted = &hash3;
1672 r.in.new_nt_crypted = &hash4;
1673 r.in.cross1_present = 1;
1674 r.in.nt_cross = &hash5;
1675 r.in.cross2_present = 1;
1676 r.in.lm_cross = &hash6;
1678 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1679 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1680 "expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash");
1682 /* Unbreak the NT hash */
1685 r.in.user_handle = &user_handle;
1686 r.in.lm_present = 1;
1687 r.in.old_lm_crypted = &hash1;
1688 r.in.new_lm_crypted = &hash2;
1689 r.in.nt_present = 1;
1690 r.in.old_nt_crypted = &hash3;
1691 r.in.new_nt_crypted = &hash4;
1692 r.in.cross1_present = 1;
1693 r.in.nt_cross = &hash5;
1694 r.in.cross2_present = 1;
1695 /* Break the LM cross */
1697 r.in.lm_cross = &hash6;
1699 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1700 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1701 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status));
1705 /* Unbreak the LM cross */
1708 r.in.user_handle = &user_handle;
1709 r.in.lm_present = 1;
1710 r.in.old_lm_crypted = &hash1;
1711 r.in.new_lm_crypted = &hash2;
1712 r.in.nt_present = 1;
1713 r.in.old_nt_crypted = &hash3;
1714 r.in.new_nt_crypted = &hash4;
1715 r.in.cross1_present = 1;
1716 /* Break the NT cross */
1718 r.in.nt_cross = &hash5;
1719 r.in.cross2_present = 1;
1720 r.in.lm_cross = &hash6;
1722 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1723 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1724 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status));
1728 /* Unbreak the NT cross */
1732 /* Reset the hashes to not broken values */
1733 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1734 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1735 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1736 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1737 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1738 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1740 r.in.user_handle = &user_handle;
1741 r.in.lm_present = 1;
1742 r.in.old_lm_crypted = &hash1;
1743 r.in.new_lm_crypted = &hash2;
1744 r.in.nt_present = 1;
1745 r.in.old_nt_crypted = &hash3;
1746 r.in.new_nt_crypted = &hash4;
1747 r.in.cross1_present = 1;
1748 r.in.nt_cross = &hash5;
1749 r.in.cross2_present = 0;
1750 r.in.lm_cross = NULL;
1752 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1753 if (NT_STATUS_IS_OK(status)) {
1755 *password = newpass;
1756 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1757 printf("ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(status));
1762 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1764 E_md4hash(oldpass, old_nt_hash);
1765 E_md4hash(newpass, new_nt_hash);
1766 E_deshash(oldpass, old_lm_hash);
1767 E_deshash(newpass, new_lm_hash);
1770 /* Reset the hashes to not broken values */
1771 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1772 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1773 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1774 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1775 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1776 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1778 r.in.user_handle = &user_handle;
1779 r.in.lm_present = 1;
1780 r.in.old_lm_crypted = &hash1;
1781 r.in.new_lm_crypted = &hash2;
1782 r.in.nt_present = 1;
1783 r.in.old_nt_crypted = &hash3;
1784 r.in.new_nt_crypted = &hash4;
1785 r.in.cross1_present = 0;
1786 r.in.nt_cross = NULL;
1787 r.in.cross2_present = 1;
1788 r.in.lm_cross = &hash6;
1790 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1791 if (NT_STATUS_IS_OK(status)) {
1793 *password = newpass;
1794 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1795 printf("ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status));
1800 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1802 E_md4hash(oldpass, old_nt_hash);
1803 E_md4hash(newpass, new_nt_hash);
1804 E_deshash(oldpass, old_lm_hash);
1805 E_deshash(newpass, new_lm_hash);
1808 /* Reset the hashes to not broken values */
1809 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1810 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1811 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1812 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1813 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1814 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1816 r.in.user_handle = &user_handle;
1817 r.in.lm_present = 1;
1818 r.in.old_lm_crypted = &hash1;
1819 r.in.new_lm_crypted = &hash2;
1820 r.in.nt_present = 1;
1821 r.in.old_nt_crypted = &hash3;
1822 r.in.new_nt_crypted = &hash4;
1823 r.in.cross1_present = 1;
1824 r.in.nt_cross = &hash5;
1825 r.in.cross2_present = 1;
1826 r.in.lm_cross = &hash6;
1828 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1829 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1830 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1831 } else if (!NT_STATUS_IS_OK(status)) {
1832 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1836 *password = newpass;
1839 r.in.user_handle = &user_handle;
1840 r.in.lm_present = 1;
1841 r.in.old_lm_crypted = &hash1;
1842 r.in.new_lm_crypted = &hash2;
1843 r.in.nt_present = 1;
1844 r.in.old_nt_crypted = &hash3;
1845 r.in.new_nt_crypted = &hash4;
1846 r.in.cross1_present = 1;
1847 r.in.nt_cross = &hash5;
1848 r.in.cross2_present = 1;
1849 r.in.lm_cross = &hash6;
1852 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1853 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1854 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1855 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1856 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status));
1862 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
1870 static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
1871 const char *acct_name,
1872 struct policy_handle *handle, char **password)
1875 struct samr_OemChangePasswordUser2 r;
1877 struct samr_Password lm_verifier;
1878 struct samr_CryptPassword lm_pass;
1879 struct lsa_AsciiString server, account, account_bad;
1882 uint8_t old_lm_hash[16], new_lm_hash[16];
1884 struct samr_GetDomPwInfo dom_pw_info;
1885 struct samr_PwInfo info;
1886 int policy_min_pw_len = 0;
1888 struct lsa_String domain_name;
1890 domain_name.string = "";
1891 dom_pw_info.in.domain_name = &domain_name;
1892 dom_pw_info.out.info = &info;
1894 torture_comment(tctx, "Testing OemChangePasswordUser2\n");
1896 torture_assert(tctx, *password != NULL,
1897 "Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?");
1899 oldpass = *password;
1901 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
1902 if (NT_STATUS_IS_OK(status)) {
1903 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
1906 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1908 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1909 account.string = acct_name;
1911 E_deshash(oldpass, old_lm_hash);
1912 E_deshash(newpass, new_lm_hash);
1914 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1915 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1916 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1918 r.in.server = &server;
1919 r.in.account = &account;
1920 r.in.password = &lm_pass;
1921 r.in.hash = &lm_verifier;
1923 /* Break the verification */
1924 lm_verifier.hash[0]++;
1926 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1928 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1929 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1930 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1935 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1936 /* Break the old password */
1938 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1939 /* unbreak it for the next operation */
1941 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1943 r.in.server = &server;
1944 r.in.account = &account;
1945 r.in.password = &lm_pass;
1946 r.in.hash = &lm_verifier;
1948 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1950 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1951 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1952 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1957 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1958 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1960 r.in.server = &server;
1961 r.in.account = &account;
1962 r.in.password = &lm_pass;
1965 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1967 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1968 && !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1969 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
1974 /* This shouldn't be a valid name */
1975 account_bad.string = TEST_ACCOUNT_NAME "XX";
1976 r.in.account = &account_bad;
1978 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1980 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1981 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
1986 /* This shouldn't be a valid name */
1987 account_bad.string = TEST_ACCOUNT_NAME "XX";
1988 r.in.account = &account_bad;
1989 r.in.password = &lm_pass;
1990 r.in.hash = &lm_verifier;
1992 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1994 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1995 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
2000 /* This shouldn't be a valid name */
2001 account_bad.string = TEST_ACCOUNT_NAME "XX";
2002 r.in.account = &account_bad;
2003 r.in.password = NULL;
2004 r.in.hash = &lm_verifier;
2006 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
2008 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
2009 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
2014 E_deshash(oldpass, old_lm_hash);
2015 E_deshash(newpass, new_lm_hash);
2017 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
2018 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2019 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
2021 r.in.server = &server;
2022 r.in.account = &account;
2023 r.in.password = &lm_pass;
2024 r.in.hash = &lm_verifier;
2026 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
2027 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2028 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
2029 } else if (!NT_STATUS_IS_OK(status)) {
2030 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
2033 *password = newpass;
2040 static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
2041 const char *acct_name,
2043 char *newpass, bool allow_password_restriction)
2046 struct samr_ChangePasswordUser2 r;
2048 struct lsa_String server, account;
2049 struct samr_CryptPassword nt_pass, lm_pass;
2050 struct samr_Password nt_verifier, lm_verifier;
2052 uint8_t old_nt_hash[16], new_nt_hash[16];
2053 uint8_t old_lm_hash[16], new_lm_hash[16];
2055 struct samr_GetDomPwInfo dom_pw_info;
2056 struct samr_PwInfo info;
2058 struct lsa_String domain_name;
2060 domain_name.string = "";
2061 dom_pw_info.in.domain_name = &domain_name;
2062 dom_pw_info.out.info = &info;
2064 torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name);
2066 torture_assert(tctx, *password != NULL,
2067 "Failing ChangePasswordUser2 as old password was NULL. Previous test failed?");
2068 oldpass = *password;
2071 int policy_min_pw_len = 0;
2072 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
2073 if (NT_STATUS_IS_OK(status)) {
2074 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
2077 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2080 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2081 init_lsa_String(&account, acct_name);
2083 E_md4hash(oldpass, old_nt_hash);
2084 E_md4hash(newpass, new_nt_hash);
2086 E_deshash(oldpass, old_lm_hash);
2087 E_deshash(newpass, new_lm_hash);
2089 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
2090 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2091 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2093 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2094 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2095 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2097 r.in.server = &server;
2098 r.in.account = &account;
2099 r.in.nt_password = &nt_pass;
2100 r.in.nt_verifier = &nt_verifier;
2102 r.in.lm_password = &lm_pass;
2103 r.in.lm_verifier = &lm_verifier;
2105 status = dcerpc_samr_ChangePasswordUser2(p, tctx, &r);
2106 if (allow_password_restriction && NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2107 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
2108 } else if (!NT_STATUS_IS_OK(status)) {
2109 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
2112 *password = newpass;
2119 bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tctx,
2120 const char *account_string,
2121 int policy_min_pw_len,
2123 const char *newpass,
2124 NTTIME last_password_change,
2125 bool handle_reject_reason)
2128 struct samr_ChangePasswordUser3 r;
2130 struct lsa_String server, account, account_bad;
2131 struct samr_CryptPassword nt_pass, lm_pass;
2132 struct samr_Password nt_verifier, lm_verifier;
2134 uint8_t old_nt_hash[16], new_nt_hash[16];
2135 uint8_t old_lm_hash[16], new_lm_hash[16];
2137 struct samr_DomInfo1 *dominfo = NULL;
2138 struct samr_ChangeReject *reject = NULL;
2140 torture_comment(tctx, "Testing ChangePasswordUser3\n");
2142 if (newpass == NULL) {
2144 if (policy_min_pw_len == 0) {
2145 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2147 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len);
2149 } while (check_password_quality(newpass) == false);
2151 torture_comment(tctx, "Using password '%s'\n", newpass);
2154 torture_assert(tctx, *password != NULL,
2155 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2157 oldpass = *password;
2158 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2159 init_lsa_String(&account, account_string);
2161 E_md4hash(oldpass, old_nt_hash);
2162 E_md4hash(newpass, new_nt_hash);
2164 E_deshash(oldpass, old_lm_hash);
2165 E_deshash(newpass, new_lm_hash);
2167 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2168 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2169 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2171 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2172 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2173 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2175 /* Break the verification */
2176 nt_verifier.hash[0]++;
2178 r.in.server = &server;
2179 r.in.account = &account;
2180 r.in.nt_password = &nt_pass;
2181 r.in.nt_verifier = &nt_verifier;
2183 r.in.lm_password = &lm_pass;
2184 r.in.lm_verifier = &lm_verifier;
2185 r.in.password3 = NULL;
2186 r.out.dominfo = &dominfo;
2187 r.out.reject = &reject;
2189 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2190 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
2191 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
2192 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
2197 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2198 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2199 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2201 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2202 /* Break the NT hash */
2204 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2205 /* Unbreak it again */
2207 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2209 r.in.server = &server;
2210 r.in.account = &account;
2211 r.in.nt_password = &nt_pass;
2212 r.in.nt_verifier = &nt_verifier;
2214 r.in.lm_password = &lm_pass;
2215 r.in.lm_verifier = &lm_verifier;
2216 r.in.password3 = NULL;
2217 r.out.dominfo = &dominfo;
2218 r.out.reject = &reject;
2220 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2221 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
2222 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
2223 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
2228 /* This shouldn't be a valid name */
2229 init_lsa_String(&account_bad, talloc_asprintf(tctx, "%sXX", account_string));
2231 r.in.account = &account_bad;
2232 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2233 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
2234 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
2239 E_md4hash(oldpass, old_nt_hash);
2240 E_md4hash(newpass, new_nt_hash);
2242 E_deshash(oldpass, old_lm_hash);
2243 E_deshash(newpass, new_lm_hash);
2245 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2246 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2247 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2249 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2250 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2251 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2253 r.in.server = &server;
2254 r.in.account = &account;
2255 r.in.nt_password = &nt_pass;
2256 r.in.nt_verifier = &nt_verifier;
2258 r.in.lm_password = &lm_pass;
2259 r.in.lm_verifier = &lm_verifier;
2260 r.in.password3 = NULL;
2261 r.out.dominfo = &dominfo;
2262 r.out.reject = &reject;
2264 unix_to_nt_time(&t, time(NULL));
2266 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2268 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
2271 && handle_reject_reason
2272 && (!null_nttime(last_password_change) || !dominfo->min_password_age)) {
2273 if (dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
2275 if (reject && (reject->reason != SAMR_REJECT_OTHER)) {
2276 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2277 SAMR_REJECT_OTHER, reject->reason);
2282 /* We tested the order of precendence which is as follows:
2291 if ((dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
2292 (last_password_change + dominfo->min_password_age > t)) {
2294 if (reject->reason != SAMR_REJECT_OTHER) {
2295 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2296 SAMR_REJECT_OTHER, reject->reason);
2300 } else if ((dominfo->min_password_length > 0) &&
2301 (strlen(newpass) < dominfo->min_password_length)) {
2303 if (reject->reason != SAMR_REJECT_TOO_SHORT) {
2304 printf("expected SAMR_REJECT_TOO_SHORT (%d), got %d\n",
2305 SAMR_REJECT_TOO_SHORT, reject->reason);
2309 } else if ((dominfo->password_history_length > 0) &&
2310 strequal(oldpass, newpass)) {
2312 if (reject->reason != SAMR_REJECT_IN_HISTORY) {
2313 printf("expected SAMR_REJECT_IN_HISTORY (%d), got %d\n",
2314 SAMR_REJECT_IN_HISTORY, reject->reason);
2317 } else if (dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
2319 if (reject->reason != SAMR_REJECT_COMPLEXITY) {
2320 printf("expected SAMR_REJECT_COMPLEXITY (%d), got %d\n",
2321 SAMR_REJECT_COMPLEXITY, reject->reason);
2327 if (reject->reason == SAMR_REJECT_TOO_SHORT) {
2328 /* retry with adjusted size */
2329 return test_ChangePasswordUser3(p, tctx, account_string,
2330 dominfo->min_password_length,
2331 password, NULL, 0, false);
2335 } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2336 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2337 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2338 SAMR_REJECT_OTHER, reject->reason);
2341 /* Perhaps the server has a 'min password age' set? */
2344 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3");
2345 *password = talloc_strdup(tctx, newpass);
2351 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_context *tctx,
2352 const char *account_string,
2353 struct policy_handle *handle,
2357 struct samr_ChangePasswordUser3 r;
2358 struct samr_SetUserInfo s;
2359 union samr_UserInfo u;
2360 DATA_BLOB session_key;
2361 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
2362 uint8_t confounder[16];
2363 struct MD5Context ctx;
2366 struct lsa_String server, account;
2367 struct samr_CryptPassword nt_pass;
2368 struct samr_Password nt_verifier;
2369 DATA_BLOB new_random_pass;
2372 uint8_t old_nt_hash[16], new_nt_hash[16];
2374 struct samr_DomInfo1 *dominfo = NULL;
2375 struct samr_ChangeReject *reject = NULL;
2377 new_random_pass = samr_very_rand_pass(tctx, 128);
2379 torture_assert(tctx, *password != NULL,
2380 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2382 oldpass = *password;
2383 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2384 init_lsa_String(&account, account_string);
2386 s.in.user_handle = handle;
2392 u.info25.info.fields_present = SAMR_FIELD_NT_PASSWORD_PRESENT;
2394 set_pw_in_buffer(u.info25.password.data, &new_random_pass);
2396 status = dcerpc_fetch_session_key(p, &session_key);
2397 if (!NT_STATUS_IS_OK(status)) {
2398 printf("SetUserInfo level %u - no session key - %s\n",
2399 s.in.level, nt_errstr(status));
2403 generate_random_buffer((uint8_t *)confounder, 16);
2406 MD5Update(&ctx, confounder, 16);
2407 MD5Update(&ctx, session_key.data, session_key.length);
2408 MD5Final(confounded_session_key.data, &ctx);
2410 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
2411 memcpy(&u.info25.password.data[516], confounder, 16);
2413 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
2415 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
2416 if (!NT_STATUS_IS_OK(status)) {
2417 printf("SetUserInfo level %u failed - %s\n",
2418 s.in.level, nt_errstr(status));
2422 torture_comment(tctx, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
2424 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2426 new_random_pass = samr_very_rand_pass(tctx, 128);
2428 mdfour(new_nt_hash, new_random_pass.data, new_random_pass.length);
2430 set_pw_in_buffer(nt_pass.data, &new_random_pass);
2431 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2432 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2434 r.in.server = &server;
2435 r.in.account = &account;
2436 r.in.nt_password = &nt_pass;
2437 r.in.nt_verifier = &nt_verifier;
2439 r.in.lm_password = NULL;
2440 r.in.lm_verifier = NULL;
2441 r.in.password3 = NULL;
2442 r.out.dominfo = &dominfo;
2443 r.out.reject = &reject;
2445 unix_to_nt_time(&t, time(NULL));
2447 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2449 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2450 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2451 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2452 SAMR_REJECT_OTHER, reject->reason);
2455 /* Perhaps the server has a 'min password age' set? */
2457 } else if (!NT_STATUS_IS_OK(status)) {
2458 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
2462 newpass = samr_rand_pass(tctx, 128);
2464 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2466 E_md4hash(newpass, new_nt_hash);
2468 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2469 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2470 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2472 r.in.server = &server;
2473 r.in.account = &account;
2474 r.in.nt_password = &nt_pass;
2475 r.in.nt_verifier = &nt_verifier;
2477 r.in.lm_password = NULL;
2478 r.in.lm_verifier = NULL;
2479 r.in.password3 = NULL;
2480 r.out.dominfo = &dominfo;
2481 r.out.reject = &reject;
2483 unix_to_nt_time(&t, time(NULL));
2485 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2487 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2488 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2489 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2490 SAMR_REJECT_OTHER, reject->reason);
2493 /* Perhaps the server has a 'min password age' set? */
2496 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3 (on second random password)");
2497 *password = talloc_strdup(tctx, newpass);
2504 static bool test_GetMembersInAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2505 struct policy_handle *alias_handle)
2507 struct samr_GetMembersInAlias r;
2508 struct lsa_SidArray sids;
2511 torture_comment(tctx, "Testing GetMembersInAlias\n");
2513 r.in.alias_handle = alias_handle;
2516 status = dcerpc_samr_GetMembersInAlias(p, tctx, &r);
2517 torture_assert_ntstatus_ok(tctx, status, "GetMembersInAlias");
2522 static bool test_AddMemberToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2523 struct policy_handle *alias_handle,
2524 const struct dom_sid *domain_sid)
2526 struct samr_AddAliasMember r;
2527 struct samr_DeleteAliasMember d;
2529 struct dom_sid *sid;
2531 sid = dom_sid_add_rid(tctx, domain_sid, 512);
2533 torture_comment(tctx, "testing AddAliasMember\n");
2534 r.in.alias_handle = alias_handle;
2537 status = dcerpc_samr_AddAliasMember(p, tctx, &r);
2538 torture_assert_ntstatus_ok(tctx, status, "AddAliasMember");
2540 d.in.alias_handle = alias_handle;
2543 status = dcerpc_samr_DeleteAliasMember(p, tctx, &d);
2544 torture_assert_ntstatus_ok(tctx, status, "DelAliasMember");
2549 static bool test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2550 struct policy_handle *alias_handle)
2552 struct samr_AddMultipleMembersToAlias a;
2553 struct samr_RemoveMultipleMembersFromAlias r;
2555 struct lsa_SidArray sids;
2557 torture_comment(tctx, "testing AddMultipleMembersToAlias\n");
2558 a.in.alias_handle = alias_handle;
2562 sids.sids = talloc_array(tctx, struct lsa_SidPtr, 3);
2564 sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2565 sids.sids[1].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-2");
2566 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-3");
2568 status = dcerpc_samr_AddMultipleMembersToAlias(p, tctx, &a);
2569 torture_assert_ntstatus_ok(tctx, status, "AddMultipleMembersToAlias");
2572 torture_comment(tctx, "testing RemoveMultipleMembersFromAlias\n");
2573 r.in.alias_handle = alias_handle;
2576 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2577 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2579 /* strange! removing twice doesn't give any error */
2580 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2581 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2583 /* but removing an alias that isn't there does */
2584 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-4");
2586 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2587 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, "RemoveMultipleMembersFromAlias");
2592 static bool test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2593 struct policy_handle *user_handle)
2595 struct samr_TestPrivateFunctionsUser r;
2598 torture_comment(tctx, "Testing TestPrivateFunctionsUser\n");
2600 r.in.user_handle = user_handle;
2602 status = dcerpc_samr_TestPrivateFunctionsUser(p, tctx, &r);
2603 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsUser");
2608 static bool test_QueryUserInfo_pwdlastset(struct dcerpc_pipe *p,
2609 struct torture_context *tctx,
2610 struct policy_handle *handle,
2615 uint16_t levels[] = { /* 3, */ 5, 21 };
2617 NTTIME pwdlastset3 = 0;
2618 NTTIME pwdlastset5 = 0;
2619 NTTIME pwdlastset21 = 0;
2621 torture_comment(tctx, "Testing QueryUserInfo%s level 5 and 21 call ",
2622 use_info2 ? "2":"");
2624 for (i=0; i<ARRAY_SIZE(levels); i++) {
2626 struct samr_QueryUserInfo r;
2627 struct samr_QueryUserInfo2 r2;
2628 union samr_UserInfo *info;
2631 r2.in.user_handle = handle;
2632 r2.in.level = levels[i];
2633 r2.out.info = &info;
2634 status = dcerpc_samr_QueryUserInfo2(p, tctx, &r2);
2637 r.in.user_handle = handle;
2638 r.in.level = levels[i];
2640 status = dcerpc_samr_QueryUserInfo(p, tctx, &r);
2643 if (!NT_STATUS_IS_OK(status) &&
2644 !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
2645 printf("QueryUserInfo%s level %u failed - %s\n",
2646 use_info2 ? "2":"", levels[i], nt_errstr(status));
2650 switch (levels[i]) {
2652 pwdlastset3 = info->info3.last_password_change;
2655 pwdlastset5 = info->info5.last_password_change;
2658 pwdlastset21 = info->info21.last_password_change;
2664 /* torture_assert_int_equal(tctx, pwdlastset3, pwdlastset5,
2665 "pwdlastset mixup"); */
2666 torture_assert_int_equal(tctx, pwdlastset5, pwdlastset21,
2667 "pwdlastset mixup");
2669 *pwdlastset = pwdlastset21;
2671 torture_comment(tctx, "(pwdlastset: %lld)\n", *pwdlastset);
2676 static bool test_SamLogon(struct torture_context *tctx,
2677 struct dcerpc_pipe *p,
2678 struct cli_credentials *test_credentials,
2679 NTSTATUS expected_result)
2682 struct netr_LogonSamLogonEx r;
2683 union netr_LogonLevel logon;
2684 union netr_Validation validation;
2685 uint8_t authoritative;
2686 struct netr_NetworkInfo ninfo;
2687 DATA_BLOB names_blob, chal, lm_resp, nt_resp;
2688 int flags = CLI_CRED_NTLM_AUTH;
2689 uint32_t samlogon_flags = 0;
2691 if (lp_client_lanman_auth(tctx->lp_ctx)) {
2692 flags |= CLI_CRED_LANMAN_AUTH;
2695 if (lp_client_ntlmv2_auth(tctx->lp_ctx)) {
2696 flags |= CLI_CRED_NTLMv2_AUTH;
2699 cli_credentials_get_ntlm_username_domain(test_credentials, tctx,
2700 &ninfo.identity_info.account_name.string,
2701 &ninfo.identity_info.domain_name.string);
2703 generate_random_buffer(ninfo.challenge,
2704 sizeof(ninfo.challenge));
2705 chal = data_blob_const(ninfo.challenge,
2706 sizeof(ninfo.challenge));
2708 names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(test_credentials),
2709 cli_credentials_get_domain(test_credentials));
2711 status = cli_credentials_get_ntlm_response(test_credentials, tctx,
2717 torture_assert_ntstatus_ok(tctx, status, "cli_credentials_get_ntlm_response failed");
2719 ninfo.lm.data = lm_resp.data;
2720 ninfo.lm.length = lm_resp.length;
2722 ninfo.nt.data = nt_resp.data;
2723 ninfo.nt.length = nt_resp.length;
2725 ninfo.identity_info.parameter_control =
2726 MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT |
2727 MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;
2728 ninfo.identity_info.logon_id_low = 0;
2729 ninfo.identity_info.logon_id_high = 0;
2730 ninfo.identity_info.workstation.string = cli_credentials_get_workstation(test_credentials);
2732 logon.network = &ninfo;
2734 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2735 r.in.computer_name = cli_credentials_get_workstation(test_credentials);
2736 r.in.logon_level = NetlogonNetworkInformation;
2737 r.in.logon = &logon;
2738 r.in.flags = &samlogon_flags;
2739 r.out.flags = &samlogon_flags;
2740 r.out.validation = &validation;
2741 r.out.authoritative = &authoritative;
2743 d_printf("Testing LogonSamLogon with name %s\n", ninfo.identity_info.account_name.string);
2745 r.in.validation_level = 6;
2747 status = dcerpc_netr_LogonSamLogonEx(p, tctx, &r);
2748 if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
2749 r.in.validation_level = 3;
2750 status = dcerpc_netr_LogonSamLogonEx(p, tctx, &r);
2752 if (!NT_STATUS_IS_OK(status)) {
2753 torture_assert_ntstatus_equal(tctx, status, expected_result, "LogonSamLogonEx failed");
2756 torture_assert_ntstatus_ok(tctx, status, "LogonSamLogonEx failed");
2762 static bool test_SamLogon_with_creds(struct torture_context *tctx,
2763 struct dcerpc_pipe *p,
2764 struct cli_credentials *machine_creds,
2765 const char *acct_name,
2767 NTSTATUS expected_samlogon_result)
2770 struct cli_credentials *test_credentials;
2772 test_credentials = cli_credentials_init(tctx);
2774 cli_credentials_set_workstation(test_credentials,
2775 cli_credentials_get_workstation(machine_creds), CRED_SPECIFIED);
2776 cli_credentials_set_domain(test_credentials,
2777 cli_credentials_get_domain(machine_creds), CRED_SPECIFIED);
2778 cli_credentials_set_username(test_credentials,
2779 acct_name, CRED_SPECIFIED);
2780 cli_credentials_set_password(test_credentials,
2781 password, CRED_SPECIFIED);
2783 printf("testing samlogon as %s password: %s\n",
2784 acct_name, password);
2786 if (!test_SamLogon(tctx, p, test_credentials,
2787 expected_samlogon_result)) {
2788 torture_warning(tctx, "new password did not work\n");
2795 static bool test_SetPassword_level(struct dcerpc_pipe *p,
2796 struct dcerpc_pipe *np,
2797 struct torture_context *tctx,
2798 struct policy_handle *handle,
2800 uint32_t fields_present,
2801 uint8_t password_expired,
2802 bool *matched_expected_error,
2804 const char *acct_name,
2806 struct cli_credentials *machine_creds,
2807 bool use_queryinfo2,
2809 NTSTATUS expected_samlogon_result)
2811 const char *fields = NULL;
2818 fields = talloc_asprintf(tctx, "(fields_present: 0x%08x)",
2825 torture_comment(tctx, "Testing SetUserInfo%s level %d call "
2826 "(password_expired: %d) %s\n",
2827 use_setinfo2 ? "2":"", level, password_expired,
2828 fields ? fields : "");
2830 if (!test_SetUserPass_level_ex(p, tctx, handle, level,
2835 matched_expected_error)) {
2839 if (!test_QueryUserInfo_pwdlastset(p, tctx, handle,
2845 if (*matched_expected_error == true) {
2849 if (!test_SamLogon_with_creds(tctx, np,
2853 expected_samlogon_result)) {
2860 static bool test_SetPassword_pwdlastset(struct dcerpc_pipe *p,
2861 struct torture_context *tctx,
2862 uint32_t acct_flags,
2863 const char *acct_name,
2864 struct policy_handle *handle,
2866 struct cli_credentials *machine_credentials)
2868 int s = 0, q = 0, f = 0, l = 0, z = 0;
2869 struct dcerpc_binding *b;
2872 bool set_levels[] = { false, true };
2873 bool query_levels[] = { false, true };
2874 uint32_t levels[] = { 18, 21, 26, 23, 24, 25 }; /* Second half only used when TEST_ALL_LEVELS defined */
2875 uint32_t nonzeros[] = { 1, 24 };
2876 uint32_t fields_present[] = {
2878 SAMR_FIELD_EXPIRED_FLAG,
2879 SAMR_FIELD_LAST_PWD_CHANGE,
2880 SAMR_FIELD_EXPIRED_FLAG | SAMR_FIELD_LAST_PWD_CHANGE,
2882 SAMR_FIELD_NT_PASSWORD_PRESENT,
2883 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
2884 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
2885 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
2886 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
2887 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
2888 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE | SAMR_FIELD_EXPIRED_FLAG
2891 struct dcerpc_pipe *np = NULL;
2893 if (torture_setting_bool(tctx, "samba3", false)) {
2895 printf("Samba3 has second granularity, setting delay to: %d\n",
2899 status = torture_rpc_binding(tctx, &b);
2900 if (!NT_STATUS_IS_OK(status)) {
2905 /* We have to use schannel, otherwise the SamLogonEx fails
2906 * with INTERNAL_ERROR */
2908 b->flags &= ~DCERPC_AUTH_OPTIONS;
2909 b->flags |= DCERPC_SCHANNEL | DCERPC_SIGN | DCERPC_SCHANNEL_128;
2911 status = dcerpc_pipe_connect_b(tctx, &np, b,
2912 &ndr_table_netlogon,
2913 machine_credentials, tctx->ev, tctx->lp_ctx);
2915 if (!NT_STATUS_IS_OK(status)) {
2916 d_printf("RPC pipe connect as domain member failed: %s\n", nt_errstr(status));
2921 /* set to 1 to enable testing for all possible opcode
2922 (SetUserInfo, SetUserInfo2, QueryUserInfo, QueryUserInfo2)
2925 #define TEST_ALL_LEVELS 1
2926 #define TEST_SET_LEVELS 1
2927 #define TEST_QUERY_LEVELS 1
2929 #ifdef TEST_ALL_LEVELS
2930 for (l=0; l<ARRAY_SIZE(levels); l++) {
2932 for (l=0; l<(ARRAY_SIZE(levels))/2; l++) {
2934 for (z=0; z<ARRAY_SIZE(nonzeros); z++) {
2935 for (f=0; f<ARRAY_SIZE(fields_present); f++) {
2936 #ifdef TEST_SET_LEVELS
2937 for (s=0; s<ARRAY_SIZE(set_levels); s++) {
2939 #ifdef TEST_QUERY_LEVELS
2940 for (q=0; q<ARRAY_SIZE(query_levels); q++) {
2942 NTTIME pwdlastset_old = 0;
2943 NTTIME pwdlastset_new = 0;
2944 bool matched_expected_error = false;
2945 NTSTATUS expected_samlogon_result = NT_STATUS_ACCOUNT_DISABLED;
2947 torture_comment(tctx, "------------------------------\n"
2948 "Testing pwdLastSet attribute for flags: 0x%08x "
2949 "(s: %d (l: %d), q: %d)\n",
2950 acct_flags, s, levels[l], q);
2952 switch (levels[l]) {
2956 if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
2957 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT))) {
2958 expected_samlogon_result = NT_STATUS_WRONG_PASSWORD;
2966 /* set a password and force password change (pwdlastset 0) by
2967 * setting the password expired flag to a non-0 value */
2969 if (!test_SetPassword_level(p, np, tctx, handle,
2973 &matched_expected_error,
2977 machine_credentials,
2980 expected_samlogon_result)) {
2984 if (matched_expected_error == true) {
2985 /* skipping on expected failure */
2989 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
2990 * set without the SAMR_FIELD_EXPIRED_FLAG */
2992 switch (levels[l]) {
2996 if ((pwdlastset_new != 0) &&
2997 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
2998 torture_comment(tctx, "not considering a non-0 "
2999 "pwdLastSet as a an error as the "
3000 "SAMR_FIELD_EXPIRED_FLAG has not "
3005 if (pwdlastset_new != 0) {
3006 torture_warning(tctx, "pwdLastSet test failed: "
3007 "expected pwdLastSet 0 but got %lld\n",
3014 switch (levels[l]) {
3018 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3019 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3020 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3021 (pwdlastset_old >= pwdlastset_new)) {
3022 torture_warning(tctx, "pwdlastset not increasing\n");
3027 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3028 (pwdlastset_old >= pwdlastset_new)) {
3029 torture_warning(tctx, "pwdlastset not increasing\n");
3039 /* set a password, pwdlastset needs to get updated (increased
3040 * value), password_expired value used here is 0 */
3042 if (!test_SetPassword_level(p, np, tctx, handle,
3046 &matched_expected_error,
3050 machine_credentials,
3053 expected_samlogon_result)) {
3057 /* when a password has been changed, pwdlastset must not be 0 afterwards
3058 * and must be larger then the old value */
3060 switch (levels[l]) {
3065 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3066 * password has been changed, old and new pwdlastset
3067 * need to be the same value */
3069 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3070 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3071 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3073 torture_assert_int_equal(tctx, pwdlastset_old,
3074 pwdlastset_new, "pwdlastset must be equal");
3078 if (pwdlastset_old >= pwdlastset_new) {
3079 torture_warning(tctx, "pwdLastSet test failed: "
3080 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
3081 pwdlastset_old, pwdlastset_new);
3084 if (pwdlastset_new == 0) {
3085 torture_warning(tctx, "pwdLastSet test failed: "
3086 "expected non-0 pwdlastset, got: %lld\n",
3092 switch (levels[l]) {
3096 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3097 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3098 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3099 (pwdlastset_old >= pwdlastset_new)) {
3100 torture_warning(tctx, "pwdlastset not increasing\n");
3105 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3106 (pwdlastset_old >= pwdlastset_new)) {
3107 torture_warning(tctx, "pwdlastset not increasing\n");
3113 pwdlastset_old = pwdlastset_new;
3119 /* set a password, pwdlastset needs to get updated (increased
3120 * value), password_expired value used here is 0 */
3122 if (!test_SetPassword_level(p, np, tctx, handle,
3126 &matched_expected_error,
3130 machine_credentials,
3133 expected_samlogon_result)) {
3137 /* when a password has been changed, pwdlastset must not be 0 afterwards
3138 * and must be larger then the old value */
3140 switch (levels[l]) {
3145 /* if no password has been changed, old and new pwdlastset
3146 * need to be the same value */
3148 if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3149 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3151 torture_assert_int_equal(tctx, pwdlastset_old,
3152 pwdlastset_new, "pwdlastset must be equal");
3156 if (pwdlastset_old >= pwdlastset_new) {
3157 torture_warning(tctx, "pwdLastSet test failed: "
3158 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
3159 pwdlastset_old, pwdlastset_new);
3162 if (pwdlastset_new == 0) {
3163 torture_warning(tctx, "pwdLastSet test failed: "
3164 "expected non-0 pwdlastset, got: %lld\n",
3172 /* set a password and force password change (pwdlastset 0) by
3173 * setting the password expired flag to a non-0 value */
3175 if (!test_SetPassword_level(p, np, tctx, handle,
3179 &matched_expected_error,
3183 machine_credentials,
3186 expected_samlogon_result)) {
3190 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3191 * set without the SAMR_FIELD_EXPIRED_FLAG */
3193 switch (levels[l]) {
3197 if ((pwdlastset_new != 0) &&
3198 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
3199 torture_comment(tctx, "not considering a non-0 "
3200 "pwdLastSet as a an error as the "
3201 "SAMR_FIELD_EXPIRED_FLAG has not "
3206 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3207 * password has been changed, old and new pwdlastset
3208 * need to be the same value */
3210 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3211 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3212 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3214 torture_assert_int_equal(tctx, pwdlastset_old,
3215 pwdlastset_new, "pwdlastset must be equal");
3220 if (pwdlastset_old == pwdlastset_new) {
3221 torture_warning(tctx, "pwdLastSet test failed: "
3222 "expected last pwdlastset (%lld) != new pwdlastset (%lld)\n",
3223 pwdlastset_old, pwdlastset_new);
3227 if (pwdlastset_new != 0) {
3228 torture_warning(tctx, "pwdLastSet test failed: "
3229 "expected pwdLastSet 0, got %lld\n",
3236 switch (levels[l]) {
3240 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3241 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3242 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3243 (pwdlastset_old >= pwdlastset_new)) {
3244 torture_warning(tctx, "pwdlastset not increasing\n");
3249 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3250 (pwdlastset_old >= pwdlastset_new)) {
3251 torture_warning(tctx, "pwdlastset not increasing\n");
3257 /* if the level we are testing does not have a fields_present
3258 * field, skip all fields present tests by setting f to to
3260 switch (levels[l]) {
3264 f = ARRAY_SIZE(fields_present);
3268 #ifdef TEST_QUERY_LEVELS
3271 #ifdef TEST_SET_LEVELS
3274 } /* fields present */
3278 #undef TEST_SET_LEVELS
3279 #undef TEST_QUERY_LEVELS
3284 static bool test_DeleteUser_with_privs(struct dcerpc_pipe *p,
3285 struct dcerpc_pipe *lp,
3286 struct torture_context *tctx,
3287 struct policy_handle *domain_handle,
3288 struct policy_handle *lsa_handle,
3289 struct policy_handle *user_handle,
3290 const struct dom_sid *domain_sid,
3292 struct cli_credentials *machine_credentials)
3297 struct policy_handle lsa_acct_handle;
3298 struct dom_sid *user_sid;
3300 user_sid = dom_sid_add_rid(tctx, domain_sid, rid);
3303 struct lsa_EnumAccountRights r;
3304 struct lsa_RightSet rights;
3306 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
3308 r.in.handle = lsa_handle;
3309 r.in.sid = user_sid;
3310 r.out.rights = &rights;
3312 status = dcerpc_lsa_EnumAccountRights(lp, tctx, &r);
3313 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3314 "Expected enum rights for account to fail");
3318 struct lsa_RightSet rights;
3319 struct lsa_StringLarge names[2];
3320 struct lsa_AddAccountRights r;
3322 torture_comment(tctx, "Testing LSA AddAccountRights\n");
3324 init_lsa_StringLarge(&names[0], "SeMachineAccountPrivilege");
3325 init_lsa_StringLarge(&names[1], NULL);
3328 rights.names = names;
3330 r.in.handle = lsa_handle;
3331 r.in.sid = user_sid;
3332 r.in.rights = &rights;
3334 status = dcerpc_lsa_AddAccountRights(lp, tctx, &r);
3335 torture_assert_ntstatus_ok(tctx, status,
3336 "Failed to add privileges");
3340 struct lsa_EnumAccounts r;
3341 uint32_t resume_handle = 0;
3342 struct lsa_SidArray lsa_sid_array;
3344 bool found_sid = false;
3346 torture_comment(tctx, "Testing LSA EnumAccounts\n");
3348 r.in.handle = lsa_handle;
3349 r.in.num_entries = 0x1000;
3350 r.in.resume_handle = &resume_handle;
3351 r.out.sids = &lsa_sid_array;
3352 r.out.resume_handle = &resume_handle;
3354 status = dcerpc_lsa_EnumAccounts(lp, tctx, &r);
3355 torture_assert_ntstatus_ok(tctx, status,
3356 "Failed to enum accounts");
3358 for (i=0; i < lsa_sid_array.num_sids; i++) {
3359 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
3364 torture_assert(tctx, found_sid,
3365 "failed to list privileged account");
3369 struct lsa_EnumAccountRights r;
3370 struct lsa_RightSet user_rights;
3372 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
3374 r.in.handle = lsa_handle;
3375 r.in.sid = user_sid;
3376 r.out.rights = &user_rights;
3378 status = dcerpc_lsa_EnumAccountRights(lp, tctx, &r);
3379 torture_assert_ntstatus_ok(tctx, status,
3380 "Failed to enum rights for account");
3382 if (user_rights.count < 1) {
3383 torture_warning(tctx, "failed to find newly added rights");
3389 struct lsa_OpenAccount r;
3391 torture_comment(tctx, "Testing LSA OpenAccount\n");
3393 r.in.handle = lsa_handle;
3394 r.in.sid = user_sid;
3395 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3396 r.out.acct_handle = &lsa_acct_handle;
3398 status = dcerpc_lsa_OpenAccount(lp, tctx, &r);
3399 torture_assert_ntstatus_ok(tctx, status,
3400 "Failed to open lsa account");
3404 struct lsa_GetSystemAccessAccount r;
3405 uint32_t access_mask;
3407 torture_comment(tctx, "Testing LSA GetSystemAccessAccount\n");
3409 r.in.handle = &lsa_acct_handle;
3410 r.out.access_mask = &access_mask;
3412 status = dcerpc_lsa_GetSystemAccessAccount(lp, tctx, &r);
3413 torture_assert_ntstatus_ok(tctx, status,
3414 "Failed to get lsa system access account");
3420 torture_comment(tctx, "Testing LSA Close\n");
3422 r.in.handle = &lsa_acct_handle;
3423 r.out.handle = &lsa_acct_handle;
3425 status = dcerpc_lsa_Close(lp, tctx, &r);
3426 torture_assert_ntstatus_ok(tctx, status,
3427 "Failed to close lsa");
3431 struct samr_DeleteUser r;
3433 torture_comment(tctx, "Testing SAMR DeleteUser\n");
3435 r.in.user_handle = user_handle;
3436 r.out.user_handle = user_handle;
3438 status = dcerpc_samr_DeleteUser(p, tctx, &r);
3439 torture_assert_ntstatus_ok(tctx, status, "Delete User failed");
3443 struct lsa_EnumAccounts r;
3444 uint32_t resume_handle = 0;
3445 struct lsa_SidArray lsa_sid_array;
3447 bool found_sid = false;
3449 torture_comment(tctx, "Testing LSA EnumAccounts\n");
3451 r.in.handle = lsa_handle;
3452 r.in.num_entries = 0x1000;
3453 r.in.resume_handle = &resume_handle;
3454 r.out.sids = &lsa_sid_array;
3455 r.out.resume_handle = &resume_handle;
3457 status = dcerpc_lsa_EnumAccounts(lp, tctx, &r);
3458 torture_assert_ntstatus_ok(tctx, status,
3459 "Failed to enum accounts");
3461 for (i=0; i < lsa_sid_array.num_sids; i++) {
3462 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
3467 torture_assert(tctx, found_sid,
3468 "failed to list privileged account");
3472 struct lsa_EnumAccountRights r;
3473 struct lsa_RightSet user_rights;
3475 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
3477 r.in.handle = lsa_handle;
3478 r.in.sid = user_sid;
3479 r.out.rights = &user_rights;
3481 status = dcerpc_lsa_EnumAccountRights(lp, tctx, &r);
3482 torture_assert_ntstatus_ok(tctx, status,
3483 "Failed to enum rights for account");
3485 if (user_rights.count < 1) {
3486 torture_warning(tctx, "failed to find newly added rights");
3492 struct lsa_OpenAccount r;
3494 torture_comment(tctx, "Testing LSA OpenAccount\n");
3496 r.in.handle = lsa_handle;
3497 r.in.sid = user_sid;
3498 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3499 r.out.acct_handle = &lsa_acct_handle;
3501 status = dcerpc_lsa_OpenAccount(lp, tctx, &r);
3502 torture_assert_ntstatus_ok(tctx, status,
3503 "Failed to open lsa account");
3507 struct lsa_GetSystemAccessAccount r;
3508 uint32_t access_mask;
3510 torture_comment(tctx, "Testing LSA GetSystemAccessAccount\n");
3512 r.in.handle = &lsa_acct_handle;
3513 r.out.access_mask = &access_mask;
3515 status = dcerpc_lsa_GetSystemAccessAccount(lp, tctx, &r);
3516 torture_assert_ntstatus_ok(tctx, status,
3517 "Failed to get lsa system access account");
3521 struct lsa_DeleteObject r;
3523 torture_comment(tctx, "Testing LSA DeleteObject\n");
3525 r.in.handle = &lsa_acct_handle;
3526 r.out.handle = &lsa_acct_handle;
3528 status = dcerpc_lsa_DeleteObject(lp, tctx, &r);
3529 torture_assert_ntstatus_ok(tctx, status,
3530 "Failed to delete object");
3534 struct lsa_EnumAccounts r;
3535 uint32_t resume_handle = 0;
3536 struct lsa_SidArray lsa_sid_array;
3538 bool found_sid = false;
3540 torture_comment(tctx, "Testing LSA EnumAccounts\n");
3542 r.in.handle = lsa_handle;
3543 r.in.num_entries = 0x1000;
3544 r.in.resume_handle = &resume_handle;
3545 r.out.sids = &lsa_sid_array;
3546 r.out.resume_handle = &resume_handle;
3548 status = dcerpc_lsa_EnumAccounts(lp, tctx, &r);
3549 torture_assert_ntstatus_ok(tctx, status,
3550 "Failed to enum accounts");
3552 for (i=0; i < lsa_sid_array.num_sids; i++) {
3553 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
3558 torture_assert(tctx, !found_sid,
3559 "should not have listed privileged account");
3563 struct lsa_EnumAccountRights r;
3564 struct lsa_RightSet user_rights;
3566 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
3568 r.in.handle = lsa_handle;
3569 r.in.sid = user_sid;
3570 r.out.rights = &user_rights;
3572 status = dcerpc_lsa_EnumAccountRights(lp, tctx, &r);
3573 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3574 "Failed to enum rights for account");
3580 static bool test_user_ops(struct dcerpc_pipe *p,
3581 struct torture_context *tctx,
3582 struct policy_handle *user_handle,
3583 struct policy_handle *domain_handle,
3584 const struct dom_sid *domain_sid,
3585 uint32_t base_acct_flags,
3586 const char *base_acct_name, enum torture_samr_choice which_ops,
3587 struct cli_credentials *machine_credentials)
3589 char *password = NULL;
3590 struct samr_QueryUserInfo q;
3591 union samr_UserInfo *info;
3597 const uint32_t password_fields[] = {
3598 SAMR_FIELD_NT_PASSWORD_PRESENT,
3599 SAMR_FIELD_LM_PASSWORD_PRESENT,
3600 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
3604 status = test_LookupName(p, tctx, domain_handle, base_acct_name, &rid);
3605 if (!NT_STATUS_IS_OK(status)) {
3609 switch (which_ops) {
3610 case TORTURE_SAMR_USER_ATTRIBUTES:
3611 if (!test_QuerySecurity(p, tctx, user_handle)) {
3615 if (!test_QueryUserInfo(p, tctx, user_handle)) {
3619 if (!test_QueryUserInfo2(p, tctx, user_handle)) {
3623 if (!test_SetUserInfo(p, tctx, user_handle, base_acct_flags,
3628 if (!test_GetUserPwInfo(p, tctx, user_handle)) {
3632 if (!test_TestPrivateFunctionsUser(p, tctx, user_handle)) {
3636 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
3640 case TORTURE_SAMR_PASSWORDS:
3641 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
3642 char simple_pass[9];
3643 char *v = generate_random_str(tctx, 1);
3645 ZERO_STRUCT(simple_pass);
3646 memset(simple_pass, *v, sizeof(simple_pass) - 1);
3648 printf("Testing machine account password policy rules\n");
3650 /* Workstation trust accounts don't seem to need to honour password quality policy */
3651 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
3655 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
3659 /* reset again, to allow another 'user' password change */
3660 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
3664 /* Try a 'short' password */
3665 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
3669 /* Try a compleatly random password */
3670 if (!test_ChangePasswordRandomBytes(p, tctx, base_acct_name, user_handle, &password)) {
3675 for (i = 0; password_fields[i]; i++) {
3676 if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
3680 /* check it was set right */
3681 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3686 for (i = 0; password_fields[i]; i++) {
3687 if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
3691 /* check it was set right */
3692 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3697 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
3701 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
3705 if (torture_setting_bool(tctx, "samba4", false)) {
3706 printf("skipping Set Password level 18 and 21 against Samba4\n");
3709 if (!test_SetUserPass_18(p, tctx, user_handle, &password)) {
3713 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3717 for (i = 0; password_fields[i]; i++) {
3719 if (password_fields[i] == SAMR_FIELD_LM_PASSWORD_PRESENT) {
3720 /* we need to skip as that would break
3721 * the ChangePasswordUser3 verify */
3725 if (!test_SetUserPass_21(p, tctx, user_handle, password_fields[i], &password)) {
3729 /* check it was set right */
3730 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3736 q.in.user_handle = user_handle;
3740 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
3741 if (!NT_STATUS_IS_OK(status)) {
3742 printf("QueryUserInfo level %u failed - %s\n",
3743 q.in.level, nt_errstr(status));
3746 uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
3747 if ((info->info5.acct_flags) != expected_flags) {
3748 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
3749 info->info5.acct_flags,
3752 if (!torture_setting_bool(tctx, "samba3", false)) {
3756 if (info->info5.rid != rid) {
3757 printf("QuerUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
3758 info->info5.rid, rid);
3765 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
3767 /* test last password change timestamp behaviour */
3768 if (!test_SetPassword_pwdlastset(p, tctx, base_acct_flags,
3770 user_handle, &password,
3771 machine_credentials)) {
3776 torture_comment(tctx, "pwdLastSet test succeeded\n");
3778 torture_warning(tctx, "pwdLastSet test failed\n");
3783 case TORTURE_SAMR_USER_PRIVILEGES: {
3785 struct dcerpc_pipe *lp;
3786 struct policy_handle *lsa_handle;
3788 status = torture_rpc_connection(tctx, &lp, &ndr_table_lsarpc);
3789 torture_assert_ntstatus_ok(tctx, status, "Failed to open LSA pipe");
3791 if (!test_lsa_OpenPolicy2(lp, tctx, &lsa_handle)) {
3795 if (!test_DeleteUser_with_privs(p, lp, tctx,
3796 domain_handle, lsa_handle, user_handle,
3798 machine_credentials)) {
3802 if (!test_lsa_Close(lp, tctx, lsa_handle)) {
3807 torture_warning(tctx, "privileged user delete test failed\n");
3812 case TORTURE_SAMR_OTHER:
3813 /* We just need the account to exist */
3819 static bool test_alias_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
3820 struct policy_handle *alias_handle,
3821 const struct dom_sid *domain_sid)
3825 if (!torture_setting_bool(tctx, "samba3", false)) {
3826 if (!test_QuerySecurity(p, tctx, alias_handle)) {
3831 if (!test_QueryAliasInfo(p, tctx, alias_handle)) {
3835 if (!test_SetAliasInfo(p, tctx, alias_handle)) {
3839 if (!test_AddMemberToAlias(p, tctx, alias_handle, domain_sid)) {
3843 if (torture_setting_bool(tctx, "samba3", false) ||
3844 torture_setting_bool(tctx, "samba4", false)) {
3845 printf("skipping MultipleMembers Alias tests against Samba\n");
3849 if (!test_AddMultipleMembersToAlias(p, tctx, alias_handle)) {
3857 static bool test_DeleteUser(struct dcerpc_pipe *p, struct torture_context *tctx,
3858 struct policy_handle *user_handle)
3860 struct samr_DeleteUser d;
3862 torture_comment(tctx, "Testing DeleteUser\n");
3864 d.in.user_handle = user_handle;
3865 d.out.user_handle = user_handle;
3867 status = dcerpc_samr_DeleteUser(p, tctx, &d);
3868 torture_assert_ntstatus_ok(tctx, status, "DeleteUser");
3873 bool test_DeleteUser_byname(struct dcerpc_pipe *p,
3874 struct torture_context *tctx,
3875 struct policy_handle *handle, const char *name)
3878 struct samr_DeleteUser d;
3879 struct policy_handle user_handle;
3882 status = test_LookupName(p, tctx, handle, name, &rid);
3883 if (!NT_STATUS_IS_OK(status)) {
3887 status = test_OpenUser_byname(p, tctx, handle, name, &user_handle);
3888 if (!NT_STATUS_IS_OK(status)) {
3892 d.in.user_handle = &user_handle;
3893 d.out.user_handle = &user_handle;
3894 status = dcerpc_samr_DeleteUser(p, tctx, &d);
3895 if (!NT_STATUS_IS_OK(status)) {
3902 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
3907 static bool test_DeleteGroup_byname(struct dcerpc_pipe *p,
3908 struct torture_context *tctx,
3909 struct policy_handle *handle, const char *name)
3912 struct samr_OpenGroup r;
3913 struct samr_DeleteDomainGroup d;
3914 struct policy_handle group_handle;
3917 status = test_LookupName(p, tctx, handle, name, &rid);
3918 if (!NT_STATUS_IS_OK(status)) {
3922 r.in.domain_handle = handle;
3923 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3925 r.out.group_handle = &group_handle;
3926 status = dcerpc_samr_OpenGroup(p, tctx, &r);
3927 if (!NT_STATUS_IS_OK(status)) {
3931 d.in.group_handle = &group_handle;
3932 d.out.group_handle = &group_handle;
3933 status = dcerpc_samr_DeleteDomainGroup(p, tctx, &d);
3934 if (!NT_STATUS_IS_OK(status)) {
3941 printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
3946 static bool test_DeleteAlias_byname(struct dcerpc_pipe *p,
3947 struct torture_context *tctx,
3948 struct policy_handle *domain_handle,
3952 struct samr_OpenAlias r;
3953 struct samr_DeleteDomAlias d;
3954 struct policy_handle alias_handle;
3957 printf("testing DeleteAlias_byname\n");
3959 status = test_LookupName(p, tctx, domain_handle, name, &rid);
3960 if (!NT_STATUS_IS_OK(status)) {
3964 r.in.domain_handle = domain_handle;
3965 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3967 r.out.alias_handle = &alias_handle;
3968 status = dcerpc_samr_OpenAlias(p, tctx, &r);
3969 if (!NT_STATUS_IS_OK(status)) {
3973 d.in.alias_handle = &alias_handle;
3974 d.out.alias_handle = &alias_handle;
3975 status = dcerpc_samr_DeleteDomAlias(p, tctx, &d);
3976 if (!NT_STATUS_IS_OK(status)) {
3983 printf("DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
3987 static bool test_DeleteAlias(struct dcerpc_pipe *p,
3988 struct torture_context *tctx,
3989 struct policy_handle *alias_handle)
3991 struct samr_DeleteDomAlias d;
3994 printf("Testing DeleteAlias\n");
3996 d.in.alias_handle = alias_handle;
3997 d.out.alias_handle = alias_handle;
3999 status = dcerpc_samr_DeleteDomAlias(p, tctx, &d);
4000 if (!NT_STATUS_IS_OK(status)) {
4001 printf("DeleteAlias failed - %s\n", nt_errstr(status));
4008 static bool test_CreateAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
4009 struct policy_handle *domain_handle,
4010 const char *alias_name,
4011 struct policy_handle *alias_handle,
4012 const struct dom_sid *domain_sid,
4016 struct samr_CreateDomAlias r;
4017 struct lsa_String name;
4021 init_lsa_String(&name, alias_name);
4022 r.in.domain_handle = domain_handle;
4023 r.in.alias_name = &name;
4024 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4025 r.out.alias_handle = alias_handle;
4028 printf("Testing CreateAlias (%s)\n", r.in.alias_name->string);
4030 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
4032 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
4033 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
4034 printf("Server correctly refused create of '%s'\n", r.in.alias_name->string);
4037 printf("Server should have refused create of '%s', got %s instead\n", r.in.alias_name->string,
4043 if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
4044 if (!test_DeleteAlias_byname(p, tctx, domain_handle, r.in.alias_name->string)) {
4047 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
4050 if (!NT_STATUS_IS_OK(status)) {
4051 printf("CreateAlias failed - %s\n", nt_errstr(status));
4059 if (!test_alias_ops(p, tctx, alias_handle, domain_sid)) {
4066 static bool test_ChangePassword(struct dcerpc_pipe *p,
4067 struct torture_context *tctx,
4068 const char *acct_name,
4069 struct policy_handle *domain_handle, char **password)
4077 if (!test_ChangePasswordUser(p, tctx, acct_name, domain_handle, password)) {
4081 if (!test_ChangePasswordUser2(p, tctx, acct_name, password, 0, true)) {
4085 if (!test_OemChangePasswordUser2(p, tctx, acct_name, domain_handle, password)) {
4089 /* test what happens when setting the old password again */
4090 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, *password, 0, true)) {
4095 char simple_pass[9];
4096 char *v = generate_random_str(tctx, 1);
4098 ZERO_STRUCT(simple_pass);
4099 memset(simple_pass, *v, sizeof(simple_pass) - 1);
4101 /* test what happens when picking a simple password */
4102 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, simple_pass, 0, true)) {
4107 /* set samr_SetDomainInfo level 1 with min_length 5 */
4109 struct samr_QueryDomainInfo r;
4110 union samr_DomainInfo *info = NULL;
4111 struct samr_SetDomainInfo s;
4112 uint16_t len_old, len;
4113 uint32_t pwd_prop_old;
4114 int64_t min_pwd_age_old;
4119 r.in.domain_handle = domain_handle;
4123 printf("testing samr_QueryDomainInfo level 1\n");
4124 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
4125 if (!NT_STATUS_IS_OK(status)) {
4129 s.in.domain_handle = domain_handle;
4133 /* remember the old min length, so we can reset it */
4134 len_old = s.in.info->info1.min_password_length;
4135 s.in.info->info1.min_password_length = len;
4136 pwd_prop_old = s.in.info->info1.password_properties;
4137 /* turn off password complexity checks for this test */
4138 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
4140 min_pwd_age_old = s.in.info->info1.min_password_age;
4141 s.in.info->info1.min_password_age = 0;
4143 printf("testing samr_SetDomainInfo level 1\n");
4144 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
4145 if (!NT_STATUS_IS_OK(status)) {
4149 printf("calling test_ChangePasswordUser3 with too short password\n");
4151 if (!test_ChangePasswordUser3(p, tctx, acct_name, len - 1, password, NULL, 0, true)) {
4155 s.in.info->info1.min_password_length = len_old;
4156 s.in.info->info1.password_properties = pwd_prop_old;
4157 s.in.info->info1.min_password_age = min_pwd_age_old;
4159 printf("testing samr_SetDomainInfo level 1\n");
4160 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
4161 if (!NT_STATUS_IS_OK(status)) {
4169 struct samr_OpenUser r;
4170 struct samr_QueryUserInfo q;
4171 union samr_UserInfo *info;
4172 struct samr_LookupNames n;
4173 struct policy_handle user_handle;
4174 struct samr_Ids rids, types;
4176 n.in.domain_handle = domain_handle;
4178 n.in.names = talloc_array(tctx, struct lsa_String, 1);
4179 n.in.names[0].string = acct_name;
4181 n.out.types = &types;
4183 status = dcerpc_samr_LookupNames(p, tctx, &n);
4184 if (!NT_STATUS_IS_OK(status)) {
4185 printf("LookupNames failed - %s\n", nt_errstr(status));
4189 r.in.domain_handle = domain_handle;
4190 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4191 r.in.rid = n.out.rids->ids[0];
4192 r.out.user_handle = &user_handle;
4194 status = dcerpc_samr_OpenUser(p, tctx, &r);
4195 if (!NT_STATUS_IS_OK(status)) {
4196 printf("OpenUser(%u) failed - %s\n", n.out.rids->ids[0], nt_errstr(status));
4200 q.in.user_handle = &user_handle;
4204 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
4205 if (!NT_STATUS_IS_OK(status)) {
4206 printf("QueryUserInfo failed - %s\n", nt_errstr(status));
4210 printf("calling test_ChangePasswordUser3 with too early password change\n");
4212 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL,
4213 info->info5.last_password_change, true)) {
4218 /* we change passwords twice - this has the effect of verifying
4219 they were changed correctly for the final call */
4220 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
4224 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
4231 static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
4232 struct policy_handle *domain_handle,
4233 const char *user_name,
4234 struct policy_handle *user_handle_out,
4235 struct dom_sid *domain_sid,
4236 enum torture_samr_choice which_ops,
4237 struct cli_credentials *machine_credentials,
4241 TALLOC_CTX *user_ctx;
4244 struct samr_CreateUser r;
4245 struct samr_QueryUserInfo q;
4246 union samr_UserInfo *info;
4247 struct samr_DeleteUser d;
4250 /* This call creates a 'normal' account - check that it really does */
4251 const uint32_t acct_flags = ACB_NORMAL;
4252 struct lsa_String name;
4255 struct policy_handle user_handle;
4256 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
4257 init_lsa_String(&name, user_name);
4259 r.in.domain_handle = domain_handle;
4260 r.in.account_name = &name;
4261 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4262 r.out.user_handle = &user_handle;
4265 printf("Testing CreateUser(%s)\n", r.in.account_name->string);
4267 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
4269 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
4270 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
4271 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
4274 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
4280 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
4281 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
4282 talloc_free(user_ctx);
4285 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
4288 if (!NT_STATUS_IS_OK(status)) {
4289 talloc_free(user_ctx);
4290 printf("CreateUser failed - %s\n", nt_errstr(status));
4295 if (user_handle_out) {
4296 *user_handle_out = user_handle;
4302 q.in.user_handle = &user_handle;
4306 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
4307 if (!NT_STATUS_IS_OK(status)) {
4308 printf("QueryUserInfo level %u failed - %s\n",
4309 q.in.level, nt_errstr(status));
4312 if ((info->info16.acct_flags & acct_flags) != acct_flags) {
4313 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
4314 info->info16.acct_flags,
4320 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
4321 domain_sid, acct_flags, name.string, which_ops,
4322 machine_credentials)) {
4326 if (user_handle_out) {
4327 *user_handle_out = user_handle;
4329 printf("Testing DeleteUser (createuser test)\n");
4331 d.in.user_handle = &user_handle;
4332 d.out.user_handle = &user_handle;
4334 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
4335 if (!NT_STATUS_IS_OK(status)) {
4336 printf("DeleteUser failed - %s\n", nt_errstr(status));
4343 talloc_free(user_ctx);
4349 static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
4350 struct policy_handle *domain_handle,
4351 struct dom_sid *domain_sid,
4352 enum torture_samr_choice which_ops,
4353 struct cli_credentials *machine_credentials)
4356 struct samr_CreateUser2 r;
4357 struct samr_QueryUserInfo q;
4358 union samr_UserInfo *info;
4359 struct samr_DeleteUser d;
4360 struct policy_handle user_handle;
4362 struct lsa_String name;
4367 uint32_t acct_flags;
4368 const char *account_name;
4370 } account_types[] = {
4371 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
4372 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
4373 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
4374 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
4375 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
4376 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
4377 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
4378 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
4379 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
4380 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_ACCESS_DENIED },
4381 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
4382 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
4383 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
4384 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
4385 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
4388 for (i = 0; account_types[i].account_name; i++) {
4389 TALLOC_CTX *user_ctx;
4390 uint32_t acct_flags = account_types[i].acct_flags;
4391 uint32_t access_granted;
4392 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
4393 init_lsa_String(&name, account_types[i].account_name);
4395 r.in.domain_handle = domain_handle;
4396 r.in.account_name = &name;
4397 r.in.acct_flags = acct_flags;
4398 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4399 r.out.user_handle = &user_handle;
4400 r.out.access_granted = &access_granted;
4403 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
4405 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
4407 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
4408 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
4409 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
4412 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
4419 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
4420 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
4421 talloc_free(user_ctx);
4425 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
4428 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
4429 printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
4430 nt_errstr(status), nt_errstr(account_types[i].nt_status));
4434 if (NT_STATUS_IS_OK(status)) {
4435 q.in.user_handle = &user_handle;
4439 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
4440 if (!NT_STATUS_IS_OK(status)) {
4441 printf("QueryUserInfo level %u failed - %s\n",
4442 q.in.level, nt_errstr(status));
4445 uint32_t expected_flags = (acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
4446 if (acct_flags == ACB_NORMAL) {
4447 expected_flags |= ACB_PW_EXPIRED;
4449 if ((info->info5.acct_flags) != expected_flags) {
4450 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
4451 info->info5.acct_flags,
4455 switch (acct_flags) {
4457 if (info->info5.primary_gid != DOMAIN_RID_DCS) {
4458 printf("QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n",
4459 DOMAIN_RID_DCS, info->info5.primary_gid);
4464 if (info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
4465 printf("QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
4466 DOMAIN_RID_DOMAIN_MEMBERS, info->info5.primary_gid);
4471 if (info->info5.primary_gid != DOMAIN_RID_USERS) {
4472 printf("QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n",
4473 DOMAIN_RID_USERS, info->info5.primary_gid);
4480 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
4481 domain_sid, acct_flags, name.string, which_ops,
4482 machine_credentials)) {
4486 if (!policy_handle_empty(&user_handle)) {
4487 printf("Testing DeleteUser (createuser2 test)\n");
4489 d.in.user_handle = &user_handle;
4490 d.out.user_handle = &user_handle;
4492 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
4493 if (!NT_STATUS_IS_OK(status)) {
4494 printf("DeleteUser failed - %s\n", nt_errstr(status));
4499 talloc_free(user_ctx);
4505 static bool test_QueryAliasInfo(struct dcerpc_pipe *p,
4506 struct torture_context *tctx,
4507 struct policy_handle *handle)
4510 struct samr_QueryAliasInfo r;
4511 union samr_AliasInfo *info;
4512 uint16_t levels[] = {1, 2, 3};
4516 for (i=0;i<ARRAY_SIZE(levels);i++) {
4517 printf("Testing QueryAliasInfo level %u\n", levels[i]);
4519 r.in.alias_handle = handle;
4520 r.in.level = levels[i];
4523 status = dcerpc_samr_QueryAliasInfo(p, tctx, &r);
4524 if (!NT_STATUS_IS_OK(status)) {
4525 printf("QueryAliasInfo level %u failed - %s\n",
4526 levels[i], nt_errstr(status));
4534 static bool test_QueryGroupInfo(struct dcerpc_pipe *p,
4535 struct torture_context *tctx,
4536 struct policy_handle *handle)
4539 struct samr_QueryGroupInfo r;
4540 union samr_GroupInfo *info;
4541 uint16_t levels[] = {1, 2, 3, 4, 5};
4545 for (i=0;i<ARRAY_SIZE(levels);i++) {
4546 printf("Testing QueryGroupInfo level %u\n", levels[i]);
4548 r.in.group_handle = handle;
4549 r.in.level = levels[i];
4552 status = dcerpc_samr_QueryGroupInfo(p, tctx, &r);
4553 if (!NT_STATUS_IS_OK(status)) {
4554 printf("QueryGroupInfo level %u failed - %s\n",
4555 levels[i], nt_errstr(status));
4563 static bool test_QueryGroupMember(struct dcerpc_pipe *p,
4564 struct torture_context *tctx,
4565 struct policy_handle *handle)
4568 struct samr_QueryGroupMember r;
4569 struct samr_RidTypeArray *rids = NULL;
4572 printf("Testing QueryGroupMember\n");
4574 r.in.group_handle = handle;
4577 status = dcerpc_samr_QueryGroupMember(p, tctx, &r);
4578 if (!NT_STATUS_IS_OK(status)) {
4579 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
4587 static bool test_SetGroupInfo(struct dcerpc_pipe *p,
4588 struct torture_context *tctx,
4589 struct policy_handle *handle)
4592 struct samr_QueryGroupInfo r;
4593 union samr_GroupInfo *info;
4594 struct samr_SetGroupInfo s;
4595 uint16_t levels[] = {1, 2, 3, 4};
4596 uint16_t set_ok[] = {0, 1, 1, 1};
4600 for (i=0;i<ARRAY_SIZE(levels);i++) {
4601 printf("Testing QueryGroupInfo level %u\n", levels[i]);
4603 r.in.group_handle = handle;
4604 r.in.level = levels[i];
4607 status = dcerpc_samr_QueryGroupInfo(p, tctx, &r);
4608 if (!NT_STATUS_IS_OK(status)) {
4609 printf("QueryGroupInfo level %u failed - %s\n",
4610 levels[i], nt_errstr(status));
4614 printf("Testing SetGroupInfo level %u\n", levels[i]);
4616 s.in.group_handle = handle;
4617 s.in.level = levels[i];
4618 s.in.info = *r.out.info;
4621 /* disabled this, as it changes the name only from the point of view of samr,
4622 but leaves the name from the point of view of w2k3 internals (and ldap). This means
4623 the name is still reserved, so creating the old name fails, but deleting by the old name
4625 if (s.in.level == 2) {
4626 init_lsa_String(&s.in.info->string, "NewName");
4630 if (s.in.level == 4) {
4631 init_lsa_String(&s.in.info->description, "test description");
4634 status = dcerpc_samr_SetGroupInfo(p, tctx, &s);
4636 if (!NT_STATUS_IS_OK(status)) {
4637 printf("SetGroupInfo level %u failed - %s\n",
4638 r.in.level, nt_errstr(status));
4643 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
4644 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
4645 r.in.level, nt_errstr(status));
4655 static bool test_QueryUserInfo(struct dcerpc_pipe *p,
4656 struct torture_context *tctx,
4657 struct policy_handle *handle)
4660 struct samr_QueryUserInfo r;
4661 union samr_UserInfo *info;
4662 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
4663 11, 12, 13, 14, 16, 17, 20, 21};
4667 for (i=0;i<ARRAY_SIZE(levels);i++) {
4668 printf("Testing QueryUserInfo level %u\n", levels[i]);
4670 r.in.user_handle = handle;
4671 r.in.level = levels[i];
4674 status = dcerpc_samr_QueryUserInfo(p, tctx, &r);
4675 if (!NT_STATUS_IS_OK(status)) {
4676 printf("QueryUserInfo level %u failed - %s\n",
4677 levels[i], nt_errstr(status));
4685 static bool test_QueryUserInfo2(struct dcerpc_pipe *p,
4686 struct torture_context *tctx,
4687 struct policy_handle *handle)
4690 struct samr_QueryUserInfo2 r;
4691 union samr_UserInfo *info;
4692 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
4693 11, 12, 13, 14, 16, 17, 20, 21};
4697 for (i=0;i<ARRAY_SIZE(levels);i++) {
4698 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
4700 r.in.user_handle = handle;
4701 r.in.level = levels[i];
4704 status = dcerpc_samr_QueryUserInfo2(p, tctx, &r);
4705 if (!NT_STATUS_IS_OK(status)) {
4706 printf("QueryUserInfo2 level %u failed - %s\n",
4707 levels[i], nt_errstr(status));
4715 static bool test_OpenUser(struct dcerpc_pipe *p,
4716 struct torture_context *tctx,
4717 struct policy_handle *handle, uint32_t rid)
4720 struct samr_OpenUser r;
4721 struct policy_handle user_handle;
4724 printf("Testing OpenUser(%u)\n", rid);
4726 r.in.domain_handle = handle;
4727 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4729 r.out.user_handle = &user_handle;
4731 status = dcerpc_samr_OpenUser(p, tctx, &r);
4732 if (!NT_STATUS_IS_OK(status)) {
4733 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
4737 if (!test_QuerySecurity(p, tctx, &user_handle)) {
4741 if (!test_QueryUserInfo(p, tctx, &user_handle)) {
4745 if (!test_QueryUserInfo2(p, tctx, &user_handle)) {
4749 if (!test_GetUserPwInfo(p, tctx, &user_handle)) {
4753 if (!test_GetGroupsForUser(p,tctx, &user_handle)) {
4757 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
4764 static bool test_OpenGroup(struct dcerpc_pipe *p,
4765 struct torture_context *tctx,
4766 struct policy_handle *handle, uint32_t rid)
4769 struct samr_OpenGroup r;
4770 struct policy_handle group_handle;
4773 printf("Testing OpenGroup(%u)\n", rid);
4775 r.in.domain_handle = handle;
4776 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4778 r.out.group_handle = &group_handle;
4780 status = dcerpc_samr_OpenGroup(p, tctx, &r);
4781 if (!NT_STATUS_IS_OK(status)) {
4782 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
4786 if (!torture_setting_bool(tctx, "samba3", false)) {
4787 if (!test_QuerySecurity(p, tctx, &group_handle)) {
4792 if (!test_QueryGroupInfo(p, tctx, &group_handle)) {
4796 if (!test_QueryGroupMember(p, tctx, &group_handle)) {
4800 if (!test_samr_handle_Close(p, tctx, &group_handle)) {
4807 static bool test_OpenAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
4808 struct policy_handle *handle, uint32_t rid)
4811 struct samr_OpenAlias r;
4812 struct policy_handle alias_handle;
4815 torture_comment(tctx, "Testing OpenAlias(%u)\n", rid);
4817 r.in.domain_handle = handle;
4818 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4820 r.out.alias_handle = &alias_handle;
4822 status = dcerpc_samr_OpenAlias(p, tctx, &r);
4823 if (!NT_STATUS_IS_OK(status)) {
4824 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
4828 if (!torture_setting_bool(tctx, "samba3", false)) {
4829 if (!test_QuerySecurity(p, tctx, &alias_handle)) {
4834 if (!test_QueryAliasInfo(p, tctx, &alias_handle)) {
4838 if (!test_GetMembersInAlias(p, tctx, &alias_handle)) {
4842 if (!test_samr_handle_Close(p, tctx, &alias_handle)) {
4849 static bool check_mask(struct dcerpc_pipe *p, struct torture_context *tctx,
4850 struct policy_handle *handle, uint32_t rid,
4851 uint32_t acct_flag_mask)
4854 struct samr_OpenUser r;
4855 struct samr_QueryUserInfo q;
4856 union samr_UserInfo *info;
4857 struct policy_handle user_handle;
4860 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
4862 r.in.domain_handle = handle;
4863 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4865 r.out.user_handle = &user_handle;
4867 status = dcerpc_samr_OpenUser(p, tctx, &r);
4868 if (!NT_STATUS_IS_OK(status)) {
4869 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
4873 q.in.user_handle = &user_handle;
4877 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
4878 if (!NT_STATUS_IS_OK(status)) {
4879 printf("QueryUserInfo level 16 failed - %s\n",
4883 if ((acct_flag_mask & info->info16.acct_flags) == 0) {
4884 printf("Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
4885 acct_flag_mask, info->info16.acct_flags, rid);
4890 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
4897 static bool test_EnumDomainUsers_all(struct dcerpc_pipe *p,
4898 struct torture_context *tctx,
4899 struct policy_handle *handle)
4901 NTSTATUS status = STATUS_MORE_ENTRIES;
4902 struct samr_EnumDomainUsers r;
4903 uint32_t mask, resume_handle=0;
4906 struct samr_LookupNames n;
4907 struct samr_LookupRids lr ;
4908 struct lsa_Strings names;
4909 struct samr_Ids rids, types;
4910 struct samr_SamArray *sam = NULL;
4911 uint32_t num_entries = 0;
4913 uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
4914 ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
4915 ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
4918 printf("Testing EnumDomainUsers\n");
4920 for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
4921 r.in.domain_handle = handle;
4922 r.in.resume_handle = &resume_handle;
4923 r.in.acct_flags = mask = masks[mask_idx];
4924 r.in.max_size = (uint32_t)-1;
4925 r.out.resume_handle = &resume_handle;
4926 r.out.num_entries = &num_entries;
4929 status = dcerpc_samr_EnumDomainUsers(p, tctx, &r);
4930 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
4931 !NT_STATUS_IS_OK(status)) {
4932 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
4936 torture_assert(tctx, sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
4938 if (sam->count == 0) {
4942 for (i=0;i<sam->count;i++) {
4944 if (!check_mask(p, tctx, handle, sam->entries[i].idx, mask)) {
4947 } else if (!test_OpenUser(p, tctx, handle, sam->entries[i].idx)) {
4953 printf("Testing LookupNames\n");
4954 n.in.domain_handle = handle;
4955 n.in.num_names = sam->count;
4956 n.in.names = talloc_array(tctx, struct lsa_String, sam->count);
4958 n.out.types = &types;
4959 for (i=0;i<sam->count;i++) {
4960 n.in.names[i].string = sam->entries[i].name.string;
4962 status = dcerpc_samr_LookupNames(p, tctx, &n);
4963 if (!NT_STATUS_IS_OK(status)) {
4964 printf("LookupNames failed - %s\n", nt_errstr(status));
4969 printf("Testing LookupRids\n");
4970 lr.in.domain_handle = handle;
4971 lr.in.num_rids = sam->count;
4972 lr.in.rids = talloc_array(tctx, uint32_t, sam->count);
4973 lr.out.names = &names;
4974 lr.out.types = &types;
4975 for (i=0;i<sam->count;i++) {
4976 lr.in.rids[i] = sam->entries[i].idx;
4978 status = dcerpc_samr_LookupRids(p, tctx, &lr);
4979 torture_assert_ntstatus_ok(tctx, status, "LookupRids");
4985 try blasting the server with a bunch of sync requests
4987 static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, struct torture_context *tctx,
4988 struct policy_handle *handle)
4991 struct samr_EnumDomainUsers r;
4992 uint32_t resume_handle=0;
4994 #define ASYNC_COUNT 100
4995 struct rpc_request *req[ASYNC_COUNT];
4997 if (!torture_setting_bool(tctx, "dangerous", false)) {
4998 torture_skip(tctx, "samr async test disabled - enable dangerous tests to use\n");
5001 torture_comment(tctx, "Testing EnumDomainUsers_async\n");
5003 r.in.domain_handle = handle;
5004 r.in.resume_handle = &resume_handle;
5005 r.in.acct_flags = 0;
5006 r.in.max_size = (uint32_t)-1;
5007 r.out.resume_handle = &resume_handle;
5009 for (i=0;i<ASYNC_COUNT;i++) {
5010 req[i] = dcerpc_samr_EnumDomainUsers_send(p, tctx, &r);
5013 for (i=0;i<ASYNC_COUNT;i++) {
5014 status = dcerpc_ndr_request_recv(req[i]);
5015 if (!NT_STATUS_IS_OK(status)) {
5016 printf("EnumDomainUsers[%d] failed - %s\n",
5017 i, nt_errstr(status));
5022 torture_comment(tctx, "%d async requests OK\n", i);
5027 static bool test_EnumDomainGroups_all(struct dcerpc_pipe *p,
5028 struct torture_context *tctx,
5029 struct policy_handle *handle)
5032 struct samr_EnumDomainGroups r;
5033 uint32_t resume_handle=0;
5034 struct samr_SamArray *sam = NULL;
5035 uint32_t num_entries = 0;
5039 printf("Testing EnumDomainGroups\n");
5041 r.in.domain_handle = handle;
5042 r.in.resume_handle = &resume_handle;
5043 r.in.max_size = (uint32_t)-1;
5044 r.out.resume_handle = &resume_handle;
5045 r.out.num_entries = &num_entries;
5048 status = dcerpc_samr_EnumDomainGroups(p, tctx, &r);
5049 if (!NT_STATUS_IS_OK(status)) {
5050 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
5058 for (i=0;i<sam->count;i++) {
5059 if (!test_OpenGroup(p, tctx, handle, sam->entries[i].idx)) {
5067 static bool test_EnumDomainAliases_all(struct dcerpc_pipe *p,
5068 struct torture_context *tctx,
5069 struct policy_handle *handle)
5072 struct samr_EnumDomainAliases r;
5073 uint32_t resume_handle=0;
5074 struct samr_SamArray *sam = NULL;
5075 uint32_t num_entries = 0;
5079 printf("Testing EnumDomainAliases\n");
5081 r.in.domain_handle = handle;
5082 r.in.resume_handle = &resume_handle;
5083 r.in.max_size = (uint32_t)-1;
5085 r.out.num_entries = &num_entries;
5086 r.out.resume_handle = &resume_handle;
5088 status = dcerpc_samr_EnumDomainAliases(p, tctx, &r);
5089 if (!NT_STATUS_IS_OK(status)) {
5090 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
5098 for (i=0;i<sam->count;i++) {
5099 if (!test_OpenAlias(p, tctx, handle, sam->entries[i].idx)) {
5107 static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p,
5108 struct torture_context *tctx,
5109 struct policy_handle *handle)
5112 struct samr_GetDisplayEnumerationIndex r;
5114 uint16_t levels[] = {1, 2, 3, 4, 5};
5115 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
5116 struct lsa_String name;
5120 for (i=0;i<ARRAY_SIZE(levels);i++) {
5121 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
5123 init_lsa_String(&name, TEST_ACCOUNT_NAME);
5125 r.in.domain_handle = handle;
5126 r.in.level = levels[i];
5130 status = dcerpc_samr_GetDisplayEnumerationIndex(p, tctx, &r);
5133 !NT_STATUS_IS_OK(status) &&
5134 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
5135 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
5136 levels[i], nt_errstr(status));
5140 init_lsa_String(&name, "zzzzzzzz");
5142 status = dcerpc_samr_GetDisplayEnumerationIndex(p, tctx, &r);
5144 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
5145 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
5146 levels[i], nt_errstr(status));
5154 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p,
5155 struct torture_context *tctx,
5156 struct policy_handle *handle)
5159 struct samr_GetDisplayEnumerationIndex2 r;
5161 uint16_t levels[] = {1, 2, 3, 4, 5};
5162 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
5163 struct lsa_String name;
5167 for (i=0;i<ARRAY_SIZE(levels);i++) {
5168 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
5170 init_lsa_String(&name, TEST_ACCOUNT_NAME);
5172 r.in.domain_handle = handle;
5173 r.in.level = levels[i];
5177 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, tctx, &r);
5179 !NT_STATUS_IS_OK(status) &&
5180 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
5181 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
5182 levels[i], nt_errstr(status));
5186 init_lsa_String(&name, "zzzzzzzz");
5188 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, tctx, &r);
5189 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
5190 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
5191 levels[i], nt_errstr(status));
5199 #define STRING_EQUAL_QUERY(s1, s2, user) \
5200 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
5201 /* odd, but valid */ \
5202 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
5203 printf("%s mismatch for %s: %s != %s (%s)\n", \
5204 #s1, user.string, s1.string, s2.string, __location__); \
5207 #define INT_EQUAL_QUERY(s1, s2, user) \
5209 printf("%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
5210 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
5214 static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p,
5215 struct torture_context *tctx,
5216 struct samr_QueryDisplayInfo *querydisplayinfo,
5217 bool *seen_testuser)
5219 struct samr_OpenUser r;
5220 struct samr_QueryUserInfo q;
5221 union samr_UserInfo *info;
5222 struct policy_handle user_handle;
5225 r.in.domain_handle = querydisplayinfo->in.domain_handle;
5226 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5227 for (i = 0; ; i++) {
5228 switch (querydisplayinfo->in.level) {
5230 if (i >= querydisplayinfo->out.info->info1.count) {
5233 r.in.rid = querydisplayinfo->out.info->info1.entries[i].rid;
5236 if (i >= querydisplayinfo->out.info->info2.count) {
5239 r.in.rid = querydisplayinfo->out.info->info2.entries[i].rid;
5245 /* Not interested in validating just the account name */
5249 r.out.user_handle = &user_handle;
5251 switch (querydisplayinfo->in.level) {
5254 status = dcerpc_samr_OpenUser(p, tctx, &r);
5255 if (!NT_STATUS_IS_OK(status)) {
5256 printf("OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(status));
5261 q.in.user_handle = &user_handle;
5264 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
5265 if (!NT_STATUS_IS_OK(status)) {
5266 printf("QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(status));
5270 switch (querydisplayinfo->in.level) {
5272 if (seen_testuser && strcmp(info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
5273 *seen_testuser = true;
5275 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].full_name,
5276 info->info21.full_name, info->info21.account_name);
5277 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].account_name,
5278 info->info21.account_name, info->info21.account_name);
5279 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].description,
5280 info->info21.description, info->info21.account_name);
5281 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].rid,
5282 info->info21.rid, info->info21.account_name);
5283 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].acct_flags,
5284 info->info21.acct_flags, info->info21.account_name);
5288 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].account_name,
5289 info->info21.account_name, info->info21.account_name);
5290 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].description,
5291 info->info21.description, info->info21.account_name);
5292 INT_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].rid,
5293 info->info21.rid, info->info21.account_name);
5294 INT_EQUAL_QUERY((querydisplayinfo->out.info->info2.entries[i].acct_flags & ~ACB_NORMAL),
5295 info->info21.acct_flags, info->info21.account_name);
5297 if (!(querydisplayinfo->out.info->info2.entries[i].acct_flags & ACB_NORMAL)) {
5298 printf("Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
5299 info->info21.account_name.string);
5302 if (!(info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
5303 printf("Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
5304 info->info21.account_name.string,
5305 querydisplayinfo->out.info->info2.entries[i].acct_flags,
5306 info->info21.acct_flags);
5313 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
5320 static bool test_QueryDisplayInfo(struct dcerpc_pipe *p,
5321 struct torture_context *tctx,
5322 struct policy_handle *handle)
5325 struct samr_QueryDisplayInfo r;
5326 struct samr_QueryDomainInfo dom_info;
5327 union samr_DomainInfo *info = NULL;
5329 uint16_t levels[] = {1, 2, 3, 4, 5};
5331 bool seen_testuser = false;
5332 uint32_t total_size;
5333 uint32_t returned_size;
5334 union samr_DispInfo disp_info;
5337 for (i=0;i<ARRAY_SIZE(levels);i++) {
5338 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
5341 status = STATUS_MORE_ENTRIES;
5342 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
5343 r.in.domain_handle = handle;
5344 r.in.level = levels[i];
5345 r.in.max_entries = 2;
5346 r.in.buf_size = (uint32_t)-1;
5347 r.out.total_size = &total_size;
5348 r.out.returned_size = &returned_size;
5349 r.out.info = &disp_info;
5351 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &r);
5352 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(status)) {
5353 printf("QueryDisplayInfo level %u failed - %s\n",
5354 levels[i], nt_errstr(status));
5357 switch (r.in.level) {
5359 if (!test_each_DisplayInfo_user(p, tctx, &r, &seen_testuser)) {
5362 r.in.start_idx += r.out.info->info1.count;
5365 if (!test_each_DisplayInfo_user(p, tctx, &r, NULL)) {
5368 r.in.start_idx += r.out.info->info2.count;
5371 r.in.start_idx += r.out.info->info3.count;
5374 r.in.start_idx += r.out.info->info4.count;
5377 r.in.start_idx += r.out.info->info5.count;
5381 dom_info.in.domain_handle = handle;
5382 dom_info.in.level = 2;
5383 dom_info.out.info = &info;
5385 /* Check number of users returned is correct */
5386 status = dcerpc_samr_QueryDomainInfo(p, tctx, &dom_info);
5387 if (!NT_STATUS_IS_OK(status)) {
5388 printf("QueryDomainInfo level %u failed - %s\n",
5389 r.in.level, nt_errstr(status));
5393 switch (r.in.level) {
5396 if (info->general.num_users < r.in.start_idx) {
5397 printf("QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
5398 r.in.start_idx, info->general.num_groups,
5399 info->general.domain_name.string);
5402 if (!seen_testuser) {
5403 struct policy_handle user_handle;
5404 if (NT_STATUS_IS_OK(test_OpenUser_byname(p, tctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
5405 printf("Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
5406 info->general.domain_name.string);
5408 test_samr_handle_Close(p, tctx, &user_handle);
5414 if (info->general.num_groups != r.in.start_idx) {
5415 printf("QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
5416 r.in.start_idx, info->general.num_groups,
5417 info->general.domain_name.string);
5429 static bool test_QueryDisplayInfo2(struct dcerpc_pipe *p,
5430 struct torture_context *tctx,
5431 struct policy_handle *handle)
5434 struct samr_QueryDisplayInfo2 r;
5436 uint16_t levels[] = {1, 2, 3, 4, 5};
5438 uint32_t total_size;
5439 uint32_t returned_size;
5440 union samr_DispInfo info;
5442 for (i=0;i<ARRAY_SIZE(levels);i++) {
5443 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
5445 r.in.domain_handle = handle;
5446 r.in.level = levels[i];
5448 r.in.max_entries = 1000;
5449 r.in.buf_size = (uint32_t)-1;
5450 r.out.total_size = &total_size;
5451 r.out.returned_size = &returned_size;
5454 status = dcerpc_samr_QueryDisplayInfo2(p, tctx, &r);
5455 if (!NT_STATUS_IS_OK(status)) {
5456 printf("QueryDisplayInfo2 level %u failed - %s\n",
5457 levels[i], nt_errstr(status));
5465 static bool test_QueryDisplayInfo3(struct dcerpc_pipe *p, struct torture_context *tctx,
5466 struct policy_handle *handle)
5469 struct samr_QueryDisplayInfo3 r;
5471 uint16_t levels[] = {1, 2, 3, 4, 5};
5473 uint32_t total_size;
5474 uint32_t returned_size;
5475 union samr_DispInfo info;
5477 for (i=0;i<ARRAY_SIZE(levels);i++) {
5478 torture_comment(tctx, "Testing QueryDisplayInfo3 level %u\n", levels[i]);
5480 r.in.domain_handle = handle;
5481 r.in.level = levels[i];
5483 r.in.max_entries = 1000;
5484 r.in.buf_size = (uint32_t)-1;
5485 r.out.total_size = &total_size;
5486 r.out.returned_size = &returned_size;
5489 status = dcerpc_samr_QueryDisplayInfo3(p, tctx, &r);
5490 if (!NT_STATUS_IS_OK(status)) {
5491 printf("QueryDisplayInfo3 level %u failed - %s\n",
5492 levels[i], nt_errstr(status));
5501 static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p,
5502 struct torture_context *tctx,
5503 struct policy_handle *handle)
5506 struct samr_QueryDisplayInfo r;
5508 uint32_t total_size;
5509 uint32_t returned_size;
5510 union samr_DispInfo info;
5512 printf("Testing QueryDisplayInfo continuation\n");
5514 r.in.domain_handle = handle;
5517 r.in.max_entries = 1;
5518 r.in.buf_size = (uint32_t)-1;
5519 r.out.total_size = &total_size;
5520 r.out.returned_size = &returned_size;
5524 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &r);
5525 if (NT_STATUS_IS_OK(status) && *r.out.returned_size != 0) {
5526 if (r.out.info->info1.entries[0].idx != r.in.start_idx + 1) {
5527 printf("expected idx %d but got %d\n",
5529 r.out.info->info1.entries[0].idx);
5533 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
5534 !NT_STATUS_IS_OK(status)) {
5535 printf("QueryDisplayInfo level %u failed - %s\n",
5536 r.in.level, nt_errstr(status));
5541 } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
5542 NT_STATUS_IS_OK(status)) &&
5543 *r.out.returned_size != 0);
5548 static bool test_QueryDomainInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
5549 struct policy_handle *handle)
5552 struct samr_QueryDomainInfo r;
5553 union samr_DomainInfo *info = NULL;
5554 struct samr_SetDomainInfo s;
5555 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
5556 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
5559 const char *domain_comment = talloc_asprintf(tctx,
5560 "Tortured by Samba4 RPC-SAMR: %s",
5561 timestring(tctx, time(NULL)));
5563 s.in.domain_handle = handle;
5565 s.in.info = talloc(tctx, union samr_DomainInfo);
5567 s.in.info->oem.oem_information.string = domain_comment;
5568 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
5569 if (!NT_STATUS_IS_OK(status)) {
5570 printf("SetDomainInfo level %u (set comment) failed - %s\n",
5571 s.in.level, nt_errstr(status));
5575 for (i=0;i<ARRAY_SIZE(levels);i++) {
5576 torture_comment(tctx, "Testing QueryDomainInfo level %u\n", levels[i]);
5578 r.in.domain_handle = handle;
5579 r.in.level = levels[i];
5582 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
5583 if (!NT_STATUS_IS_OK(status)) {
5584 printf("QueryDomainInfo level %u failed - %s\n",
5585 r.in.level, nt_errstr(status));
5590 switch (levels[i]) {
5592 if (strcmp(info->general.oem_information.string, domain_comment) != 0) {
5593 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
5594 levels[i], info->general.oem_information.string, domain_comment);
5595 if (!torture_setting_bool(tctx, "samba3", false)) {
5599 if (!info->general.primary.string) {
5600 printf("QueryDomainInfo level %u returned no PDC name\n",
5603 } else if (info->general.role == SAMR_ROLE_DOMAIN_PDC) {
5604 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), info->general.primary.string) != 0) {
5605 printf("QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
5606 levels[i], info->general.primary.string, dcerpc_server_name(p));
5611 if (strcmp(info->oem.oem_information.string, domain_comment) != 0) {
5612 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
5613 levels[i], info->oem.oem_information.string, domain_comment);
5614 if (!torture_setting_bool(tctx, "samba3", false)) {
5620 if (!info->info6.primary.string) {
5621 printf("QueryDomainInfo level %u returned no PDC name\n",
5627 if (strcmp(info->general2.general.oem_information.string, domain_comment) != 0) {
5628 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
5629 levels[i], info->general2.general.oem_information.string, domain_comment);
5630 if (!torture_setting_bool(tctx, "samba3", false)) {
5637 torture_comment(tctx, "Testing SetDomainInfo level %u\n", levels[i]);
5639 s.in.domain_handle = handle;
5640 s.in.level = levels[i];
5643 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
5645 if (!NT_STATUS_IS_OK(status)) {
5646 printf("SetDomainInfo level %u failed - %s\n",
5647 r.in.level, nt_errstr(status));
5652 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
5653 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
5654 r.in.level, nt_errstr(status));
5660 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
5661 if (!NT_STATUS_IS_OK(status)) {
5662 printf("QueryDomainInfo level %u failed - %s\n",
5663 r.in.level, nt_errstr(status));
5673 static bool test_QueryDomainInfo2(struct dcerpc_pipe *p, struct torture_context *tctx,
5674 struct policy_handle *handle)
5677 struct samr_QueryDomainInfo2 r;
5678 union samr_DomainInfo *info = NULL;
5679 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
5683 for (i=0;i<ARRAY_SIZE(levels);i++) {
5684 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
5686 r.in.domain_handle = handle;
5687 r.in.level = levels[i];
5690 status = dcerpc_samr_QueryDomainInfo2(p, tctx, &r);
5691 if (!NT_STATUS_IS_OK(status)) {
5692 printf("QueryDomainInfo2 level %u failed - %s\n",
5693 r.in.level, nt_errstr(status));
5702 /* Test whether querydispinfo level 5 and enumdomgroups return the same
5703 set of group names. */
5704 static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx,
5705 struct policy_handle *handle)
5707 struct samr_EnumDomainGroups q1;
5708 struct samr_QueryDisplayInfo q2;
5710 uint32_t resume_handle=0;
5711 struct samr_SamArray *sam = NULL;
5712 uint32_t num_entries = 0;
5715 uint32_t total_size;
5716 uint32_t returned_size;
5717 union samr_DispInfo info;
5720 const char **names = NULL;
5722 torture_comment(tctx, "Testing coherency of querydispinfo vs enumdomgroups\n");
5724 q1.in.domain_handle = handle;
5725 q1.in.resume_handle = &resume_handle;
5727 q1.out.resume_handle = &resume_handle;
5728 q1.out.num_entries = &num_entries;
5731 status = STATUS_MORE_ENTRIES;
5732 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
5733 status = dcerpc_samr_EnumDomainGroups(p, tctx, &q1);
5735 if (!NT_STATUS_IS_OK(status) &&
5736 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
5739 for (i=0; i<*q1.out.num_entries; i++) {
5740 add_string_to_array(tctx,
5741 sam->entries[i].name.string,
5742 &names, &num_names);
5746 torture_assert_ntstatus_ok(tctx, status, "EnumDomainGroups");
5748 torture_assert(tctx, sam, "EnumDomainGroups failed to return sam");
5750 q2.in.domain_handle = handle;
5752 q2.in.start_idx = 0;
5753 q2.in.max_entries = 5;
5754 q2.in.buf_size = (uint32_t)-1;
5755 q2.out.total_size = &total_size;
5756 q2.out.returned_size = &returned_size;
5757 q2.out.info = &info;
5759 status = STATUS_MORE_ENTRIES;
5760 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
5761 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &q2);
5763 if (!NT_STATUS_IS_OK(status) &&
5764 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
5767 for (i=0; i<q2.out.info->info5.count; i++) {
5769 const char *name = q2.out.info->info5.entries[i].account_name.string;
5771 for (j=0; j<num_names; j++) {
5772 if (names[j] == NULL)
5774 if (strequal(names[j], name)) {
5782 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
5787 q2.in.start_idx += q2.out.info->info5.count;
5790 if (!NT_STATUS_IS_OK(status)) {
5791 printf("QueryDisplayInfo level 5 failed - %s\n",
5796 for (i=0; i<num_names; i++) {
5797 if (names[i] != NULL) {
5798 printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
5807 static bool test_DeleteDomainGroup(struct dcerpc_pipe *p, struct torture_context *tctx,
5808 struct policy_handle *group_handle)
5810 struct samr_DeleteDomainGroup d;
5813 torture_comment(tctx, "Testing DeleteDomainGroup\n");
5815 d.in.group_handle = group_handle;
5816 d.out.group_handle = group_handle;
5818 status = dcerpc_samr_DeleteDomainGroup(p, tctx, &d);
5819 torture_assert_ntstatus_ok(tctx, status, "DeleteDomainGroup");
5824 static bool test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
5825 struct policy_handle *domain_handle)
5827 struct samr_TestPrivateFunctionsDomain r;
5831 torture_comment(tctx, "Testing TestPrivateFunctionsDomain\n");
5833 r.in.domain_handle = domain_handle;
5835 status = dcerpc_samr_TestPrivateFunctionsDomain(p, tctx, &r);
5836 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsDomain");
5841 static bool test_RidToSid(struct dcerpc_pipe *p, struct torture_context *tctx,
5842 struct dom_sid *domain_sid,
5843 struct policy_handle *domain_handle)
5845 struct samr_RidToSid r;
5848 struct dom_sid *calc_sid, *out_sid;
5849 int rids[] = { 0, 42, 512, 10200 };
5852 for (i=0;i<ARRAY_SIZE(rids);i++) {
5853 torture_comment(tctx, "Testing RidToSid\n");
5855 calc_sid = dom_sid_dup(tctx, domain_sid);
5856 r.in.domain_handle = domain_handle;
5858 r.out.sid = &out_sid;
5860 status = dcerpc_samr_RidToSid(p, tctx, &r);
5861 if (!NT_STATUS_IS_OK(status)) {
5862 printf("RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
5865 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
5867 if (!dom_sid_equal(calc_sid, out_sid)) {
5868 printf("RidToSid for %d failed - got %s, expected %s\n", rids[i],
5869 dom_sid_string(tctx, out_sid),
5870 dom_sid_string(tctx, calc_sid));
5879 static bool test_GetBootKeyInformation(struct dcerpc_pipe *p, struct torture_context *tctx,
5880 struct policy_handle *domain_handle)
5882 struct samr_GetBootKeyInformation r;
5885 uint32_t unknown = 0;
5887 torture_comment(tctx, "Testing GetBootKeyInformation\n");
5889 r.in.domain_handle = domain_handle;
5890 r.out.unknown = &unknown;
5892 status = dcerpc_samr_GetBootKeyInformation(p, tctx, &r);
5893 if (!NT_STATUS_IS_OK(status)) {
5894 /* w2k3 seems to fail this sometimes and pass it sometimes */
5895 torture_comment(tctx, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
5901 static bool test_AddGroupMember(struct dcerpc_pipe *p, struct torture_context *tctx,
5902 struct policy_handle *domain_handle,
5903 struct policy_handle *group_handle)
5906 struct samr_AddGroupMember r;
5907 struct samr_DeleteGroupMember d;
5908 struct samr_QueryGroupMember q;
5909 struct samr_RidTypeArray *rids = NULL;
5910 struct samr_SetMemberAttributesOfGroup s;
5912 bool found_member = false;
5915 status = test_LookupName(p, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
5916 torture_assert_ntstatus_ok(tctx, status, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME);
5918 r.in.group_handle = group_handle;
5920 r.in.flags = 0; /* ??? */
5922 torture_comment(tctx, "Testing AddGroupMember, QueryGroupMember and DeleteGroupMember\n");
5924 d.in.group_handle = group_handle;
5927 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
5928 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_NOT_IN_GROUP, status, "DeleteGroupMember");
5930 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5931 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
5933 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5934 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_IN_GROUP, status, "AddGroupMember");
5936 if (torture_setting_bool(tctx, "samba4", false) ||
5937 torture_setting_bool(tctx, "samba3", false)) {
5938 torture_comment(tctx, "skipping SetMemberAttributesOfGroup test against Samba\n");
5940 /* this one is quite strange. I am using random inputs in the
5941 hope of triggering an error that might give us a clue */
5943 s.in.group_handle = group_handle;
5944 s.in.unknown1 = random();
5945 s.in.unknown2 = random();
5947 status = dcerpc_samr_SetMemberAttributesOfGroup(p, tctx, &s);
5948 torture_assert_ntstatus_ok(tctx, status, "SetMemberAttributesOfGroup");
5951 q.in.group_handle = group_handle;
5954 status = dcerpc_samr_QueryGroupMember(p, tctx, &q);
5955 torture_assert_ntstatus_ok(tctx, status, "QueryGroupMember");
5956 torture_assert(tctx, rids, "QueryGroupMember did not fill in rids structure");
5958 for (i=0; i < rids->count; i++) {
5959 if (rids->rids[i] == rid) {
5960 found_member = true;
5964 torture_assert(tctx, found_member, "QueryGroupMember did not list newly added member");
5966 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
5967 torture_assert_ntstatus_ok(tctx, status, "DeleteGroupMember");
5970 found_member = false;
5972 status = dcerpc_samr_QueryGroupMember(p, tctx, &q);
5973 torture_assert_ntstatus_ok(tctx, status, "QueryGroupMember");
5974 torture_assert(tctx, rids, "QueryGroupMember did not fill in rids structure");
5976 for (i=0; i < rids->count; i++) {
5977 if (rids->rids[i] == rid) {
5978 found_member = true;
5982 torture_assert(tctx, !found_member, "QueryGroupMember does still list removed member");
5984 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5985 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
5991 static bool test_CreateDomainGroup(struct dcerpc_pipe *p,
5992 struct torture_context *tctx,
5993 struct policy_handle *domain_handle,
5994 const char *group_name,
5995 struct policy_handle *group_handle,
5996 struct dom_sid *domain_sid,
6000 struct samr_CreateDomainGroup r;
6002 struct lsa_String name;
6005 init_lsa_String(&name, group_name);
6007 r.in.domain_handle = domain_handle;
6009 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6010 r.out.group_handle = group_handle;
6013 printf("Testing CreateDomainGroup(%s)\n", r.in.name->string);
6015 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
6017 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
6018 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
6019 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.name->string);
6022 printf("Server should have refused create of '%s', got %s instead\n", r.in.name->string,
6028 if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS)) {
6029 if (!test_DeleteGroup_byname(p, tctx, domain_handle, r.in.name->string)) {
6030 printf("CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
6034 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
6036 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
6037 if (!test_DeleteUser_byname(p, tctx, domain_handle, r.in.name->string)) {
6039 printf("CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
6043 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
6045 torture_assert_ntstatus_ok(tctx, status, "CreateDomainGroup");
6051 if (!test_AddGroupMember(p, tctx, domain_handle, group_handle)) {
6052 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
6056 if (!test_SetGroupInfo(p, tctx, group_handle)) {
6065 its not totally clear what this does. It seems to accept any sid you like.
6067 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p,
6068 struct torture_context *tctx,
6069 struct policy_handle *domain_handle)
6072 struct samr_RemoveMemberFromForeignDomain r;
6074 r.in.domain_handle = domain_handle;
6075 r.in.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-12-34-56-78");
6077 status = dcerpc_samr_RemoveMemberFromForeignDomain(p, tctx, &r);
6078 torture_assert_ntstatus_ok(tctx, status, "RemoveMemberFromForeignDomain");
6083 static bool test_EnumDomainUsers(struct dcerpc_pipe *p,
6084 struct torture_context *tctx,
6085 struct policy_handle *domain_handle,
6086 uint32_t *total_num_entries_p)
6089 struct samr_EnumDomainUsers r;
6090 uint32_t resume_handle = 0;
6091 uint32_t num_entries = 0;
6092 uint32_t total_num_entries = 0;
6093 struct samr_SamArray *sam;
6095 r.in.domain_handle = domain_handle;
6096 r.in.acct_flags = 0;
6097 r.in.max_size = (uint32_t)-1;
6098 r.in.resume_handle = &resume_handle;
6101 r.out.num_entries = &num_entries;
6102 r.out.resume_handle = &resume_handle;
6104 printf("Testing EnumDomainUsers\n");
6107 status = dcerpc_samr_EnumDomainUsers(p, tctx, &r);
6108 if (NT_STATUS_IS_ERR(status)) {
6109 torture_assert_ntstatus_ok(tctx, status,
6110 "failed to enumerate users");
6113 total_num_entries += num_entries;
6114 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
6116 if (total_num_entries_p) {
6117 *total_num_entries_p = total_num_entries;
6123 static bool test_EnumDomainGroups(struct dcerpc_pipe *p,
6124 struct torture_context *tctx,
6125 struct policy_handle *domain_handle,
6126 uint32_t *total_num_entries_p)
6129 struct samr_EnumDomainGroups r;
6130 uint32_t resume_handle = 0;
6131 uint32_t num_entries = 0;
6132 uint32_t total_num_entries = 0;
6133 struct samr_SamArray *sam;
6135 r.in.domain_handle = domain_handle;
6136 r.in.max_size = (uint32_t)-1;
6137 r.in.resume_handle = &resume_handle;
6140 r.out.num_entries = &num_entries;
6141 r.out.resume_handle = &resume_handle;
6143 printf("Testing EnumDomainGroups\n");
6146 status = dcerpc_samr_EnumDomainGroups(p, tctx, &r);
6147 if (NT_STATUS_IS_ERR(status)) {
6148 torture_assert_ntstatus_ok(tctx, status,
6149 "failed to enumerate groups");
6152 total_num_entries += num_entries;
6153 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
6155 if (total_num_entries_p) {
6156 *total_num_entries_p = total_num_entries;
6162 static bool test_EnumDomainAliases(struct dcerpc_pipe *p,
6163 struct torture_context *tctx,
6164 struct policy_handle *domain_handle,
6165 uint32_t *total_num_entries_p)
6168 struct samr_EnumDomainAliases r;
6169 uint32_t resume_handle = 0;
6170 uint32_t num_entries = 0;
6171 uint32_t total_num_entries = 0;
6172 struct samr_SamArray *sam;
6174 r.in.domain_handle = domain_handle;
6175 r.in.max_size = (uint32_t)-1;
6176 r.in.resume_handle = &resume_handle;
6179 r.out.num_entries = &num_entries;
6180 r.out.resume_handle = &resume_handle;
6182 printf("Testing EnumDomainAliases\n");
6185 status = dcerpc_samr_EnumDomainAliases(p, tctx, &r);
6186 if (NT_STATUS_IS_ERR(status)) {
6187 torture_assert_ntstatus_ok(tctx, status,
6188 "failed to enumerate aliases");
6191 total_num_entries += num_entries;
6192 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
6194 if (total_num_entries_p) {
6195 *total_num_entries_p = total_num_entries;
6201 static bool test_QueryDisplayInfo_level(struct dcerpc_pipe *p,
6202 struct torture_context *tctx,
6203 struct policy_handle *handle,
6205 uint32_t *total_num_entries_p)
6208 struct samr_QueryDisplayInfo r;
6209 uint32_t total_num_entries = 0;
6211 r.in.domain_handle = handle;
6214 r.in.max_entries = (uint32_t)-1;
6215 r.in.buf_size = (uint32_t)-1;
6217 printf("Testing QueryDisplayInfo\n");
6220 uint32_t total_size;
6221 uint32_t returned_size;
6222 union samr_DispInfo info;
6224 r.out.total_size = &total_size;
6225 r.out.returned_size = &returned_size;
6228 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &r);
6229 if (NT_STATUS_IS_ERR(status)) {
6230 torture_assert_ntstatus_ok(tctx, status,
6231 "failed to query displayinfo");
6234 if (*r.out.returned_size == 0) {
6238 switch (r.in.level) {
6240 total_num_entries += info.info1.count;
6241 r.in.start_idx += info.info1.entries[info.info1.count - 1].idx + 1;
6244 total_num_entries += info.info2.count;
6245 r.in.start_idx += info.info2.entries[info.info2.count - 1].idx + 1;
6248 total_num_entries += info.info3.count;
6249 r.in.start_idx += info.info3.entries[info.info3.count - 1].idx + 1;
6252 total_num_entries += info.info4.count;
6253 r.in.start_idx += info.info4.entries[info.info4.count - 1].idx + 1;
6256 total_num_entries += info.info5.count;
6257 r.in.start_idx += info.info5.entries[info.info5.count - 1].idx + 1;
6263 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
6265 if (total_num_entries_p) {
6266 *total_num_entries_p = total_num_entries;
6272 static bool test_ManyObjects(struct dcerpc_pipe *p,
6273 struct torture_context *tctx,
6274 struct policy_handle *domain_handle,
6275 struct dom_sid *domain_sid,
6276 enum torture_samr_choice which_ops)
6278 uint32_t num_total = 1500;
6279 uint32_t num_enum = 0;
6280 uint32_t num_disp = 0;
6281 uint32_t num_created = 0;
6282 uint32_t num_anounced = 0;
6287 struct policy_handle *handles = talloc_zero_array(tctx, struct policy_handle, num_total);
6292 struct samr_QueryDomainInfo2 r;
6293 union samr_DomainInfo *info;
6294 r.in.domain_handle = domain_handle;
6298 status = dcerpc_samr_QueryDomainInfo2(p, tctx, &r);
6299 torture_assert_ntstatus_ok(tctx, status,
6300 "failed to query domain info");
6302 switch (which_ops) {
6303 case TORTURE_SAMR_MANY_ACCOUNTS:
6304 num_anounced = info->general.num_users;
6306 case TORTURE_SAMR_MANY_GROUPS:
6307 num_anounced = info->general.num_groups;
6309 case TORTURE_SAMR_MANY_ALIASES:
6310 num_anounced = info->general.num_aliases;
6319 for (i=0; i < num_total; i++) {
6321 const char *name = NULL;
6323 switch (which_ops) {
6324 case TORTURE_SAMR_MANY_ACCOUNTS:
6325 name = talloc_asprintf(tctx, "%s%04d", TEST_ACCOUNT_NAME, i);
6326 ret &= test_CreateUser(p, tctx, domain_handle, name, &handles[i], domain_sid, 0, NULL, false);
6328 case TORTURE_SAMR_MANY_GROUPS:
6329 name = talloc_asprintf(tctx, "%s%04d", TEST_GROUPNAME, i);
6330 ret &= test_CreateDomainGroup(p, tctx, domain_handle, name, &handles[i], domain_sid, false);
6332 case TORTURE_SAMR_MANY_ALIASES:
6333 name = talloc_asprintf(tctx, "%s%04d", TEST_ALIASNAME, i);
6334 ret &= test_CreateAlias(p, tctx, domain_handle, name, &handles[i], domain_sid, false);
6339 if (!policy_handle_empty(&handles[i])) {
6346 switch (which_ops) {
6347 case TORTURE_SAMR_MANY_ACCOUNTS:
6348 ret &= test_EnumDomainUsers(p, tctx, domain_handle, &num_enum);
6350 case TORTURE_SAMR_MANY_GROUPS:
6351 ret &= test_EnumDomainGroups(p, tctx, domain_handle, &num_enum);
6353 case TORTURE_SAMR_MANY_ALIASES:
6354 ret &= test_EnumDomainAliases(p, tctx, domain_handle, &num_enum);
6362 switch (which_ops) {
6363 case TORTURE_SAMR_MANY_ACCOUNTS:
6364 ret &= test_QueryDisplayInfo_level(p, tctx, domain_handle, 1, &num_disp);
6366 case TORTURE_SAMR_MANY_GROUPS:
6367 ret &= test_QueryDisplayInfo_level(p, tctx, domain_handle, 3, &num_disp);
6369 case TORTURE_SAMR_MANY_ALIASES:
6370 /* no aliases in dispinfo */
6376 /* close or delete */
6378 for (i=0; i < num_total; i++) {
6380 if (policy_handle_empty(&handles[i])) {
6384 if (torture_setting_bool(tctx, "samba3", false)) {
6385 ret &= test_samr_handle_Close(p, tctx, &handles[i]);
6387 switch (which_ops) {
6388 case TORTURE_SAMR_MANY_ACCOUNTS:
6389 ret &= test_DeleteUser(p, tctx, &handles[i]);
6391 case TORTURE_SAMR_MANY_GROUPS:
6392 ret &= test_DeleteDomainGroup(p, tctx, &handles[i]);
6394 case TORTURE_SAMR_MANY_ALIASES:
6395 ret &= test_DeleteAlias(p, tctx, &handles[i]);
6403 talloc_free(handles);
6405 if (which_ops == TORTURE_SAMR_MANY_ACCOUNTS && num_enum != num_anounced + num_created) {
6406 torture_comment(tctx,
6407 "unexpected number of results (%u) returned in enum call, expected %u\n",
6408 num_enum, num_anounced + num_created);
6410 torture_comment(tctx,
6411 "unexpected number of results (%u) returned in dispinfo, call, expected %u\n",
6412 num_disp, num_anounced + num_created);
6417 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
6418 struct policy_handle *handle);
6420 static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
6421 struct policy_handle *handle, struct dom_sid *sid,
6422 enum torture_samr_choice which_ops,
6423 struct cli_credentials *machine_credentials)
6426 struct samr_OpenDomain r;
6427 struct policy_handle domain_handle;
6428 struct policy_handle alias_handle;
6429 struct policy_handle user_handle;
6430 struct policy_handle group_handle;
6433 ZERO_STRUCT(alias_handle);
6434 ZERO_STRUCT(user_handle);
6435 ZERO_STRUCT(group_handle);
6436 ZERO_STRUCT(domain_handle);
6438 torture_comment(tctx, "Testing OpenDomain of %s\n", dom_sid_string(tctx, sid));
6440 r.in.connect_handle = handle;
6441 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6443 r.out.domain_handle = &domain_handle;
6445 status = dcerpc_samr_OpenDomain(p, tctx, &r);
6446 torture_assert_ntstatus_ok(tctx, status, "OpenDomain");
6448 /* run the domain tests with the main handle closed - this tests
6449 the servers reference counting */
6450 torture_assert(tctx, test_samr_handle_Close(p, tctx, handle), "Failed to close SAMR handle");
6452 switch (which_ops) {
6453 case TORTURE_SAMR_PASSWORDS:
6454 case TORTURE_SAMR_USER_PRIVILEGES:
6455 if (!torture_setting_bool(tctx, "samba3", false)) {
6456 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops, NULL);
6458 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, which_ops, NULL, true);
6460 printf("Testing PASSWORDS or PRIVILAGES on domain %s failed!\n", dom_sid_string(tctx, sid));
6463 case TORTURE_SAMR_USER_ATTRIBUTES:
6464 if (!torture_setting_bool(tctx, "samba3", false)) {
6465 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops, NULL);
6467 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, which_ops, NULL, true);
6468 /* This test needs 'complex' users to validate */
6469 ret &= test_QueryDisplayInfo(p, tctx, &domain_handle);
6471 printf("Testing ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
6474 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
6475 if (!torture_setting_bool(tctx, "samba3", false)) {
6476 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops, machine_credentials);
6478 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, which_ops, machine_credentials, true);
6480 printf("Testing PASSWORDS PWDLASTSET on domain %s failed!\n", dom_sid_string(tctx, sid));
6483 case TORTURE_SAMR_MANY_ACCOUNTS:
6484 case TORTURE_SAMR_MANY_GROUPS:
6485 case TORTURE_SAMR_MANY_ALIASES:
6486 ret &= test_ManyObjects(p, tctx, &domain_handle, sid, which_ops);
6488 printf("Testing MANY-{ACCOUNTS,GROUPS,ALIASES} on domain %s failed!\n", dom_sid_string(tctx, sid));
6491 case TORTURE_SAMR_OTHER:
6492 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, which_ops, NULL, true);
6494 printf("Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid));
6496 if (!torture_setting_bool(tctx, "samba3", false)) {
6497 ret &= test_QuerySecurity(p, tctx, &domain_handle);
6499 ret &= test_RemoveMemberFromForeignDomain(p, tctx, &domain_handle);
6500 ret &= test_CreateAlias(p, tctx, &domain_handle, TEST_ALIASNAME, &alias_handle, sid, true);
6501 ret &= test_CreateDomainGroup(p, tctx, &domain_handle, TEST_GROUPNAME, &group_handle, sid, true);
6502 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
6503 ret &= test_QueryDomainInfo2(p, tctx, &domain_handle);
6504 ret &= test_EnumDomainUsers_all(p, tctx, &domain_handle);
6505 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
6506 ret &= test_EnumDomainGroups_all(p, tctx, &domain_handle);
6507 ret &= test_EnumDomainAliases_all(p, tctx, &domain_handle);
6508 ret &= test_QueryDisplayInfo2(p, tctx, &domain_handle);
6509 ret &= test_QueryDisplayInfo3(p, tctx, &domain_handle);
6510 ret &= test_QueryDisplayInfo_continue(p, tctx, &domain_handle);
6512 if (torture_setting_bool(tctx, "samba4", false)) {
6513 torture_comment(tctx, "skipping GetDisplayEnumerationIndex test against Samba4\n");
6515 ret &= test_GetDisplayEnumerationIndex(p, tctx, &domain_handle);
6516 ret &= test_GetDisplayEnumerationIndex2(p, tctx, &domain_handle);
6518 ret &= test_GroupList(p, tctx, &domain_handle);
6519 ret &= test_TestPrivateFunctionsDomain(p, tctx, &domain_handle);
6520 ret &= test_RidToSid(p, tctx, sid, &domain_handle);
6521 ret &= test_GetBootKeyInformation(p, tctx, &domain_handle);
6523 torture_comment(tctx, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx, sid));
6528 if (!policy_handle_empty(&user_handle) &&
6529 !test_DeleteUser(p, tctx, &user_handle)) {
6533 if (!policy_handle_empty(&alias_handle) &&
6534 !test_DeleteAlias(p, tctx, &alias_handle)) {
6538 if (!policy_handle_empty(&group_handle) &&
6539 !test_DeleteDomainGroup(p, tctx, &group_handle)) {
6543 torture_assert(tctx, test_samr_handle_Close(p, tctx, &domain_handle), "Failed to close SAMR domain handle");
6545 torture_assert(tctx, test_Connect(p, tctx, handle), "Faile to re-connect SAMR handle");
6546 /* reconnect the main handle */
6549 printf("Testing domain %s failed!\n", dom_sid_string(tctx, sid));
6555 static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
6556 struct policy_handle *handle, const char *domain,
6557 enum torture_samr_choice which_ops,
6558 struct cli_credentials *machine_credentials)
6561 struct samr_LookupDomain r;
6562 struct dom_sid2 *sid = NULL;
6563 struct lsa_String n1;
6564 struct lsa_String n2;
6567 torture_comment(tctx, "Testing LookupDomain(%s)\n", domain);
6569 /* check for correct error codes */
6570 r.in.connect_handle = handle;
6571 r.in.domain_name = &n2;
6575 status = dcerpc_samr_LookupDomain(p, tctx, &r);
6576 torture_assert_ntstatus_equal(tctx, NT_STATUS_INVALID_PARAMETER, status, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
6578 init_lsa_String(&n2, "xxNODOMAINxx");
6580 status = dcerpc_samr_LookupDomain(p, tctx, &r);
6581 torture_assert_ntstatus_equal(tctx, NT_STATUS_NO_SUCH_DOMAIN, status, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
6583 r.in.connect_handle = handle;
6585 init_lsa_String(&n1, domain);
6586 r.in.domain_name = &n1;
6588 status = dcerpc_samr_LookupDomain(p, tctx, &r);
6589 torture_assert_ntstatus_ok(tctx, status, "LookupDomain");
6591 if (!test_GetDomPwInfo(p, tctx, &n1)) {
6595 if (!test_OpenDomain(p, tctx, handle, *r.out.sid, which_ops,
6596 machine_credentials)) {
6604 static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
6605 struct policy_handle *handle, enum torture_samr_choice which_ops,
6606 struct cli_credentials *machine_credentials)
6609 struct samr_EnumDomains r;
6610 uint32_t resume_handle = 0;
6611 uint32_t num_entries = 0;
6612 struct samr_SamArray *sam = NULL;
6616 r.in.connect_handle = handle;
6617 r.in.resume_handle = &resume_handle;
6618 r.in.buf_size = (uint32_t)-1;
6619 r.out.resume_handle = &resume_handle;
6620 r.out.num_entries = &num_entries;
6623 status = dcerpc_samr_EnumDomains(p, tctx, &r);
6624 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
6630 for (i=0;i<sam->count;i++) {
6631 if (!test_LookupDomain(p, tctx, handle,
6632 sam->entries[i].name.string, which_ops,
6633 machine_credentials)) {
6638 status = dcerpc_samr_EnumDomains(p, tctx, &r);
6639 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
6645 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
6646 struct policy_handle *handle)
6649 struct samr_Connect r;
6650 struct samr_Connect2 r2;
6651 struct samr_Connect3 r3;
6652 struct samr_Connect4 r4;
6653 struct samr_Connect5 r5;
6654 union samr_ConnectInfo info;
6655 struct policy_handle h;
6656 uint32_t level_out = 0;
6657 bool ret = true, got_handle = false;
6659 torture_comment(tctx, "testing samr_Connect\n");
6661 r.in.system_name = 0;
6662 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6663 r.out.connect_handle = &h;
6665 status = dcerpc_samr_Connect(p, tctx, &r);
6666 if (!NT_STATUS_IS_OK(status)) {
6667 torture_comment(tctx, "Connect failed - %s\n", nt_errstr(status));
6674 torture_comment(tctx, "testing samr_Connect2\n");
6676 r2.in.system_name = NULL;
6677 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6678 r2.out.connect_handle = &h;
6680 status = dcerpc_samr_Connect2(p, tctx, &r2);
6681 if (!NT_STATUS_IS_OK(status)) {
6682 torture_comment(tctx, "Connect2 failed - %s\n", nt_errstr(status));
6686 test_samr_handle_Close(p, tctx, handle);
6692 torture_comment(tctx, "testing samr_Connect3\n");
6694 r3.in.system_name = NULL;
6696 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6697 r3.out.connect_handle = &h;
6699 status = dcerpc_samr_Connect3(p, tctx, &r3);
6700 if (!NT_STATUS_IS_OK(status)) {
6701 printf("Connect3 failed - %s\n", nt_errstr(status));
6705 test_samr_handle_Close(p, tctx, handle);
6711 torture_comment(tctx, "testing samr_Connect4\n");
6713 r4.in.system_name = "";
6714 r4.in.client_version = 0;
6715 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6716 r4.out.connect_handle = &h;
6718 status = dcerpc_samr_Connect4(p, tctx, &r4);
6719 if (!NT_STATUS_IS_OK(status)) {
6720 printf("Connect4 failed - %s\n", nt_errstr(status));
6724 test_samr_handle_Close(p, tctx, handle);
6730 torture_comment(tctx, "testing samr_Connect5\n");
6732 info.info1.client_version = 0;
6733 info.info1.unknown2 = 0;
6735 r5.in.system_name = "";
6736 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6738 r5.out.level_out = &level_out;
6739 r5.in.info_in = &info;
6740 r5.out.info_out = &info;
6741 r5.out.connect_handle = &h;
6743 status = dcerpc_samr_Connect5(p, tctx, &r5);
6744 if (!NT_STATUS_IS_OK(status)) {
6745 printf("Connect5 failed - %s\n", nt_errstr(status));
6749 test_samr_handle_Close(p, tctx, handle);
6759 bool torture_rpc_samr(struct torture_context *torture)
6762 struct dcerpc_pipe *p;
6764 struct policy_handle handle;
6766 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6767 if (!NT_STATUS_IS_OK(status)) {
6771 ret &= test_Connect(p, torture, &handle);
6773 if (!torture_setting_bool(torture, "samba3", false)) {
6774 ret &= test_QuerySecurity(p, torture, &handle);
6777 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_OTHER, NULL);
6779 ret &= test_SetDsrmPassword(p, torture, &handle);
6781 ret &= test_Shutdown(p, torture, &handle);
6783 ret &= test_samr_handle_Close(p, torture, &handle);
6789 bool torture_rpc_samr_users(struct torture_context *torture)
6792 struct dcerpc_pipe *p;
6794 struct policy_handle handle;
6796 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6797 if (!NT_STATUS_IS_OK(status)) {
6801 ret &= test_Connect(p, torture, &handle);
6803 if (!torture_setting_bool(torture, "samba3", false)) {
6804 ret &= test_QuerySecurity(p, torture, &handle);
6807 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_USER_ATTRIBUTES, NULL);
6809 ret &= test_SetDsrmPassword(p, torture, &handle);
6811 ret &= test_Shutdown(p, torture, &handle);
6813 ret &= test_samr_handle_Close(p, torture, &handle);
6819 bool torture_rpc_samr_passwords(struct torture_context *torture)
6822 struct dcerpc_pipe *p;
6824 struct policy_handle handle;
6826 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6827 if (!NT_STATUS_IS_OK(status)) {
6831 ret &= test_Connect(p, torture, &handle);
6833 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_PASSWORDS, NULL);
6835 ret &= test_samr_handle_Close(p, torture, &handle);
6840 static bool torture_rpc_samr_pwdlastset(struct torture_context *torture,
6841 struct dcerpc_pipe *p2,
6842 struct cli_credentials *machine_credentials)
6845 struct dcerpc_pipe *p;
6847 struct policy_handle handle;
6849 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6850 if (!NT_STATUS_IS_OK(status)) {
6854 ret &= test_Connect(p, torture, &handle);
6856 ret &= test_EnumDomains(p, torture, &handle,
6857 TORTURE_SAMR_PASSWORDS_PWDLASTSET,
6858 machine_credentials);
6860 ret &= test_samr_handle_Close(p, torture, &handle);
6865 struct torture_suite *torture_rpc_samr_passwords_pwdlastset(TALLOC_CTX *mem_ctx)
6867 struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-PASSWORDS-PWDLASTSET");
6868 struct torture_rpc_tcase *tcase;
6870 tcase = torture_suite_add_machine_rpc_iface_tcase(suite, "samr",
6872 TEST_ACCOUNT_NAME_PWD);
6874 torture_rpc_tcase_add_test_creds(tcase, "pwdLastSet",
6875 torture_rpc_samr_pwdlastset);
6880 static bool torture_rpc_samr_users_privileges_delete_user(struct torture_context *torture,
6881 struct dcerpc_pipe *p2,
6882 struct cli_credentials *machine_credentials)
6885 struct dcerpc_pipe *p;
6887 struct policy_handle handle;
6889 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6890 if (!NT_STATUS_IS_OK(status)) {
6894 ret &= test_Connect(p, torture, &handle);
6896 ret &= test_EnumDomains(p, torture, &handle,
6897 TORTURE_SAMR_USER_PRIVILEGES,
6898 machine_credentials);
6900 ret &= test_samr_handle_Close(p, torture, &handle);
6905 struct torture_suite *torture_rpc_samr_user_privileges(TALLOC_CTX *mem_ctx)
6907 struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-USERS-PRIVILEGES");
6908 struct torture_rpc_tcase *tcase;
6910 tcase = torture_suite_add_machine_rpc_iface_tcase(suite, "samr",
6912 TEST_ACCOUNT_NAME_PWD);
6914 torture_rpc_tcase_add_test_creds(tcase, "delete_privileged_user",
6915 torture_rpc_samr_users_privileges_delete_user);
6920 static bool torture_rpc_samr_many_accounts(struct torture_context *torture,
6921 struct dcerpc_pipe *p2,
6922 struct cli_credentials *machine_credentials)
6925 struct dcerpc_pipe *p;
6927 struct policy_handle handle;
6929 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6930 if (!NT_STATUS_IS_OK(status)) {
6934 ret &= test_Connect(p, torture, &handle);
6936 ret &= test_EnumDomains(p, torture, &handle,
6937 TORTURE_SAMR_MANY_ACCOUNTS,
6938 machine_credentials);
6940 ret &= test_samr_handle_Close(p, torture, &handle);
6945 static bool torture_rpc_samr_many_groups(struct torture_context *torture,
6946 struct dcerpc_pipe *p2,
6947 struct cli_credentials *machine_credentials)
6950 struct dcerpc_pipe *p;
6952 struct policy_handle handle;
6954 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6955 if (!NT_STATUS_IS_OK(status)) {
6959 ret &= test_Connect(p, torture, &handle);
6961 ret &= test_EnumDomains(p, torture, &handle,
6962 TORTURE_SAMR_MANY_GROUPS,
6963 machine_credentials);
6965 ret &= test_samr_handle_Close(p, torture, &handle);
6970 static bool torture_rpc_samr_many_aliases(struct torture_context *torture,
6971 struct dcerpc_pipe *p2,
6972 struct cli_credentials *machine_credentials)
6975 struct dcerpc_pipe *p;
6977 struct policy_handle handle;
6979 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6980 if (!NT_STATUS_IS_OK(status)) {
6984 ret &= test_Connect(p, torture, &handle);
6986 ret &= test_EnumDomains(p, torture, &handle,
6987 TORTURE_SAMR_MANY_ALIASES,
6988 machine_credentials);
6990 ret &= test_samr_handle_Close(p, torture, &handle);
6995 struct torture_suite *torture_rpc_samr_large_dc(TALLOC_CTX *mem_ctx)
6997 struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-LARGE-DC");
6998 struct torture_rpc_tcase *tcase;
7000 tcase = torture_suite_add_machine_rpc_iface_tcase(suite, "samr",
7004 torture_rpc_tcase_add_test_creds(tcase, "many_aliases",
7005 torture_rpc_samr_many_aliases);
7006 torture_rpc_tcase_add_test_creds(tcase, "many_groups",
7007 torture_rpc_samr_many_groups);
7008 torture_rpc_tcase_add_test_creds(tcase, "many_accounts",
7009 torture_rpc_samr_many_accounts);