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_IS_OK(status)) {
2749 torture_assert_ntstatus_equal(tctx, status, expected_result, "LogonSamLogonEx failed");
2752 torture_assert_ntstatus_ok(tctx, status, "LogonSamLogonEx failed");
2758 static bool test_SamLogon_with_creds(struct torture_context *tctx,
2759 struct dcerpc_pipe *p,
2760 struct cli_credentials *machine_creds,
2761 const char *acct_name,
2763 NTSTATUS expected_samlogon_result)
2766 struct cli_credentials *test_credentials;
2768 test_credentials = cli_credentials_init(tctx);
2770 cli_credentials_set_workstation(test_credentials,
2771 cli_credentials_get_workstation(machine_creds), CRED_SPECIFIED);
2772 cli_credentials_set_domain(test_credentials,
2773 cli_credentials_get_domain(machine_creds), CRED_SPECIFIED);
2774 cli_credentials_set_username(test_credentials,
2775 acct_name, CRED_SPECIFIED);
2776 cli_credentials_set_password(test_credentials,
2777 password, CRED_SPECIFIED);
2779 printf("testing samlogon as %s password: %s\n",
2780 acct_name, password);
2782 if (!test_SamLogon(tctx, p, test_credentials,
2783 expected_samlogon_result)) {
2784 torture_warning(tctx, "new password did not work\n");
2791 static bool test_SetPassword_level(struct dcerpc_pipe *p,
2792 struct dcerpc_pipe *np,
2793 struct torture_context *tctx,
2794 struct policy_handle *handle,
2796 uint32_t fields_present,
2797 uint8_t password_expired,
2798 bool *matched_expected_error,
2800 const char *acct_name,
2802 struct cli_credentials *machine_creds,
2803 bool use_queryinfo2,
2805 NTSTATUS expected_samlogon_result)
2807 const char *fields = NULL;
2814 fields = talloc_asprintf(tctx, "(fields_present: 0x%08x)",
2821 torture_comment(tctx, "Testing SetUserInfo%s level %d call "
2822 "(password_expired: %d) %s\n",
2823 use_setinfo2 ? "2":"", level, password_expired,
2824 fields ? fields : "");
2826 if (!test_SetUserPass_level_ex(p, tctx, handle, level,
2831 matched_expected_error)) {
2835 if (!test_QueryUserInfo_pwdlastset(p, tctx, handle,
2841 if (*matched_expected_error == true) {
2845 if (!test_SamLogon_with_creds(tctx, np,
2849 expected_samlogon_result)) {
2856 static bool test_SetPassword_pwdlastset(struct dcerpc_pipe *p,
2857 struct torture_context *tctx,
2858 uint32_t acct_flags,
2859 const char *acct_name,
2860 struct policy_handle *handle,
2862 struct cli_credentials *machine_credentials)
2864 int s = 0, q = 0, f = 0, l = 0, z = 0;
2865 struct dcerpc_binding *b;
2868 bool set_levels[] = { false, true };
2869 bool query_levels[] = { false, true };
2870 uint32_t levels[] = { 18, 21, 23, 24, 25, 26 };
2871 uint32_t nonzeros[] = { 1, 24 };
2872 uint32_t fields_present[] = {
2874 SAMR_FIELD_EXPIRED_FLAG,
2875 SAMR_FIELD_LAST_PWD_CHANGE,
2876 SAMR_FIELD_EXPIRED_FLAG | SAMR_FIELD_LAST_PWD_CHANGE,
2878 SAMR_FIELD_NT_PASSWORD_PRESENT,
2879 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
2880 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
2881 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
2882 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
2883 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
2884 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE | SAMR_FIELD_EXPIRED_FLAG
2887 struct dcerpc_pipe *np = NULL;
2889 if (torture_setting_bool(tctx, "samba3", false)) {
2891 printf("Samba3 has second granularity, setting delay to: %d\n",
2895 status = torture_rpc_binding(tctx, &b);
2896 if (!NT_STATUS_IS_OK(status)) {
2901 /* We have to use schannel, otherwise the SamLogonEx fails
2902 * with INTERNAL_ERROR */
2904 b->flags &= ~DCERPC_AUTH_OPTIONS;
2905 b->flags |= DCERPC_SCHANNEL | DCERPC_SIGN | DCERPC_SCHANNEL_128;
2907 status = dcerpc_pipe_connect_b(tctx, &np, b,
2908 &ndr_table_netlogon,
2909 machine_credentials, tctx->ev, tctx->lp_ctx);
2911 if (!NT_STATUS_IS_OK(status)) {
2912 d_printf("RPC pipe connect as domain member failed: %s\n", nt_errstr(status));
2917 /* set to 1 to enable testing for all possible opcode
2918 (SetUserInfo, SetUserInfo2, QueryUserInfo, QueryUserInfo2)
2921 #define TEST_SET_LEVELS 1
2922 #define TEST_QUERY_LEVELS 1
2924 for (l=0; l<ARRAY_SIZE(levels); l++) {
2925 for (z=0; z<ARRAY_SIZE(nonzeros); z++) {
2926 for (f=0; f<ARRAY_SIZE(fields_present); f++) {
2927 #ifdef TEST_SET_LEVELS
2928 for (s=0; s<ARRAY_SIZE(set_levels); s++) {
2930 #ifdef TEST_QUERY_LEVELS
2931 for (q=0; q<ARRAY_SIZE(query_levels); q++) {
2933 NTTIME pwdlastset_old = 0;
2934 NTTIME pwdlastset_new = 0;
2935 bool matched_expected_error = false;
2936 NTSTATUS expected_samlogon_result = NT_STATUS_ACCOUNT_DISABLED;
2938 torture_comment(tctx, "------------------------------\n"
2939 "Testing pwdLastSet attribute for flags: 0x%08x "
2940 "(s: %d (l: %d), q: %d)\n",
2941 acct_flags, s, levels[l], q);
2943 switch (levels[l]) {
2947 if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
2948 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT))) {
2949 expected_samlogon_result = NT_STATUS_WRONG_PASSWORD;
2957 /* set a password and force password change (pwdlastset 0) by
2958 * setting the password expired flag to a non-0 value */
2960 if (!test_SetPassword_level(p, np, tctx, handle,
2964 &matched_expected_error,
2968 machine_credentials,
2971 expected_samlogon_result)) {
2975 if (matched_expected_error == true) {
2976 /* skipping on expected failure */
2980 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
2981 * set without the SAMR_FIELD_EXPIRED_FLAG */
2983 switch (levels[l]) {
2987 if ((pwdlastset_new != 0) &&
2988 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
2989 torture_comment(tctx, "not considering a non-0 "
2990 "pwdLastSet as a an error as the "
2991 "SAMR_FIELD_EXPIRED_FLAG has not "
2996 if (pwdlastset_new != 0) {
2997 torture_warning(tctx, "pwdLastSet test failed: "
2998 "expected pwdLastSet 0 but got %lld\n",
3005 switch (levels[l]) {
3009 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3010 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3011 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3012 (pwdlastset_old >= pwdlastset_new)) {
3013 torture_warning(tctx, "pwdlastset not increasing\n");
3018 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3019 (pwdlastset_old >= pwdlastset_new)) {
3020 torture_warning(tctx, "pwdlastset not increasing\n");
3030 /* set a password, pwdlastset needs to get updated (increased
3031 * value), password_expired value used here is 0 */
3033 if (!test_SetPassword_level(p, np, tctx, handle,
3037 &matched_expected_error,
3041 machine_credentials,
3044 expected_samlogon_result)) {
3048 /* when a password has been changed, pwdlastset must not be 0 afterwards
3049 * and must be larger then the old value */
3051 switch (levels[l]) {
3056 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3057 * password has been changed, old and new pwdlastset
3058 * need to be the same value */
3060 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3061 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3062 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3064 torture_assert_int_equal(tctx, pwdlastset_old,
3065 pwdlastset_new, "pwdlastset must be equal");
3069 if (pwdlastset_old >= pwdlastset_new) {
3070 torture_warning(tctx, "pwdLastSet test failed: "
3071 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
3072 pwdlastset_old, pwdlastset_new);
3075 if (pwdlastset_new == 0) {
3076 torture_warning(tctx, "pwdLastSet test failed: "
3077 "expected non-0 pwdlastset, got: %lld\n",
3083 switch (levels[l]) {
3087 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3088 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3089 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3090 (pwdlastset_old >= pwdlastset_new)) {
3091 torture_warning(tctx, "pwdlastset not increasing\n");
3096 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3097 (pwdlastset_old >= pwdlastset_new)) {
3098 torture_warning(tctx, "pwdlastset not increasing\n");
3104 pwdlastset_old = pwdlastset_new;
3110 /* set a password, pwdlastset needs to get updated (increased
3111 * value), password_expired value used here is 0 */
3113 if (!test_SetPassword_level(p, np, tctx, handle,
3117 &matched_expected_error,
3121 machine_credentials,
3124 expected_samlogon_result)) {
3128 /* when a password has been changed, pwdlastset must not be 0 afterwards
3129 * and must be larger then the old value */
3131 switch (levels[l]) {
3136 /* if no password has been changed, old and new pwdlastset
3137 * need to be the same value */
3139 if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3140 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3142 torture_assert_int_equal(tctx, pwdlastset_old,
3143 pwdlastset_new, "pwdlastset must be equal");
3147 if (pwdlastset_old >= pwdlastset_new) {
3148 torture_warning(tctx, "pwdLastSet test failed: "
3149 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
3150 pwdlastset_old, pwdlastset_new);
3153 if (pwdlastset_new == 0) {
3154 torture_warning(tctx, "pwdLastSet test failed: "
3155 "expected non-0 pwdlastset, got: %lld\n",
3163 /* set a password and force password change (pwdlastset 0) by
3164 * setting the password expired flag to a non-0 value */
3166 if (!test_SetPassword_level(p, np, tctx, handle,
3170 &matched_expected_error,
3174 machine_credentials,
3177 expected_samlogon_result)) {
3181 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3182 * set without the SAMR_FIELD_EXPIRED_FLAG */
3184 switch (levels[l]) {
3188 if ((pwdlastset_new != 0) &&
3189 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
3190 torture_comment(tctx, "not considering a non-0 "
3191 "pwdLastSet as a an error as the "
3192 "SAMR_FIELD_EXPIRED_FLAG has not "
3197 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3198 * password has been changed, old and new pwdlastset
3199 * need to be the same value */
3201 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3202 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3203 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3205 torture_assert_int_equal(tctx, pwdlastset_old,
3206 pwdlastset_new, "pwdlastset must be equal");
3211 if (pwdlastset_old == pwdlastset_new) {
3212 torture_warning(tctx, "pwdLastSet test failed: "
3213 "expected last pwdlastset (%lld) != new pwdlastset (%lld)\n",
3214 pwdlastset_old, pwdlastset_new);
3218 if (pwdlastset_new != 0) {
3219 torture_warning(tctx, "pwdLastSet test failed: "
3220 "expected pwdLastSet 0, got %lld\n",
3227 switch (levels[l]) {
3231 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3232 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3233 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3234 (pwdlastset_old >= pwdlastset_new)) {
3235 torture_warning(tctx, "pwdlastset not increasing\n");
3240 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3241 (pwdlastset_old >= pwdlastset_new)) {
3242 torture_warning(tctx, "pwdlastset not increasing\n");
3248 /* if the level we are testing does not have a fields_present
3249 * field, skip all fields present tests by setting f to to
3251 switch (levels[l]) {
3255 f = ARRAY_SIZE(fields_present);
3259 #ifdef TEST_QUERY_LEVELS
3262 #ifdef TEST_SET_LEVELS
3265 } /* fields present */
3269 #undef TEST_SET_LEVELS
3270 #undef TEST_QUERY_LEVELS
3275 static bool test_DeleteUser_with_privs(struct dcerpc_pipe *p,
3276 struct dcerpc_pipe *lp,
3277 struct torture_context *tctx,
3278 struct policy_handle *domain_handle,
3279 struct policy_handle *lsa_handle,
3280 struct policy_handle *user_handle,
3281 const struct dom_sid *domain_sid,
3283 struct cli_credentials *machine_credentials)
3288 struct policy_handle lsa_acct_handle;
3289 struct dom_sid *user_sid;
3291 user_sid = dom_sid_add_rid(tctx, domain_sid, rid);
3294 struct lsa_EnumAccountRights r;
3295 struct lsa_RightSet rights;
3297 printf("Testing LSA EnumAccountRights\n");
3299 r.in.handle = lsa_handle;
3300 r.in.sid = user_sid;
3301 r.out.rights = &rights;
3303 status = dcerpc_lsa_EnumAccountRights(lp, tctx, &r);
3304 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3305 "Expected enum rights for account to fail");
3309 struct lsa_RightSet rights;
3310 struct lsa_StringLarge names[2];
3311 struct lsa_AddAccountRights r;
3313 printf("Testing LSA AddAccountRights\n");
3315 init_lsa_StringLarge(&names[0], "SeMachineAccountPrivilege");
3316 init_lsa_StringLarge(&names[1], NULL);
3319 rights.names = names;
3321 r.in.handle = lsa_handle;
3322 r.in.sid = user_sid;
3323 r.in.rights = &rights;
3325 status = dcerpc_lsa_AddAccountRights(lp, tctx, &r);
3326 torture_assert_ntstatus_ok(tctx, status,
3327 "Failed to add privileges");
3331 struct lsa_EnumAccounts r;
3332 uint32_t resume_handle = 0;
3333 struct lsa_SidArray lsa_sid_array;
3335 bool found_sid = false;
3337 printf("Testing LSA EnumAccounts\n");
3339 r.in.handle = lsa_handle;
3340 r.in.num_entries = 0x1000;
3341 r.in.resume_handle = &resume_handle;
3342 r.out.sids = &lsa_sid_array;
3343 r.out.resume_handle = &resume_handle;
3345 status = dcerpc_lsa_EnumAccounts(lp, tctx, &r);
3346 torture_assert_ntstatus_ok(tctx, status,
3347 "Failed to enum accounts");
3349 for (i=0; i < lsa_sid_array.num_sids; i++) {
3350 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
3355 torture_assert(tctx, found_sid,
3356 "failed to list privileged account");
3360 struct lsa_EnumAccountRights r;
3361 struct lsa_RightSet user_rights;
3363 printf("Testing LSA EnumAccountRights\n");
3365 r.in.handle = lsa_handle;
3366 r.in.sid = user_sid;
3367 r.out.rights = &user_rights;
3369 status = dcerpc_lsa_EnumAccountRights(lp, tctx, &r);
3370 torture_assert_ntstatus_ok(tctx, status,
3371 "Failed to enum rights for account");
3373 if (user_rights.count < 1) {
3374 torture_warning(tctx, "failed to find newly added rights");
3380 struct lsa_OpenAccount r;
3382 printf("Testing LSA OpenAccount\n");
3384 r.in.handle = lsa_handle;
3385 r.in.sid = user_sid;
3386 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3387 r.out.acct_handle = &lsa_acct_handle;
3389 status = dcerpc_lsa_OpenAccount(lp, tctx, &r);
3390 torture_assert_ntstatus_ok(tctx, status,
3391 "Failed to open lsa account");
3395 struct lsa_GetSystemAccessAccount r;
3396 uint32_t access_mask;
3398 printf("Testing LSA GetSystemAccessAccount\n");
3400 r.in.handle = &lsa_acct_handle;
3401 r.out.access_mask = &access_mask;
3403 status = dcerpc_lsa_GetSystemAccessAccount(lp, tctx, &r);
3404 torture_assert_ntstatus_ok(tctx, status,
3405 "Failed to get lsa system access account");
3411 printf("Testing LSA Close\n");
3413 r.in.handle = &lsa_acct_handle;
3414 r.out.handle = &lsa_acct_handle;
3416 status = dcerpc_lsa_Close(lp, tctx, &r);
3417 torture_assert_ntstatus_ok(tctx, status,
3418 "Failed to close lsa");
3422 struct samr_DeleteUser r;
3424 printf("Testing SAMR DeleteUser\n");
3426 r.in.user_handle = user_handle;
3427 r.out.user_handle = user_handle;
3429 status = dcerpc_samr_DeleteUser(p, tctx, &r);
3430 torture_assert_ntstatus_ok(tctx, status, "Delete User failed");
3434 struct lsa_EnumAccounts r;
3435 uint32_t resume_handle = 0;
3436 struct lsa_SidArray lsa_sid_array;
3438 bool found_sid = false;
3440 printf("Testing LSA EnumAccounts\n");
3442 r.in.handle = lsa_handle;
3443 r.in.num_entries = 0x1000;
3444 r.in.resume_handle = &resume_handle;
3445 r.out.sids = &lsa_sid_array;
3446 r.out.resume_handle = &resume_handle;
3448 status = dcerpc_lsa_EnumAccounts(lp, tctx, &r);
3449 torture_assert_ntstatus_ok(tctx, status,
3450 "Failed to enum accounts");
3452 for (i=0; i < lsa_sid_array.num_sids; i++) {
3453 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
3458 torture_assert(tctx, found_sid,
3459 "failed to list privileged account");
3463 struct lsa_EnumAccountRights r;
3464 struct lsa_RightSet user_rights;
3466 printf("Testing LSA EnumAccountRights\n");
3468 r.in.handle = lsa_handle;
3469 r.in.sid = user_sid;
3470 r.out.rights = &user_rights;
3472 status = dcerpc_lsa_EnumAccountRights(lp, tctx, &r);
3473 torture_assert_ntstatus_ok(tctx, status,
3474 "Failed to enum rights for account");
3476 if (user_rights.count < 1) {
3477 torture_warning(tctx, "failed to find newly added rights");
3483 struct lsa_OpenAccount r;
3485 printf("Testing LSA OpenAccount\n");
3487 r.in.handle = lsa_handle;
3488 r.in.sid = user_sid;
3489 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3490 r.out.acct_handle = &lsa_acct_handle;
3492 status = dcerpc_lsa_OpenAccount(lp, tctx, &r);
3493 torture_assert_ntstatus_ok(tctx, status,
3494 "Failed to open lsa account");
3498 struct lsa_GetSystemAccessAccount r;
3499 uint32_t access_mask;
3501 printf("Testing LSA GetSystemAccessAccount\n");
3503 r.in.handle = &lsa_acct_handle;
3504 r.out.access_mask = &access_mask;
3506 status = dcerpc_lsa_GetSystemAccessAccount(lp, tctx, &r);
3507 torture_assert_ntstatus_ok(tctx, status,
3508 "Failed to get lsa system access account");
3512 struct lsa_DeleteObject r;
3514 printf("Testing LSA DeleteObject\n");
3516 r.in.handle = &lsa_acct_handle;
3517 r.out.handle = &lsa_acct_handle;
3519 status = dcerpc_lsa_DeleteObject(lp, tctx, &r);
3520 torture_assert_ntstatus_ok(tctx, status,
3521 "Failed to delete object");
3525 struct lsa_EnumAccounts r;
3526 uint32_t resume_handle = 0;
3527 struct lsa_SidArray lsa_sid_array;
3529 bool found_sid = false;
3531 printf("Testing LSA EnumAccounts\n");
3533 r.in.handle = lsa_handle;
3534 r.in.num_entries = 0x1000;
3535 r.in.resume_handle = &resume_handle;
3536 r.out.sids = &lsa_sid_array;
3537 r.out.resume_handle = &resume_handle;
3539 status = dcerpc_lsa_EnumAccounts(lp, tctx, &r);
3540 torture_assert_ntstatus_ok(tctx, status,
3541 "Failed to enum accounts");
3543 for (i=0; i < lsa_sid_array.num_sids; i++) {
3544 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
3549 torture_assert(tctx, !found_sid,
3550 "should not have listed privileged account");
3554 struct lsa_EnumAccountRights r;
3555 struct lsa_RightSet user_rights;
3557 printf("Testing LSA EnumAccountRights\n");
3559 r.in.handle = lsa_handle;
3560 r.in.sid = user_sid;
3561 r.out.rights = &user_rights;
3563 status = dcerpc_lsa_EnumAccountRights(lp, tctx, &r);
3564 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3565 "Failed to enum rights for account");
3571 static bool test_user_ops(struct dcerpc_pipe *p,
3572 struct torture_context *tctx,
3573 struct policy_handle *user_handle,
3574 struct policy_handle *domain_handle,
3575 const struct dom_sid *domain_sid,
3576 uint32_t base_acct_flags,
3577 const char *base_acct_name, enum torture_samr_choice which_ops,
3578 struct cli_credentials *machine_credentials)
3580 char *password = NULL;
3581 struct samr_QueryUserInfo q;
3582 union samr_UserInfo *info;
3588 const uint32_t password_fields[] = {
3589 SAMR_FIELD_NT_PASSWORD_PRESENT,
3590 SAMR_FIELD_LM_PASSWORD_PRESENT,
3591 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
3595 status = test_LookupName(p, tctx, domain_handle, base_acct_name, &rid);
3596 if (!NT_STATUS_IS_OK(status)) {
3600 switch (which_ops) {
3601 case TORTURE_SAMR_USER_ATTRIBUTES:
3602 if (!test_QuerySecurity(p, tctx, user_handle)) {
3606 if (!test_QueryUserInfo(p, tctx, user_handle)) {
3610 if (!test_QueryUserInfo2(p, tctx, user_handle)) {
3614 if (!test_SetUserInfo(p, tctx, user_handle, base_acct_flags,
3619 if (!test_GetUserPwInfo(p, tctx, user_handle)) {
3623 if (!test_TestPrivateFunctionsUser(p, tctx, user_handle)) {
3627 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
3631 case TORTURE_SAMR_PASSWORDS:
3632 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
3633 char simple_pass[9];
3634 char *v = generate_random_str(tctx, 1);
3636 ZERO_STRUCT(simple_pass);
3637 memset(simple_pass, *v, sizeof(simple_pass) - 1);
3639 printf("Testing machine account password policy rules\n");
3641 /* Workstation trust accounts don't seem to need to honour password quality policy */
3642 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
3646 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
3650 /* reset again, to allow another 'user' password change */
3651 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
3655 /* Try a 'short' password */
3656 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
3660 /* Try a compleatly random password */
3661 if (!test_ChangePasswordRandomBytes(p, tctx, base_acct_name, user_handle, &password)) {
3666 for (i = 0; password_fields[i]; i++) {
3667 if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
3671 /* check it was set right */
3672 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3677 for (i = 0; password_fields[i]; i++) {
3678 if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
3682 /* check it was set right */
3683 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3688 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
3692 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
3696 if (torture_setting_bool(tctx, "samba4", false)) {
3697 printf("skipping Set Password level 18 and 21 against Samba4\n");
3700 if (!test_SetUserPass_18(p, tctx, user_handle, &password)) {
3704 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3708 for (i = 0; password_fields[i]; i++) {
3710 if (password_fields[i] == SAMR_FIELD_LM_PASSWORD_PRESENT) {
3711 /* we need to skip as that would break
3712 * the ChangePasswordUser3 verify */
3716 if (!test_SetUserPass_21(p, tctx, user_handle, password_fields[i], &password)) {
3720 /* check it was set right */
3721 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3727 q.in.user_handle = user_handle;
3731 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
3732 if (!NT_STATUS_IS_OK(status)) {
3733 printf("QueryUserInfo level %u failed - %s\n",
3734 q.in.level, nt_errstr(status));
3737 uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
3738 if ((info->info5.acct_flags) != expected_flags) {
3739 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
3740 info->info5.acct_flags,
3743 if (!torture_setting_bool(tctx, "samba3", false)) {
3747 if (info->info5.rid != rid) {
3748 printf("QuerUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
3749 info->info5.rid, rid);
3756 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
3758 /* test last password change timestamp behaviour */
3759 if (!test_SetPassword_pwdlastset(p, tctx, base_acct_flags,
3761 user_handle, &password,
3762 machine_credentials)) {
3767 torture_comment(tctx, "pwdLastSet test succeeded\n");
3769 torture_warning(tctx, "pwdLastSet test failed\n");
3774 case TORTURE_SAMR_USER_PRIVILEGES: {
3776 struct dcerpc_pipe *lp;
3777 struct policy_handle *lsa_handle;
3779 status = torture_rpc_connection(tctx, &lp, &ndr_table_lsarpc);
3780 torture_assert_ntstatus_ok(tctx, status, "Failed to open LSA pipe");
3782 if (!test_lsa_OpenPolicy2(lp, tctx, &lsa_handle)) {
3786 if (!test_DeleteUser_with_privs(p, lp, tctx,
3787 domain_handle, lsa_handle, user_handle,
3789 machine_credentials)) {
3793 if (!test_lsa_Close(lp, tctx, lsa_handle)) {
3798 torture_warning(tctx, "privileged user delete test failed\n");
3803 case TORTURE_SAMR_OTHER:
3804 /* We just need the account to exist */
3810 static bool test_alias_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
3811 struct policy_handle *alias_handle,
3812 const struct dom_sid *domain_sid)
3816 if (!torture_setting_bool(tctx, "samba3", false)) {
3817 if (!test_QuerySecurity(p, tctx, alias_handle)) {
3822 if (!test_QueryAliasInfo(p, tctx, alias_handle)) {
3826 if (!test_SetAliasInfo(p, tctx, alias_handle)) {
3830 if (!test_AddMemberToAlias(p, tctx, alias_handle, domain_sid)) {
3834 if (torture_setting_bool(tctx, "samba4", false)) {
3835 printf("skipping MultipleMembers Alias tests against Samba4\n");
3839 if (!test_AddMultipleMembersToAlias(p, tctx, alias_handle)) {
3847 static bool test_DeleteUser(struct dcerpc_pipe *p, struct torture_context *tctx,
3848 struct policy_handle *user_handle)
3850 struct samr_DeleteUser d;
3852 torture_comment(tctx, "Testing DeleteUser\n");
3854 d.in.user_handle = user_handle;
3855 d.out.user_handle = user_handle;
3857 status = dcerpc_samr_DeleteUser(p, tctx, &d);
3858 torture_assert_ntstatus_ok(tctx, status, "DeleteUser");
3863 bool test_DeleteUser_byname(struct dcerpc_pipe *p,
3864 struct torture_context *tctx,
3865 struct policy_handle *handle, const char *name)
3868 struct samr_DeleteUser d;
3869 struct policy_handle user_handle;
3872 status = test_LookupName(p, tctx, handle, name, &rid);
3873 if (!NT_STATUS_IS_OK(status)) {
3877 status = test_OpenUser_byname(p, tctx, handle, name, &user_handle);
3878 if (!NT_STATUS_IS_OK(status)) {
3882 d.in.user_handle = &user_handle;
3883 d.out.user_handle = &user_handle;
3884 status = dcerpc_samr_DeleteUser(p, tctx, &d);
3885 if (!NT_STATUS_IS_OK(status)) {
3892 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
3897 static bool test_DeleteGroup_byname(struct dcerpc_pipe *p,
3898 struct torture_context *tctx,
3899 struct policy_handle *handle, const char *name)
3902 struct samr_OpenGroup r;
3903 struct samr_DeleteDomainGroup d;
3904 struct policy_handle group_handle;
3907 status = test_LookupName(p, tctx, handle, name, &rid);
3908 if (!NT_STATUS_IS_OK(status)) {
3912 r.in.domain_handle = handle;
3913 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3915 r.out.group_handle = &group_handle;
3916 status = dcerpc_samr_OpenGroup(p, tctx, &r);
3917 if (!NT_STATUS_IS_OK(status)) {
3921 d.in.group_handle = &group_handle;
3922 d.out.group_handle = &group_handle;
3923 status = dcerpc_samr_DeleteDomainGroup(p, tctx, &d);
3924 if (!NT_STATUS_IS_OK(status)) {
3931 printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
3936 static bool test_DeleteAlias_byname(struct dcerpc_pipe *p,
3937 struct torture_context *tctx,
3938 struct policy_handle *domain_handle,
3942 struct samr_OpenAlias r;
3943 struct samr_DeleteDomAlias d;
3944 struct policy_handle alias_handle;
3947 printf("testing DeleteAlias_byname\n");
3949 status = test_LookupName(p, tctx, domain_handle, name, &rid);
3950 if (!NT_STATUS_IS_OK(status)) {
3954 r.in.domain_handle = domain_handle;
3955 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3957 r.out.alias_handle = &alias_handle;
3958 status = dcerpc_samr_OpenAlias(p, tctx, &r);
3959 if (!NT_STATUS_IS_OK(status)) {
3963 d.in.alias_handle = &alias_handle;
3964 d.out.alias_handle = &alias_handle;
3965 status = dcerpc_samr_DeleteDomAlias(p, tctx, &d);
3966 if (!NT_STATUS_IS_OK(status)) {
3973 printf("DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
3977 static bool test_DeleteAlias(struct dcerpc_pipe *p,
3978 struct torture_context *tctx,
3979 struct policy_handle *alias_handle)
3981 struct samr_DeleteDomAlias d;
3984 printf("Testing DeleteAlias\n");
3986 d.in.alias_handle = alias_handle;
3987 d.out.alias_handle = alias_handle;
3989 status = dcerpc_samr_DeleteDomAlias(p, tctx, &d);
3990 if (!NT_STATUS_IS_OK(status)) {
3991 printf("DeleteAlias failed - %s\n", nt_errstr(status));
3998 static bool test_CreateAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
3999 struct policy_handle *domain_handle,
4000 const char *alias_name,
4001 struct policy_handle *alias_handle,
4002 const struct dom_sid *domain_sid,
4006 struct samr_CreateDomAlias r;
4007 struct lsa_String name;
4011 init_lsa_String(&name, alias_name);
4012 r.in.domain_handle = domain_handle;
4013 r.in.alias_name = &name;
4014 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4015 r.out.alias_handle = alias_handle;
4018 printf("Testing CreateAlias (%s)\n", r.in.alias_name->string);
4020 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
4022 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
4023 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
4024 printf("Server correctly refused create of '%s'\n", r.in.alias_name->string);
4027 printf("Server should have refused create of '%s', got %s instead\n", r.in.alias_name->string,
4033 if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
4034 if (!test_DeleteAlias_byname(p, tctx, domain_handle, r.in.alias_name->string)) {
4037 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
4040 if (!NT_STATUS_IS_OK(status)) {
4041 printf("CreateAlias failed - %s\n", nt_errstr(status));
4049 if (!test_alias_ops(p, tctx, alias_handle, domain_sid)) {
4056 static bool test_ChangePassword(struct dcerpc_pipe *p,
4057 struct torture_context *tctx,
4058 const char *acct_name,
4059 struct policy_handle *domain_handle, char **password)
4067 if (!test_ChangePasswordUser(p, tctx, acct_name, domain_handle, password)) {
4071 if (!test_ChangePasswordUser2(p, tctx, acct_name, password, 0, true)) {
4075 if (!test_OemChangePasswordUser2(p, tctx, acct_name, domain_handle, password)) {
4079 /* test what happens when setting the old password again */
4080 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, *password, 0, true)) {
4085 char simple_pass[9];
4086 char *v = generate_random_str(tctx, 1);
4088 ZERO_STRUCT(simple_pass);
4089 memset(simple_pass, *v, sizeof(simple_pass) - 1);
4091 /* test what happens when picking a simple password */
4092 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, simple_pass, 0, true)) {
4097 /* set samr_SetDomainInfo level 1 with min_length 5 */
4099 struct samr_QueryDomainInfo r;
4100 union samr_DomainInfo *info = NULL;
4101 struct samr_SetDomainInfo s;
4102 uint16_t len_old, len;
4103 uint32_t pwd_prop_old;
4104 int64_t min_pwd_age_old;
4109 r.in.domain_handle = domain_handle;
4113 printf("testing samr_QueryDomainInfo level 1\n");
4114 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
4115 if (!NT_STATUS_IS_OK(status)) {
4119 s.in.domain_handle = domain_handle;
4123 /* remember the old min length, so we can reset it */
4124 len_old = s.in.info->info1.min_password_length;
4125 s.in.info->info1.min_password_length = len;
4126 pwd_prop_old = s.in.info->info1.password_properties;
4127 /* turn off password complexity checks for this test */
4128 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
4130 min_pwd_age_old = s.in.info->info1.min_password_age;
4131 s.in.info->info1.min_password_age = 0;
4133 printf("testing samr_SetDomainInfo level 1\n");
4134 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
4135 if (!NT_STATUS_IS_OK(status)) {
4139 printf("calling test_ChangePasswordUser3 with too short password\n");
4141 if (!test_ChangePasswordUser3(p, tctx, acct_name, len - 1, password, NULL, 0, true)) {
4145 s.in.info->info1.min_password_length = len_old;
4146 s.in.info->info1.password_properties = pwd_prop_old;
4147 s.in.info->info1.min_password_age = min_pwd_age_old;
4149 printf("testing samr_SetDomainInfo level 1\n");
4150 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
4151 if (!NT_STATUS_IS_OK(status)) {
4159 struct samr_OpenUser r;
4160 struct samr_QueryUserInfo q;
4161 union samr_UserInfo *info;
4162 struct samr_LookupNames n;
4163 struct policy_handle user_handle;
4164 struct samr_Ids rids, types;
4166 n.in.domain_handle = domain_handle;
4168 n.in.names = talloc_array(tctx, struct lsa_String, 1);
4169 n.in.names[0].string = acct_name;
4171 n.out.types = &types;
4173 status = dcerpc_samr_LookupNames(p, tctx, &n);
4174 if (!NT_STATUS_IS_OK(status)) {
4175 printf("LookupNames failed - %s\n", nt_errstr(status));
4179 r.in.domain_handle = domain_handle;
4180 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4181 r.in.rid = n.out.rids->ids[0];
4182 r.out.user_handle = &user_handle;
4184 status = dcerpc_samr_OpenUser(p, tctx, &r);
4185 if (!NT_STATUS_IS_OK(status)) {
4186 printf("OpenUser(%u) failed - %s\n", n.out.rids->ids[0], nt_errstr(status));
4190 q.in.user_handle = &user_handle;
4194 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
4195 if (!NT_STATUS_IS_OK(status)) {
4196 printf("QueryUserInfo failed - %s\n", nt_errstr(status));
4200 printf("calling test_ChangePasswordUser3 with too early password change\n");
4202 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL,
4203 info->info5.last_password_change, true)) {
4208 /* we change passwords twice - this has the effect of verifying
4209 they were changed correctly for the final call */
4210 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
4214 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
4221 static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
4222 struct policy_handle *domain_handle,
4223 const char *user_name,
4224 struct policy_handle *user_handle_out,
4225 struct dom_sid *domain_sid,
4226 enum torture_samr_choice which_ops,
4227 struct cli_credentials *machine_credentials,
4231 TALLOC_CTX *user_ctx;
4234 struct samr_CreateUser r;
4235 struct samr_QueryUserInfo q;
4236 union samr_UserInfo *info;
4237 struct samr_DeleteUser d;
4240 /* This call creates a 'normal' account - check that it really does */
4241 const uint32_t acct_flags = ACB_NORMAL;
4242 struct lsa_String name;
4245 struct policy_handle user_handle;
4246 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
4247 init_lsa_String(&name, user_name);
4249 r.in.domain_handle = domain_handle;
4250 r.in.account_name = &name;
4251 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4252 r.out.user_handle = &user_handle;
4255 printf("Testing CreateUser(%s)\n", r.in.account_name->string);
4257 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
4259 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
4260 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
4261 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
4264 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
4270 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
4271 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
4272 talloc_free(user_ctx);
4275 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
4278 if (!NT_STATUS_IS_OK(status)) {
4279 talloc_free(user_ctx);
4280 printf("CreateUser failed - %s\n", nt_errstr(status));
4285 if (user_handle_out) {
4286 *user_handle_out = user_handle;
4292 q.in.user_handle = &user_handle;
4296 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
4297 if (!NT_STATUS_IS_OK(status)) {
4298 printf("QueryUserInfo level %u failed - %s\n",
4299 q.in.level, nt_errstr(status));
4302 if ((info->info16.acct_flags & acct_flags) != acct_flags) {
4303 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
4304 info->info16.acct_flags,
4310 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
4311 domain_sid, acct_flags, name.string, which_ops,
4312 machine_credentials)) {
4316 if (user_handle_out) {
4317 *user_handle_out = user_handle;
4319 printf("Testing DeleteUser (createuser test)\n");
4321 d.in.user_handle = &user_handle;
4322 d.out.user_handle = &user_handle;
4324 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
4325 if (!NT_STATUS_IS_OK(status)) {
4326 printf("DeleteUser failed - %s\n", nt_errstr(status));
4333 talloc_free(user_ctx);
4339 static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
4340 struct policy_handle *domain_handle,
4341 struct dom_sid *domain_sid,
4342 enum torture_samr_choice which_ops,
4343 struct cli_credentials *machine_credentials)
4346 struct samr_CreateUser2 r;
4347 struct samr_QueryUserInfo q;
4348 union samr_UserInfo *info;
4349 struct samr_DeleteUser d;
4350 struct policy_handle user_handle;
4352 struct lsa_String name;
4357 uint32_t acct_flags;
4358 const char *account_name;
4360 } account_types[] = {
4361 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
4362 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
4363 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
4364 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
4365 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
4366 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
4367 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
4368 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
4369 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
4370 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
4371 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
4372 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
4373 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
4374 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
4375 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
4378 for (i = 0; account_types[i].account_name; i++) {
4379 TALLOC_CTX *user_ctx;
4380 uint32_t acct_flags = account_types[i].acct_flags;
4381 uint32_t access_granted;
4382 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
4383 init_lsa_String(&name, account_types[i].account_name);
4385 r.in.domain_handle = domain_handle;
4386 r.in.account_name = &name;
4387 r.in.acct_flags = acct_flags;
4388 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4389 r.out.user_handle = &user_handle;
4390 r.out.access_granted = &access_granted;
4393 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
4395 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
4397 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
4398 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
4399 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
4402 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
4409 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
4410 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
4411 talloc_free(user_ctx);
4415 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
4418 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
4419 printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
4420 nt_errstr(status), nt_errstr(account_types[i].nt_status));
4424 if (NT_STATUS_IS_OK(status)) {
4425 q.in.user_handle = &user_handle;
4429 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
4430 if (!NT_STATUS_IS_OK(status)) {
4431 printf("QueryUserInfo level %u failed - %s\n",
4432 q.in.level, nt_errstr(status));
4435 uint32_t expected_flags = (acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
4436 if (acct_flags == ACB_NORMAL) {
4437 expected_flags |= ACB_PW_EXPIRED;
4439 if ((info->info5.acct_flags) != expected_flags) {
4440 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
4441 info->info5.acct_flags,
4445 switch (acct_flags) {
4447 if (info->info5.primary_gid != DOMAIN_RID_DCS) {
4448 printf("QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n",
4449 DOMAIN_RID_DCS, info->info5.primary_gid);
4454 if (info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
4455 printf("QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
4456 DOMAIN_RID_DOMAIN_MEMBERS, info->info5.primary_gid);
4461 if (info->info5.primary_gid != DOMAIN_RID_USERS) {
4462 printf("QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n",
4463 DOMAIN_RID_USERS, info->info5.primary_gid);
4470 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
4471 domain_sid, acct_flags, name.string, which_ops,
4472 machine_credentials)) {
4476 if (!policy_handle_empty(&user_handle)) {
4477 printf("Testing DeleteUser (createuser2 test)\n");
4479 d.in.user_handle = &user_handle;
4480 d.out.user_handle = &user_handle;
4482 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
4483 if (!NT_STATUS_IS_OK(status)) {
4484 printf("DeleteUser failed - %s\n", nt_errstr(status));
4489 talloc_free(user_ctx);
4495 static bool test_QueryAliasInfo(struct dcerpc_pipe *p,
4496 struct torture_context *tctx,
4497 struct policy_handle *handle)
4500 struct samr_QueryAliasInfo r;
4501 union samr_AliasInfo *info;
4502 uint16_t levels[] = {1, 2, 3};
4506 for (i=0;i<ARRAY_SIZE(levels);i++) {
4507 printf("Testing QueryAliasInfo level %u\n", levels[i]);
4509 r.in.alias_handle = handle;
4510 r.in.level = levels[i];
4513 status = dcerpc_samr_QueryAliasInfo(p, tctx, &r);
4514 if (!NT_STATUS_IS_OK(status)) {
4515 printf("QueryAliasInfo level %u failed - %s\n",
4516 levels[i], nt_errstr(status));
4524 static bool test_QueryGroupInfo(struct dcerpc_pipe *p,
4525 struct torture_context *tctx,
4526 struct policy_handle *handle)
4529 struct samr_QueryGroupInfo r;
4530 union samr_GroupInfo *info;
4531 uint16_t levels[] = {1, 2, 3, 4, 5};
4535 for (i=0;i<ARRAY_SIZE(levels);i++) {
4536 printf("Testing QueryGroupInfo level %u\n", levels[i]);
4538 r.in.group_handle = handle;
4539 r.in.level = levels[i];
4542 status = dcerpc_samr_QueryGroupInfo(p, tctx, &r);
4543 if (!NT_STATUS_IS_OK(status)) {
4544 printf("QueryGroupInfo level %u failed - %s\n",
4545 levels[i], nt_errstr(status));
4553 static bool test_QueryGroupMember(struct dcerpc_pipe *p,
4554 struct torture_context *tctx,
4555 struct policy_handle *handle)
4558 struct samr_QueryGroupMember r;
4559 struct samr_RidTypeArray *rids = NULL;
4562 printf("Testing QueryGroupMember\n");
4564 r.in.group_handle = handle;
4567 status = dcerpc_samr_QueryGroupMember(p, tctx, &r);
4568 if (!NT_STATUS_IS_OK(status)) {
4569 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
4577 static bool test_SetGroupInfo(struct dcerpc_pipe *p,
4578 struct torture_context *tctx,
4579 struct policy_handle *handle)
4582 struct samr_QueryGroupInfo r;
4583 union samr_GroupInfo *info;
4584 struct samr_SetGroupInfo s;
4585 uint16_t levels[] = {1, 2, 3, 4};
4586 uint16_t set_ok[] = {0, 1, 1, 1};
4590 for (i=0;i<ARRAY_SIZE(levels);i++) {
4591 printf("Testing QueryGroupInfo level %u\n", levels[i]);
4593 r.in.group_handle = handle;
4594 r.in.level = levels[i];
4597 status = dcerpc_samr_QueryGroupInfo(p, tctx, &r);
4598 if (!NT_STATUS_IS_OK(status)) {
4599 printf("QueryGroupInfo level %u failed - %s\n",
4600 levels[i], nt_errstr(status));
4604 printf("Testing SetGroupInfo level %u\n", levels[i]);
4606 s.in.group_handle = handle;
4607 s.in.level = levels[i];
4608 s.in.info = *r.out.info;
4611 /* disabled this, as it changes the name only from the point of view of samr,
4612 but leaves the name from the point of view of w2k3 internals (and ldap). This means
4613 the name is still reserved, so creating the old name fails, but deleting by the old name
4615 if (s.in.level == 2) {
4616 init_lsa_String(&s.in.info->string, "NewName");
4620 if (s.in.level == 4) {
4621 init_lsa_String(&s.in.info->description, "test description");
4624 status = dcerpc_samr_SetGroupInfo(p, tctx, &s);
4626 if (!NT_STATUS_IS_OK(status)) {
4627 printf("SetGroupInfo level %u failed - %s\n",
4628 r.in.level, nt_errstr(status));
4633 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
4634 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
4635 r.in.level, nt_errstr(status));
4645 static bool test_QueryUserInfo(struct dcerpc_pipe *p,
4646 struct torture_context *tctx,
4647 struct policy_handle *handle)
4650 struct samr_QueryUserInfo r;
4651 union samr_UserInfo *info;
4652 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
4653 11, 12, 13, 14, 16, 17, 20, 21};
4657 for (i=0;i<ARRAY_SIZE(levels);i++) {
4658 printf("Testing QueryUserInfo level %u\n", levels[i]);
4660 r.in.user_handle = handle;
4661 r.in.level = levels[i];
4664 status = dcerpc_samr_QueryUserInfo(p, tctx, &r);
4665 if (!NT_STATUS_IS_OK(status)) {
4666 printf("QueryUserInfo level %u failed - %s\n",
4667 levels[i], nt_errstr(status));
4675 static bool test_QueryUserInfo2(struct dcerpc_pipe *p,
4676 struct torture_context *tctx,
4677 struct policy_handle *handle)
4680 struct samr_QueryUserInfo2 r;
4681 union samr_UserInfo *info;
4682 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
4683 11, 12, 13, 14, 16, 17, 20, 21};
4687 for (i=0;i<ARRAY_SIZE(levels);i++) {
4688 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
4690 r.in.user_handle = handle;
4691 r.in.level = levels[i];
4694 status = dcerpc_samr_QueryUserInfo2(p, tctx, &r);
4695 if (!NT_STATUS_IS_OK(status)) {
4696 printf("QueryUserInfo2 level %u failed - %s\n",
4697 levels[i], nt_errstr(status));
4705 static bool test_OpenUser(struct dcerpc_pipe *p,
4706 struct torture_context *tctx,
4707 struct policy_handle *handle, uint32_t rid)
4710 struct samr_OpenUser r;
4711 struct policy_handle user_handle;
4714 printf("Testing OpenUser(%u)\n", rid);
4716 r.in.domain_handle = handle;
4717 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4719 r.out.user_handle = &user_handle;
4721 status = dcerpc_samr_OpenUser(p, tctx, &r);
4722 if (!NT_STATUS_IS_OK(status)) {
4723 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
4727 if (!test_QuerySecurity(p, tctx, &user_handle)) {
4731 if (!test_QueryUserInfo(p, tctx, &user_handle)) {
4735 if (!test_QueryUserInfo2(p, tctx, &user_handle)) {
4739 if (!test_GetUserPwInfo(p, tctx, &user_handle)) {
4743 if (!test_GetGroupsForUser(p,tctx, &user_handle)) {
4747 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
4754 static bool test_OpenGroup(struct dcerpc_pipe *p,
4755 struct torture_context *tctx,
4756 struct policy_handle *handle, uint32_t rid)
4759 struct samr_OpenGroup r;
4760 struct policy_handle group_handle;
4763 printf("Testing OpenGroup(%u)\n", rid);
4765 r.in.domain_handle = handle;
4766 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4768 r.out.group_handle = &group_handle;
4770 status = dcerpc_samr_OpenGroup(p, tctx, &r);
4771 if (!NT_STATUS_IS_OK(status)) {
4772 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
4776 if (!torture_setting_bool(tctx, "samba3", false)) {
4777 if (!test_QuerySecurity(p, tctx, &group_handle)) {
4782 if (!test_QueryGroupInfo(p, tctx, &group_handle)) {
4786 if (!test_QueryGroupMember(p, tctx, &group_handle)) {
4790 if (!test_samr_handle_Close(p, tctx, &group_handle)) {
4797 static bool test_OpenAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
4798 struct policy_handle *handle, uint32_t rid)
4801 struct samr_OpenAlias r;
4802 struct policy_handle alias_handle;
4805 torture_comment(tctx, "Testing OpenAlias(%u)\n", rid);
4807 r.in.domain_handle = handle;
4808 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4810 r.out.alias_handle = &alias_handle;
4812 status = dcerpc_samr_OpenAlias(p, tctx, &r);
4813 if (!NT_STATUS_IS_OK(status)) {
4814 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
4818 if (!torture_setting_bool(tctx, "samba3", false)) {
4819 if (!test_QuerySecurity(p, tctx, &alias_handle)) {
4824 if (!test_QueryAliasInfo(p, tctx, &alias_handle)) {
4828 if (!test_GetMembersInAlias(p, tctx, &alias_handle)) {
4832 if (!test_samr_handle_Close(p, tctx, &alias_handle)) {
4839 static bool check_mask(struct dcerpc_pipe *p, struct torture_context *tctx,
4840 struct policy_handle *handle, uint32_t rid,
4841 uint32_t acct_flag_mask)
4844 struct samr_OpenUser r;
4845 struct samr_QueryUserInfo q;
4846 union samr_UserInfo *info;
4847 struct policy_handle user_handle;
4850 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
4852 r.in.domain_handle = handle;
4853 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4855 r.out.user_handle = &user_handle;
4857 status = dcerpc_samr_OpenUser(p, tctx, &r);
4858 if (!NT_STATUS_IS_OK(status)) {
4859 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
4863 q.in.user_handle = &user_handle;
4867 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
4868 if (!NT_STATUS_IS_OK(status)) {
4869 printf("QueryUserInfo level 16 failed - %s\n",
4873 if ((acct_flag_mask & info->info16.acct_flags) == 0) {
4874 printf("Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
4875 acct_flag_mask, info->info16.acct_flags, rid);
4880 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
4887 static bool test_EnumDomainUsers_all(struct dcerpc_pipe *p,
4888 struct torture_context *tctx,
4889 struct policy_handle *handle)
4891 NTSTATUS status = STATUS_MORE_ENTRIES;
4892 struct samr_EnumDomainUsers r;
4893 uint32_t mask, resume_handle=0;
4896 struct samr_LookupNames n;
4897 struct samr_LookupRids lr ;
4898 struct lsa_Strings names;
4899 struct samr_Ids rids, types;
4900 struct samr_SamArray *sam = NULL;
4901 uint32_t num_entries = 0;
4903 uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
4904 ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
4905 ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
4908 printf("Testing EnumDomainUsers\n");
4910 for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
4911 r.in.domain_handle = handle;
4912 r.in.resume_handle = &resume_handle;
4913 r.in.acct_flags = mask = masks[mask_idx];
4914 r.in.max_size = (uint32_t)-1;
4915 r.out.resume_handle = &resume_handle;
4916 r.out.num_entries = &num_entries;
4919 status = dcerpc_samr_EnumDomainUsers(p, tctx, &r);
4920 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
4921 !NT_STATUS_IS_OK(status)) {
4922 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
4926 torture_assert(tctx, sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
4928 if (sam->count == 0) {
4932 for (i=0;i<sam->count;i++) {
4934 if (!check_mask(p, tctx, handle, sam->entries[i].idx, mask)) {
4937 } else if (!test_OpenUser(p, tctx, handle, sam->entries[i].idx)) {
4943 printf("Testing LookupNames\n");
4944 n.in.domain_handle = handle;
4945 n.in.num_names = sam->count;
4946 n.in.names = talloc_array(tctx, struct lsa_String, sam->count);
4948 n.out.types = &types;
4949 for (i=0;i<sam->count;i++) {
4950 n.in.names[i].string = sam->entries[i].name.string;
4952 status = dcerpc_samr_LookupNames(p, tctx, &n);
4953 if (!NT_STATUS_IS_OK(status)) {
4954 printf("LookupNames failed - %s\n", nt_errstr(status));
4959 printf("Testing LookupRids\n");
4960 lr.in.domain_handle = handle;
4961 lr.in.num_rids = sam->count;
4962 lr.in.rids = talloc_array(tctx, uint32_t, sam->count);
4963 lr.out.names = &names;
4964 lr.out.types = &types;
4965 for (i=0;i<sam->count;i++) {
4966 lr.in.rids[i] = sam->entries[i].idx;
4968 status = dcerpc_samr_LookupRids(p, tctx, &lr);
4969 torture_assert_ntstatus_ok(tctx, status, "LookupRids");
4975 try blasting the server with a bunch of sync requests
4977 static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, struct torture_context *tctx,
4978 struct policy_handle *handle)
4981 struct samr_EnumDomainUsers r;
4982 uint32_t resume_handle=0;
4984 #define ASYNC_COUNT 100
4985 struct rpc_request *req[ASYNC_COUNT];
4987 if (!torture_setting_bool(tctx, "dangerous", false)) {
4988 torture_skip(tctx, "samr async test disabled - enable dangerous tests to use\n");
4991 torture_comment(tctx, "Testing EnumDomainUsers_async\n");
4993 r.in.domain_handle = handle;
4994 r.in.resume_handle = &resume_handle;
4995 r.in.acct_flags = 0;
4996 r.in.max_size = (uint32_t)-1;
4997 r.out.resume_handle = &resume_handle;
4999 for (i=0;i<ASYNC_COUNT;i++) {
5000 req[i] = dcerpc_samr_EnumDomainUsers_send(p, tctx, &r);
5003 for (i=0;i<ASYNC_COUNT;i++) {
5004 status = dcerpc_ndr_request_recv(req[i]);
5005 if (!NT_STATUS_IS_OK(status)) {
5006 printf("EnumDomainUsers[%d] failed - %s\n",
5007 i, nt_errstr(status));
5012 torture_comment(tctx, "%d async requests OK\n", i);
5017 static bool test_EnumDomainGroups_all(struct dcerpc_pipe *p,
5018 struct torture_context *tctx,
5019 struct policy_handle *handle)
5022 struct samr_EnumDomainGroups r;
5023 uint32_t resume_handle=0;
5024 struct samr_SamArray *sam = NULL;
5025 uint32_t num_entries = 0;
5029 printf("Testing EnumDomainGroups\n");
5031 r.in.domain_handle = handle;
5032 r.in.resume_handle = &resume_handle;
5033 r.in.max_size = (uint32_t)-1;
5034 r.out.resume_handle = &resume_handle;
5035 r.out.num_entries = &num_entries;
5038 status = dcerpc_samr_EnumDomainGroups(p, tctx, &r);
5039 if (!NT_STATUS_IS_OK(status)) {
5040 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
5048 for (i=0;i<sam->count;i++) {
5049 if (!test_OpenGroup(p, tctx, handle, sam->entries[i].idx)) {
5057 static bool test_EnumDomainAliases_all(struct dcerpc_pipe *p,
5058 struct torture_context *tctx,
5059 struct policy_handle *handle)
5062 struct samr_EnumDomainAliases r;
5063 uint32_t resume_handle=0;
5064 struct samr_SamArray *sam = NULL;
5065 uint32_t num_entries = 0;
5069 printf("Testing EnumDomainAliases\n");
5071 r.in.domain_handle = handle;
5072 r.in.resume_handle = &resume_handle;
5073 r.in.max_size = (uint32_t)-1;
5075 r.out.num_entries = &num_entries;
5076 r.out.resume_handle = &resume_handle;
5078 status = dcerpc_samr_EnumDomainAliases(p, tctx, &r);
5079 if (!NT_STATUS_IS_OK(status)) {
5080 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
5088 for (i=0;i<sam->count;i++) {
5089 if (!test_OpenAlias(p, tctx, handle, sam->entries[i].idx)) {
5097 static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p,
5098 struct torture_context *tctx,
5099 struct policy_handle *handle)
5102 struct samr_GetDisplayEnumerationIndex r;
5104 uint16_t levels[] = {1, 2, 3, 4, 5};
5105 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
5106 struct lsa_String name;
5110 for (i=0;i<ARRAY_SIZE(levels);i++) {
5111 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
5113 init_lsa_String(&name, TEST_ACCOUNT_NAME);
5115 r.in.domain_handle = handle;
5116 r.in.level = levels[i];
5120 status = dcerpc_samr_GetDisplayEnumerationIndex(p, tctx, &r);
5123 !NT_STATUS_IS_OK(status) &&
5124 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
5125 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
5126 levels[i], nt_errstr(status));
5130 init_lsa_String(&name, "zzzzzzzz");
5132 status = dcerpc_samr_GetDisplayEnumerationIndex(p, tctx, &r);
5134 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
5135 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
5136 levels[i], nt_errstr(status));
5144 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p,
5145 struct torture_context *tctx,
5146 struct policy_handle *handle)
5149 struct samr_GetDisplayEnumerationIndex2 r;
5151 uint16_t levels[] = {1, 2, 3, 4, 5};
5152 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
5153 struct lsa_String name;
5157 for (i=0;i<ARRAY_SIZE(levels);i++) {
5158 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
5160 init_lsa_String(&name, TEST_ACCOUNT_NAME);
5162 r.in.domain_handle = handle;
5163 r.in.level = levels[i];
5167 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, tctx, &r);
5169 !NT_STATUS_IS_OK(status) &&
5170 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
5171 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
5172 levels[i], nt_errstr(status));
5176 init_lsa_String(&name, "zzzzzzzz");
5178 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, tctx, &r);
5179 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
5180 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
5181 levels[i], nt_errstr(status));
5189 #define STRING_EQUAL_QUERY(s1, s2, user) \
5190 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
5191 /* odd, but valid */ \
5192 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
5193 printf("%s mismatch for %s: %s != %s (%s)\n", \
5194 #s1, user.string, s1.string, s2.string, __location__); \
5197 #define INT_EQUAL_QUERY(s1, s2, user) \
5199 printf("%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
5200 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
5204 static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p,
5205 struct torture_context *tctx,
5206 struct samr_QueryDisplayInfo *querydisplayinfo,
5207 bool *seen_testuser)
5209 struct samr_OpenUser r;
5210 struct samr_QueryUserInfo q;
5211 union samr_UserInfo *info;
5212 struct policy_handle user_handle;
5215 r.in.domain_handle = querydisplayinfo->in.domain_handle;
5216 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5217 for (i = 0; ; i++) {
5218 switch (querydisplayinfo->in.level) {
5220 if (i >= querydisplayinfo->out.info->info1.count) {
5223 r.in.rid = querydisplayinfo->out.info->info1.entries[i].rid;
5226 if (i >= querydisplayinfo->out.info->info2.count) {
5229 r.in.rid = querydisplayinfo->out.info->info2.entries[i].rid;
5235 /* Not interested in validating just the account name */
5239 r.out.user_handle = &user_handle;
5241 switch (querydisplayinfo->in.level) {
5244 status = dcerpc_samr_OpenUser(p, tctx, &r);
5245 if (!NT_STATUS_IS_OK(status)) {
5246 printf("OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(status));
5251 q.in.user_handle = &user_handle;
5254 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
5255 if (!NT_STATUS_IS_OK(status)) {
5256 printf("QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(status));
5260 switch (querydisplayinfo->in.level) {
5262 if (seen_testuser && strcmp(info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
5263 *seen_testuser = true;
5265 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].full_name,
5266 info->info21.full_name, info->info21.account_name);
5267 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].account_name,
5268 info->info21.account_name, info->info21.account_name);
5269 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].description,
5270 info->info21.description, info->info21.account_name);
5271 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].rid,
5272 info->info21.rid, info->info21.account_name);
5273 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].acct_flags,
5274 info->info21.acct_flags, info->info21.account_name);
5278 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].account_name,
5279 info->info21.account_name, info->info21.account_name);
5280 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].description,
5281 info->info21.description, info->info21.account_name);
5282 INT_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].rid,
5283 info->info21.rid, info->info21.account_name);
5284 INT_EQUAL_QUERY((querydisplayinfo->out.info->info2.entries[i].acct_flags & ~ACB_NORMAL),
5285 info->info21.acct_flags, info->info21.account_name);
5287 if (!(querydisplayinfo->out.info->info2.entries[i].acct_flags & ACB_NORMAL)) {
5288 printf("Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
5289 info->info21.account_name.string);
5292 if (!(info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
5293 printf("Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
5294 info->info21.account_name.string,
5295 querydisplayinfo->out.info->info2.entries[i].acct_flags,
5296 info->info21.acct_flags);
5303 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
5310 static bool test_QueryDisplayInfo(struct dcerpc_pipe *p,
5311 struct torture_context *tctx,
5312 struct policy_handle *handle)
5315 struct samr_QueryDisplayInfo r;
5316 struct samr_QueryDomainInfo dom_info;
5317 union samr_DomainInfo *info = NULL;
5319 uint16_t levels[] = {1, 2, 3, 4, 5};
5321 bool seen_testuser = false;
5322 uint32_t total_size;
5323 uint32_t returned_size;
5324 union samr_DispInfo disp_info;
5327 for (i=0;i<ARRAY_SIZE(levels);i++) {
5328 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
5331 status = STATUS_MORE_ENTRIES;
5332 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
5333 r.in.domain_handle = handle;
5334 r.in.level = levels[i];
5335 r.in.max_entries = 2;
5336 r.in.buf_size = (uint32_t)-1;
5337 r.out.total_size = &total_size;
5338 r.out.returned_size = &returned_size;
5339 r.out.info = &disp_info;
5341 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &r);
5342 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(status)) {
5343 printf("QueryDisplayInfo level %u failed - %s\n",
5344 levels[i], nt_errstr(status));
5347 switch (r.in.level) {
5349 if (!test_each_DisplayInfo_user(p, tctx, &r, &seen_testuser)) {
5352 r.in.start_idx += r.out.info->info1.count;
5355 if (!test_each_DisplayInfo_user(p, tctx, &r, NULL)) {
5358 r.in.start_idx += r.out.info->info2.count;
5361 r.in.start_idx += r.out.info->info3.count;
5364 r.in.start_idx += r.out.info->info4.count;
5367 r.in.start_idx += r.out.info->info5.count;
5371 dom_info.in.domain_handle = handle;
5372 dom_info.in.level = 2;
5373 dom_info.out.info = &info;
5375 /* Check number of users returned is correct */
5376 status = dcerpc_samr_QueryDomainInfo(p, tctx, &dom_info);
5377 if (!NT_STATUS_IS_OK(status)) {
5378 printf("QueryDomainInfo level %u failed - %s\n",
5379 r.in.level, nt_errstr(status));
5383 switch (r.in.level) {
5386 if (info->general.num_users < r.in.start_idx) {
5387 printf("QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
5388 r.in.start_idx, info->general.num_groups,
5389 info->general.domain_name.string);
5392 if (!seen_testuser) {
5393 struct policy_handle user_handle;
5394 if (NT_STATUS_IS_OK(test_OpenUser_byname(p, tctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
5395 printf("Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
5396 info->general.domain_name.string);
5398 test_samr_handle_Close(p, tctx, &user_handle);
5404 if (info->general.num_groups != r.in.start_idx) {
5405 printf("QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
5406 r.in.start_idx, info->general.num_groups,
5407 info->general.domain_name.string);
5419 static bool test_QueryDisplayInfo2(struct dcerpc_pipe *p,
5420 struct torture_context *tctx,
5421 struct policy_handle *handle)
5424 struct samr_QueryDisplayInfo2 r;
5426 uint16_t levels[] = {1, 2, 3, 4, 5};
5428 uint32_t total_size;
5429 uint32_t returned_size;
5430 union samr_DispInfo info;
5432 for (i=0;i<ARRAY_SIZE(levels);i++) {
5433 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
5435 r.in.domain_handle = handle;
5436 r.in.level = levels[i];
5438 r.in.max_entries = 1000;
5439 r.in.buf_size = (uint32_t)-1;
5440 r.out.total_size = &total_size;
5441 r.out.returned_size = &returned_size;
5444 status = dcerpc_samr_QueryDisplayInfo2(p, tctx, &r);
5445 if (!NT_STATUS_IS_OK(status)) {
5446 printf("QueryDisplayInfo2 level %u failed - %s\n",
5447 levels[i], nt_errstr(status));
5455 static bool test_QueryDisplayInfo3(struct dcerpc_pipe *p, struct torture_context *tctx,
5456 struct policy_handle *handle)
5459 struct samr_QueryDisplayInfo3 r;
5461 uint16_t levels[] = {1, 2, 3, 4, 5};
5463 uint32_t total_size;
5464 uint32_t returned_size;
5465 union samr_DispInfo info;
5467 for (i=0;i<ARRAY_SIZE(levels);i++) {
5468 torture_comment(tctx, "Testing QueryDisplayInfo3 level %u\n", levels[i]);
5470 r.in.domain_handle = handle;
5471 r.in.level = levels[i];
5473 r.in.max_entries = 1000;
5474 r.in.buf_size = (uint32_t)-1;
5475 r.out.total_size = &total_size;
5476 r.out.returned_size = &returned_size;
5479 status = dcerpc_samr_QueryDisplayInfo3(p, tctx, &r);
5480 if (!NT_STATUS_IS_OK(status)) {
5481 printf("QueryDisplayInfo3 level %u failed - %s\n",
5482 levels[i], nt_errstr(status));
5491 static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p,
5492 struct torture_context *tctx,
5493 struct policy_handle *handle)
5496 struct samr_QueryDisplayInfo r;
5498 uint32_t total_size;
5499 uint32_t returned_size;
5500 union samr_DispInfo info;
5502 printf("Testing QueryDisplayInfo continuation\n");
5504 r.in.domain_handle = handle;
5507 r.in.max_entries = 1;
5508 r.in.buf_size = (uint32_t)-1;
5509 r.out.total_size = &total_size;
5510 r.out.returned_size = &returned_size;
5514 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &r);
5515 if (NT_STATUS_IS_OK(status) && *r.out.returned_size != 0) {
5516 if (r.out.info->info1.entries[0].idx != r.in.start_idx + 1) {
5517 printf("expected idx %d but got %d\n",
5519 r.out.info->info1.entries[0].idx);
5523 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
5524 !NT_STATUS_IS_OK(status)) {
5525 printf("QueryDisplayInfo level %u failed - %s\n",
5526 r.in.level, nt_errstr(status));
5531 } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
5532 NT_STATUS_IS_OK(status)) &&
5533 *r.out.returned_size != 0);
5538 static bool test_QueryDomainInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
5539 struct policy_handle *handle)
5542 struct samr_QueryDomainInfo r;
5543 union samr_DomainInfo *info = NULL;
5544 struct samr_SetDomainInfo s;
5545 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
5546 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
5549 const char *domain_comment = talloc_asprintf(tctx,
5550 "Tortured by Samba4 RPC-SAMR: %s",
5551 timestring(tctx, time(NULL)));
5553 s.in.domain_handle = handle;
5555 s.in.info = talloc(tctx, union samr_DomainInfo);
5557 s.in.info->oem.oem_information.string = domain_comment;
5558 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
5559 if (!NT_STATUS_IS_OK(status)) {
5560 printf("SetDomainInfo level %u (set comment) failed - %s\n",
5561 s.in.level, nt_errstr(status));
5565 for (i=0;i<ARRAY_SIZE(levels);i++) {
5566 torture_comment(tctx, "Testing QueryDomainInfo level %u\n", levels[i]);
5568 r.in.domain_handle = handle;
5569 r.in.level = levels[i];
5572 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
5573 if (!NT_STATUS_IS_OK(status)) {
5574 printf("QueryDomainInfo level %u failed - %s\n",
5575 r.in.level, nt_errstr(status));
5580 switch (levels[i]) {
5582 if (strcmp(info->general.oem_information.string, domain_comment) != 0) {
5583 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
5584 levels[i], info->general.oem_information.string, domain_comment);
5587 if (!info->general.primary.string) {
5588 printf("QueryDomainInfo level %u returned no PDC name\n",
5591 } else if (info->general.role == SAMR_ROLE_DOMAIN_PDC) {
5592 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), info->general.primary.string) != 0) {
5593 printf("QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
5594 levels[i], info->general.primary.string, dcerpc_server_name(p));
5599 if (strcmp(info->oem.oem_information.string, domain_comment) != 0) {
5600 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
5601 levels[i], info->oem.oem_information.string, domain_comment);
5606 if (!info->info6.primary.string) {
5607 printf("QueryDomainInfo level %u returned no PDC name\n",
5613 if (strcmp(info->general2.general.oem_information.string, domain_comment) != 0) {
5614 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
5615 levels[i], info->general2.general.oem_information.string, domain_comment);
5621 torture_comment(tctx, "Testing SetDomainInfo level %u\n", levels[i]);
5623 s.in.domain_handle = handle;
5624 s.in.level = levels[i];
5627 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
5629 if (!NT_STATUS_IS_OK(status)) {
5630 printf("SetDomainInfo level %u failed - %s\n",
5631 r.in.level, nt_errstr(status));
5636 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
5637 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
5638 r.in.level, nt_errstr(status));
5644 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
5645 if (!NT_STATUS_IS_OK(status)) {
5646 printf("QueryDomainInfo level %u failed - %s\n",
5647 r.in.level, nt_errstr(status));
5657 static bool test_QueryDomainInfo2(struct dcerpc_pipe *p, struct torture_context *tctx,
5658 struct policy_handle *handle)
5661 struct samr_QueryDomainInfo2 r;
5662 union samr_DomainInfo *info = NULL;
5663 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
5667 for (i=0;i<ARRAY_SIZE(levels);i++) {
5668 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
5670 r.in.domain_handle = handle;
5671 r.in.level = levels[i];
5674 status = dcerpc_samr_QueryDomainInfo2(p, tctx, &r);
5675 if (!NT_STATUS_IS_OK(status)) {
5676 printf("QueryDomainInfo2 level %u failed - %s\n",
5677 r.in.level, nt_errstr(status));
5686 /* Test whether querydispinfo level 5 and enumdomgroups return the same
5687 set of group names. */
5688 static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx,
5689 struct policy_handle *handle)
5691 struct samr_EnumDomainGroups q1;
5692 struct samr_QueryDisplayInfo q2;
5694 uint32_t resume_handle=0;
5695 struct samr_SamArray *sam = NULL;
5696 uint32_t num_entries = 0;
5699 uint32_t total_size;
5700 uint32_t returned_size;
5701 union samr_DispInfo info;
5704 const char **names = NULL;
5706 torture_comment(tctx, "Testing coherency of querydispinfo vs enumdomgroups\n");
5708 q1.in.domain_handle = handle;
5709 q1.in.resume_handle = &resume_handle;
5711 q1.out.resume_handle = &resume_handle;
5712 q1.out.num_entries = &num_entries;
5715 status = STATUS_MORE_ENTRIES;
5716 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
5717 status = dcerpc_samr_EnumDomainGroups(p, tctx, &q1);
5719 if (!NT_STATUS_IS_OK(status) &&
5720 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
5723 for (i=0; i<*q1.out.num_entries; i++) {
5724 add_string_to_array(tctx,
5725 sam->entries[i].name.string,
5726 &names, &num_names);
5730 torture_assert_ntstatus_ok(tctx, status, "EnumDomainGroups");
5732 torture_assert(tctx, sam, "EnumDomainGroups failed to return sam");
5734 q2.in.domain_handle = handle;
5736 q2.in.start_idx = 0;
5737 q2.in.max_entries = 5;
5738 q2.in.buf_size = (uint32_t)-1;
5739 q2.out.total_size = &total_size;
5740 q2.out.returned_size = &returned_size;
5741 q2.out.info = &info;
5743 status = STATUS_MORE_ENTRIES;
5744 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
5745 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &q2);
5747 if (!NT_STATUS_IS_OK(status) &&
5748 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
5751 for (i=0; i<q2.out.info->info5.count; i++) {
5753 const char *name = q2.out.info->info5.entries[i].account_name.string;
5755 for (j=0; j<num_names; j++) {
5756 if (names[j] == NULL)
5758 if (strequal(names[j], name)) {
5766 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
5771 q2.in.start_idx += q2.out.info->info5.count;
5774 if (!NT_STATUS_IS_OK(status)) {
5775 printf("QueryDisplayInfo level 5 failed - %s\n",
5780 for (i=0; i<num_names; i++) {
5781 if (names[i] != NULL) {
5782 printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
5791 static bool test_DeleteDomainGroup(struct dcerpc_pipe *p, struct torture_context *tctx,
5792 struct policy_handle *group_handle)
5794 struct samr_DeleteDomainGroup d;
5797 torture_comment(tctx, "Testing DeleteDomainGroup\n");
5799 d.in.group_handle = group_handle;
5800 d.out.group_handle = group_handle;
5802 status = dcerpc_samr_DeleteDomainGroup(p, tctx, &d);
5803 torture_assert_ntstatus_ok(tctx, status, "DeleteDomainGroup");
5808 static bool test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
5809 struct policy_handle *domain_handle)
5811 struct samr_TestPrivateFunctionsDomain r;
5815 torture_comment(tctx, "Testing TestPrivateFunctionsDomain\n");
5817 r.in.domain_handle = domain_handle;
5819 status = dcerpc_samr_TestPrivateFunctionsDomain(p, tctx, &r);
5820 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsDomain");
5825 static bool test_RidToSid(struct dcerpc_pipe *p, struct torture_context *tctx,
5826 struct dom_sid *domain_sid,
5827 struct policy_handle *domain_handle)
5829 struct samr_RidToSid r;
5832 struct dom_sid *calc_sid, *out_sid;
5833 int rids[] = { 0, 42, 512, 10200 };
5836 for (i=0;i<ARRAY_SIZE(rids);i++) {
5837 torture_comment(tctx, "Testing RidToSid\n");
5839 calc_sid = dom_sid_dup(tctx, domain_sid);
5840 r.in.domain_handle = domain_handle;
5842 r.out.sid = &out_sid;
5844 status = dcerpc_samr_RidToSid(p, tctx, &r);
5845 if (!NT_STATUS_IS_OK(status)) {
5846 printf("RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
5849 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
5851 if (!dom_sid_equal(calc_sid, out_sid)) {
5852 printf("RidToSid for %d failed - got %s, expected %s\n", rids[i],
5853 dom_sid_string(tctx, out_sid),
5854 dom_sid_string(tctx, calc_sid));
5863 static bool test_GetBootKeyInformation(struct dcerpc_pipe *p, struct torture_context *tctx,
5864 struct policy_handle *domain_handle)
5866 struct samr_GetBootKeyInformation r;
5869 uint32_t unknown = 0;
5871 torture_comment(tctx, "Testing GetBootKeyInformation\n");
5873 r.in.domain_handle = domain_handle;
5874 r.out.unknown = &unknown;
5876 status = dcerpc_samr_GetBootKeyInformation(p, tctx, &r);
5877 if (!NT_STATUS_IS_OK(status)) {
5878 /* w2k3 seems to fail this sometimes and pass it sometimes */
5879 torture_comment(tctx, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
5885 static bool test_AddGroupMember(struct dcerpc_pipe *p, struct torture_context *tctx,
5886 struct policy_handle *domain_handle,
5887 struct policy_handle *group_handle)
5890 struct samr_AddGroupMember r;
5891 struct samr_DeleteGroupMember d;
5892 struct samr_QueryGroupMember q;
5893 struct samr_RidTypeArray *rids = NULL;
5894 struct samr_SetMemberAttributesOfGroup s;
5897 status = test_LookupName(p, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
5898 torture_assert_ntstatus_ok(tctx, status, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME);
5900 r.in.group_handle = group_handle;
5902 r.in.flags = 0; /* ??? */
5904 torture_comment(tctx, "Testing AddGroupMember and DeleteGroupMember\n");
5906 d.in.group_handle = group_handle;
5909 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
5910 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_NOT_IN_GROUP, status, "DeleteGroupMember");
5912 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5913 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
5915 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5916 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_IN_GROUP, status, "AddGroupMember");
5918 if (torture_setting_bool(tctx, "samba4", false) ||
5919 torture_setting_bool(tctx, "samba3", false)) {
5920 torture_comment(tctx, "skipping SetMemberAttributesOfGroup test against Samba4\n");
5922 /* this one is quite strange. I am using random inputs in the
5923 hope of triggering an error that might give us a clue */
5925 s.in.group_handle = group_handle;
5926 s.in.unknown1 = random();
5927 s.in.unknown2 = random();
5929 status = dcerpc_samr_SetMemberAttributesOfGroup(p, tctx, &s);
5930 torture_assert_ntstatus_ok(tctx, status, "SetMemberAttributesOfGroup");
5933 q.in.group_handle = group_handle;
5936 status = dcerpc_samr_QueryGroupMember(p, tctx, &q);
5937 torture_assert_ntstatus_ok(tctx, status, "QueryGroupMember");
5939 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
5940 torture_assert_ntstatus_ok(tctx, status, "DeleteGroupMember");
5942 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5943 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
5949 static bool test_CreateDomainGroup(struct dcerpc_pipe *p,
5950 struct torture_context *tctx,
5951 struct policy_handle *domain_handle,
5952 const char *group_name,
5953 struct policy_handle *group_handle,
5954 struct dom_sid *domain_sid,
5958 struct samr_CreateDomainGroup r;
5960 struct lsa_String name;
5963 init_lsa_String(&name, group_name);
5965 r.in.domain_handle = domain_handle;
5967 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5968 r.out.group_handle = group_handle;
5971 printf("Testing CreateDomainGroup(%s)\n", r.in.name->string);
5973 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
5975 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5976 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5977 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.name->string);
5980 printf("Server should have refused create of '%s', got %s instead\n", r.in.name->string,
5986 if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS)) {
5987 if (!test_DeleteGroup_byname(p, tctx, domain_handle, r.in.name->string)) {
5988 printf("CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
5992 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
5994 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
5995 if (!test_DeleteUser_byname(p, tctx, domain_handle, r.in.name->string)) {
5997 printf("CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
6001 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
6003 torture_assert_ntstatus_ok(tctx, status, "CreateDomainGroup");
6009 if (!test_AddGroupMember(p, tctx, domain_handle, group_handle)) {
6010 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
6014 if (!test_SetGroupInfo(p, tctx, group_handle)) {
6023 its not totally clear what this does. It seems to accept any sid you like.
6025 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p,
6026 struct torture_context *tctx,
6027 struct policy_handle *domain_handle)
6030 struct samr_RemoveMemberFromForeignDomain r;
6032 r.in.domain_handle = domain_handle;
6033 r.in.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-12-34-56-78");
6035 status = dcerpc_samr_RemoveMemberFromForeignDomain(p, tctx, &r);
6036 torture_assert_ntstatus_ok(tctx, status, "RemoveMemberFromForeignDomain");
6041 static bool test_EnumDomainUsers(struct dcerpc_pipe *p,
6042 struct torture_context *tctx,
6043 struct policy_handle *domain_handle,
6044 uint32_t *total_num_entries_p)
6047 struct samr_EnumDomainUsers r;
6048 uint32_t resume_handle = 0;
6049 uint32_t num_entries = 0;
6050 uint32_t total_num_entries = 0;
6051 struct samr_SamArray *sam;
6053 r.in.domain_handle = domain_handle;
6054 r.in.acct_flags = ACB_NORMAL;
6055 r.in.max_size = (uint32_t)-1;
6056 r.in.resume_handle = &resume_handle;
6059 r.out.num_entries = &num_entries;
6060 r.out.resume_handle = &resume_handle;
6062 printf("Testing EnumDomainUsers\n");
6065 status = dcerpc_samr_EnumDomainUsers(p, tctx, &r);
6066 if (NT_STATUS_IS_ERR(status)) {
6067 torture_assert_ntstatus_ok(tctx, status,
6068 "failed to enumerate users");
6071 total_num_entries += num_entries;
6072 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
6074 if (total_num_entries_p) {
6075 *total_num_entries_p = total_num_entries;
6081 static bool test_EnumDomainGroups(struct dcerpc_pipe *p,
6082 struct torture_context *tctx,
6083 struct policy_handle *domain_handle,
6084 uint32_t *total_num_entries_p)
6087 struct samr_EnumDomainGroups r;
6088 uint32_t resume_handle = 0;
6089 uint32_t num_entries = 0;
6090 uint32_t total_num_entries = 0;
6091 struct samr_SamArray *sam;
6093 r.in.domain_handle = domain_handle;
6094 r.in.max_size = (uint32_t)-1;
6095 r.in.resume_handle = &resume_handle;
6098 r.out.num_entries = &num_entries;
6099 r.out.resume_handle = &resume_handle;
6101 printf("Testing EnumDomainGroups\n");
6104 status = dcerpc_samr_EnumDomainGroups(p, tctx, &r);
6105 if (NT_STATUS_IS_ERR(status)) {
6106 torture_assert_ntstatus_ok(tctx, status,
6107 "failed to enumerate groups");
6110 total_num_entries += num_entries;
6111 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
6113 if (total_num_entries_p) {
6114 *total_num_entries_p = total_num_entries;
6120 static bool test_EnumDomainAliases(struct dcerpc_pipe *p,
6121 struct torture_context *tctx,
6122 struct policy_handle *domain_handle,
6123 uint32_t *total_num_entries_p)
6126 struct samr_EnumDomainAliases r;
6127 uint32_t resume_handle = 0;
6128 uint32_t num_entries = 0;
6129 uint32_t total_num_entries = 0;
6130 struct samr_SamArray *sam;
6132 r.in.domain_handle = domain_handle;
6133 r.in.max_size = (uint32_t)-1;
6134 r.in.resume_handle = &resume_handle;
6137 r.out.num_entries = &num_entries;
6138 r.out.resume_handle = &resume_handle;
6140 printf("Testing EnumDomainAliases\n");
6143 status = dcerpc_samr_EnumDomainAliases(p, tctx, &r);
6144 if (NT_STATUS_IS_ERR(status)) {
6145 torture_assert_ntstatus_ok(tctx, status,
6146 "failed to enumerate aliases");
6149 total_num_entries += num_entries;
6150 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
6152 if (total_num_entries_p) {
6153 *total_num_entries_p = total_num_entries;
6159 static bool test_ManyObjects(struct dcerpc_pipe *p,
6160 struct torture_context *tctx,
6161 struct policy_handle *domain_handle,
6162 struct dom_sid *domain_sid,
6163 enum torture_samr_choice which_ops)
6165 uint32_t num_total = 1500;
6166 uint32_t num_enum = 0;
6167 uint32_t num_disp = 0;
6168 uint32_t num_created = 0;
6169 uint32_t num_anounced = 0;
6177 struct samr_QueryDomainInfo2 r;
6178 union samr_DomainInfo *info;
6179 r.in.domain_handle = domain_handle;
6183 status = dcerpc_samr_QueryDomainInfo2(p, tctx, &r);
6184 torture_assert_ntstatus_ok(tctx, status,
6185 "failed to query domain info");
6187 switch (which_ops) {
6188 case TORTURE_SAMR_MANY_ACCOUNTS:
6189 num_anounced = info->general.num_users;
6191 case TORTURE_SAMR_MANY_GROUPS:
6192 num_anounced = info->general.num_groups;
6194 case TORTURE_SAMR_MANY_ALIASES:
6195 num_anounced = info->general.num_aliases;
6204 for (i=0; i < num_total; i++) {
6206 struct policy_handle handle;
6207 const char *name = NULL;
6209 ZERO_STRUCT(handle);
6211 switch (which_ops) {
6212 case TORTURE_SAMR_MANY_ACCOUNTS:
6213 name = talloc_asprintf(tctx, "%s%04d", TEST_ACCOUNT_NAME, i);
6214 ret &= test_CreateUser(p, tctx, domain_handle, name, &handle, domain_sid, 0, NULL, false);
6216 case TORTURE_SAMR_MANY_GROUPS:
6217 name = talloc_asprintf(tctx, "%s%04d", TEST_GROUPNAME, i);
6218 ret &= test_CreateDomainGroup(p, tctx, domain_handle, name, &handle, domain_sid, false);
6220 case TORTURE_SAMR_MANY_ALIASES:
6221 name = talloc_asprintf(tctx, "%s%04d", TEST_ALIASNAME, i);
6222 ret &= test_CreateAlias(p, tctx, domain_handle, name, &handle, domain_sid, false);
6227 if (!policy_handle_empty(&handle)) {
6228 ret &= test_samr_handle_Close(p, tctx, &handle);
6235 switch (which_ops) {
6236 case TORTURE_SAMR_MANY_ACCOUNTS:
6237 ret &= test_EnumDomainUsers(p, tctx, domain_handle, &num_enum);
6239 case TORTURE_SAMR_MANY_GROUPS:
6240 ret &= test_EnumDomainGroups(p, tctx, domain_handle, &num_enum);
6242 case TORTURE_SAMR_MANY_ALIASES:
6243 ret &= test_EnumDomainAliases(p, tctx, domain_handle, &num_enum);
6249 torture_assert_int_equal(tctx, num_enum, num_anounced + num_created,
6250 "unexpected number of results returned in enum call");
6252 /* TODO: dispinfo */
6254 switch (which_ops) {
6255 case TORTURE_SAMR_MANY_ACCOUNTS:
6257 case TORTURE_SAMR_MANY_GROUPS:
6259 case TORTURE_SAMR_MANY_ALIASES:
6265 torture_assert_int_equal(tctx, num_disp, num_anounced + num_created,
6266 "unexpected number of results returned in dispinfo call");
6271 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
6272 struct policy_handle *handle);
6274 static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
6275 struct policy_handle *handle, struct dom_sid *sid,
6276 enum torture_samr_choice which_ops,
6277 struct cli_credentials *machine_credentials)
6280 struct samr_OpenDomain r;
6281 struct policy_handle domain_handle;
6282 struct policy_handle alias_handle;
6283 struct policy_handle user_handle;
6284 struct policy_handle group_handle;
6287 ZERO_STRUCT(alias_handle);
6288 ZERO_STRUCT(user_handle);
6289 ZERO_STRUCT(group_handle);
6290 ZERO_STRUCT(domain_handle);
6292 torture_comment(tctx, "Testing OpenDomain of %s\n", dom_sid_string(tctx, sid));
6294 r.in.connect_handle = handle;
6295 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6297 r.out.domain_handle = &domain_handle;
6299 status = dcerpc_samr_OpenDomain(p, tctx, &r);
6300 torture_assert_ntstatus_ok(tctx, status, "OpenDomain");
6302 /* run the domain tests with the main handle closed - this tests
6303 the servers reference counting */
6304 ret &= test_samr_handle_Close(p, tctx, handle);
6306 switch (which_ops) {
6307 case TORTURE_SAMR_USER_ATTRIBUTES:
6308 case TORTURE_SAMR_USER_PRIVILEGES:
6309 case TORTURE_SAMR_PASSWORDS:
6310 if (!torture_setting_bool(tctx, "samba3", false)) {
6311 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops, NULL);
6313 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, which_ops, NULL, true);
6314 /* This test needs 'complex' users to validate */
6315 ret &= test_QueryDisplayInfo(p, tctx, &domain_handle);
6317 printf("Testing PASSWORDS or ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
6320 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
6321 if (!torture_setting_bool(tctx, "samba3", false)) {
6322 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops, machine_credentials);
6324 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, which_ops, machine_credentials, true);
6326 printf("Testing PASSWORDS PWDLASTSET on domain %s failed!\n", dom_sid_string(tctx, sid));
6329 case TORTURE_SAMR_MANY_ACCOUNTS:
6330 case TORTURE_SAMR_MANY_GROUPS:
6331 case TORTURE_SAMR_MANY_ALIASES:
6332 ret &= test_ManyObjects(p, tctx, &domain_handle, sid, which_ops);
6334 case TORTURE_SAMR_OTHER:
6335 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, which_ops, NULL, true);
6337 printf("Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid));
6339 if (!torture_setting_bool(tctx, "samba3", false)) {
6340 ret &= test_QuerySecurity(p, tctx, &domain_handle);
6342 ret &= test_RemoveMemberFromForeignDomain(p, tctx, &domain_handle);
6343 ret &= test_CreateAlias(p, tctx, &domain_handle, TEST_ALIASNAME, &alias_handle, sid, true);
6344 ret &= test_CreateDomainGroup(p, tctx, &domain_handle, TEST_GROUPNAME, &group_handle, sid, true);
6345 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
6346 ret &= test_QueryDomainInfo2(p, tctx, &domain_handle);
6347 ret &= test_EnumDomainUsers_all(p, tctx, &domain_handle);
6348 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
6349 ret &= test_EnumDomainGroups_all(p, tctx, &domain_handle);
6350 ret &= test_EnumDomainAliases_all(p, tctx, &domain_handle);
6351 ret &= test_QueryDisplayInfo2(p, tctx, &domain_handle);
6352 ret &= test_QueryDisplayInfo3(p, tctx, &domain_handle);
6353 ret &= test_QueryDisplayInfo_continue(p, tctx, &domain_handle);
6355 if (torture_setting_bool(tctx, "samba4", false)) {
6356 torture_comment(tctx, "skipping GetDisplayEnumerationIndex test against Samba4\n");
6358 ret &= test_GetDisplayEnumerationIndex(p, tctx, &domain_handle);
6359 ret &= test_GetDisplayEnumerationIndex2(p, tctx, &domain_handle);
6361 ret &= test_GroupList(p, tctx, &domain_handle);
6362 ret &= test_TestPrivateFunctionsDomain(p, tctx, &domain_handle);
6363 ret &= test_RidToSid(p, tctx, sid, &domain_handle);
6364 ret &= test_GetBootKeyInformation(p, tctx, &domain_handle);
6366 torture_comment(tctx, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx, sid));
6371 if (!policy_handle_empty(&user_handle) &&
6372 !test_DeleteUser(p, tctx, &user_handle)) {
6376 if (!policy_handle_empty(&alias_handle) &&
6377 !test_DeleteAlias(p, tctx, &alias_handle)) {
6381 if (!policy_handle_empty(&group_handle) &&
6382 !test_DeleteDomainGroup(p, tctx, &group_handle)) {
6386 ret &= test_samr_handle_Close(p, tctx, &domain_handle);
6388 /* reconnect the main handle */
6389 ret &= test_Connect(p, tctx, handle);
6392 printf("Testing domain %s failed!\n", dom_sid_string(tctx, sid));
6398 static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
6399 struct policy_handle *handle, const char *domain,
6400 enum torture_samr_choice which_ops,
6401 struct cli_credentials *machine_credentials)
6404 struct samr_LookupDomain r;
6405 struct dom_sid2 *sid = NULL;
6406 struct lsa_String n1;
6407 struct lsa_String n2;
6410 torture_comment(tctx, "Testing LookupDomain(%s)\n", domain);
6412 /* check for correct error codes */
6413 r.in.connect_handle = handle;
6414 r.in.domain_name = &n2;
6418 status = dcerpc_samr_LookupDomain(p, tctx, &r);
6419 torture_assert_ntstatus_equal(tctx, NT_STATUS_INVALID_PARAMETER, status, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
6421 init_lsa_String(&n2, "xxNODOMAINxx");
6423 status = dcerpc_samr_LookupDomain(p, tctx, &r);
6424 torture_assert_ntstatus_equal(tctx, NT_STATUS_NO_SUCH_DOMAIN, status, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
6426 r.in.connect_handle = handle;
6428 init_lsa_String(&n1, domain);
6429 r.in.domain_name = &n1;
6431 status = dcerpc_samr_LookupDomain(p, tctx, &r);
6432 torture_assert_ntstatus_ok(tctx, status, "LookupDomain");
6434 if (!test_GetDomPwInfo(p, tctx, &n1)) {
6438 if (!test_OpenDomain(p, tctx, handle, *r.out.sid, which_ops,
6439 machine_credentials)) {
6447 static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
6448 struct policy_handle *handle, enum torture_samr_choice which_ops,
6449 struct cli_credentials *machine_credentials)
6452 struct samr_EnumDomains r;
6453 uint32_t resume_handle = 0;
6454 uint32_t num_entries = 0;
6455 struct samr_SamArray *sam = NULL;
6459 r.in.connect_handle = handle;
6460 r.in.resume_handle = &resume_handle;
6461 r.in.buf_size = (uint32_t)-1;
6462 r.out.resume_handle = &resume_handle;
6463 r.out.num_entries = &num_entries;
6466 status = dcerpc_samr_EnumDomains(p, tctx, &r);
6467 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
6473 for (i=0;i<sam->count;i++) {
6474 if (!test_LookupDomain(p, tctx, handle,
6475 sam->entries[i].name.string, which_ops,
6476 machine_credentials)) {
6481 status = dcerpc_samr_EnumDomains(p, tctx, &r);
6482 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
6488 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
6489 struct policy_handle *handle)
6492 struct samr_Connect r;
6493 struct samr_Connect2 r2;
6494 struct samr_Connect3 r3;
6495 struct samr_Connect4 r4;
6496 struct samr_Connect5 r5;
6497 union samr_ConnectInfo info;
6498 struct policy_handle h;
6499 uint32_t level_out = 0;
6500 bool ret = true, got_handle = false;
6502 torture_comment(tctx, "testing samr_Connect\n");
6504 r.in.system_name = 0;
6505 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6506 r.out.connect_handle = &h;
6508 status = dcerpc_samr_Connect(p, tctx, &r);
6509 if (!NT_STATUS_IS_OK(status)) {
6510 torture_comment(tctx, "Connect failed - %s\n", nt_errstr(status));
6517 torture_comment(tctx, "testing samr_Connect2\n");
6519 r2.in.system_name = NULL;
6520 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6521 r2.out.connect_handle = &h;
6523 status = dcerpc_samr_Connect2(p, tctx, &r2);
6524 if (!NT_STATUS_IS_OK(status)) {
6525 torture_comment(tctx, "Connect2 failed - %s\n", nt_errstr(status));
6529 test_samr_handle_Close(p, tctx, handle);
6535 torture_comment(tctx, "testing samr_Connect3\n");
6537 r3.in.system_name = NULL;
6539 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6540 r3.out.connect_handle = &h;
6542 status = dcerpc_samr_Connect3(p, tctx, &r3);
6543 if (!NT_STATUS_IS_OK(status)) {
6544 printf("Connect3 failed - %s\n", nt_errstr(status));
6548 test_samr_handle_Close(p, tctx, handle);
6554 torture_comment(tctx, "testing samr_Connect4\n");
6556 r4.in.system_name = "";
6557 r4.in.client_version = 0;
6558 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6559 r4.out.connect_handle = &h;
6561 status = dcerpc_samr_Connect4(p, tctx, &r4);
6562 if (!NT_STATUS_IS_OK(status)) {
6563 printf("Connect4 failed - %s\n", nt_errstr(status));
6567 test_samr_handle_Close(p, tctx, handle);
6573 torture_comment(tctx, "testing samr_Connect5\n");
6575 info.info1.client_version = 0;
6576 info.info1.unknown2 = 0;
6578 r5.in.system_name = "";
6579 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6581 r5.out.level_out = &level_out;
6582 r5.in.info_in = &info;
6583 r5.out.info_out = &info;
6584 r5.out.connect_handle = &h;
6586 status = dcerpc_samr_Connect5(p, tctx, &r5);
6587 if (!NT_STATUS_IS_OK(status)) {
6588 printf("Connect5 failed - %s\n", nt_errstr(status));
6592 test_samr_handle_Close(p, tctx, handle);
6602 bool torture_rpc_samr(struct torture_context *torture)
6605 struct dcerpc_pipe *p;
6607 struct policy_handle handle;
6609 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6610 if (!NT_STATUS_IS_OK(status)) {
6614 ret &= test_Connect(p, torture, &handle);
6616 if (!torture_setting_bool(torture, "samba3", false)) {
6617 ret &= test_QuerySecurity(p, torture, &handle);
6620 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_OTHER, NULL);
6622 ret &= test_SetDsrmPassword(p, torture, &handle);
6624 ret &= test_Shutdown(p, torture, &handle);
6626 ret &= test_samr_handle_Close(p, torture, &handle);
6632 bool torture_rpc_samr_users(struct torture_context *torture)
6635 struct dcerpc_pipe *p;
6637 struct policy_handle handle;
6639 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6640 if (!NT_STATUS_IS_OK(status)) {
6644 ret &= test_Connect(p, torture, &handle);
6646 if (!torture_setting_bool(torture, "samba3", false)) {
6647 ret &= test_QuerySecurity(p, torture, &handle);
6650 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_USER_ATTRIBUTES, NULL);
6652 ret &= test_SetDsrmPassword(p, torture, &handle);
6654 ret &= test_Shutdown(p, torture, &handle);
6656 ret &= test_samr_handle_Close(p, torture, &handle);
6662 bool torture_rpc_samr_passwords(struct torture_context *torture)
6665 struct dcerpc_pipe *p;
6667 struct policy_handle handle;
6669 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6670 if (!NT_STATUS_IS_OK(status)) {
6674 ret &= test_Connect(p, torture, &handle);
6676 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_PASSWORDS, NULL);
6678 ret &= test_samr_handle_Close(p, torture, &handle);
6683 static bool torture_rpc_samr_pwdlastset(struct torture_context *torture,
6684 struct dcerpc_pipe *p2,
6685 struct cli_credentials *machine_credentials)
6688 struct dcerpc_pipe *p;
6690 struct policy_handle handle;
6692 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6693 if (!NT_STATUS_IS_OK(status)) {
6697 ret &= test_Connect(p, torture, &handle);
6699 ret &= test_EnumDomains(p, torture, &handle,
6700 TORTURE_SAMR_PASSWORDS_PWDLASTSET,
6701 machine_credentials);
6703 ret &= test_samr_handle_Close(p, torture, &handle);
6708 struct torture_suite *torture_rpc_samr_passwords_pwdlastset(TALLOC_CTX *mem_ctx)
6710 struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-PASSWORDS-PWDLASTSET");
6711 struct torture_rpc_tcase *tcase;
6713 tcase = torture_suite_add_machine_rpc_iface_tcase(suite, "samr",
6715 TEST_ACCOUNT_NAME_PWD);
6717 torture_rpc_tcase_add_test_creds(tcase, "pwdLastSet",
6718 torture_rpc_samr_pwdlastset);
6723 static bool torture_rpc_samr_users_privileges_delete_user(struct torture_context *torture,
6724 struct dcerpc_pipe *p2,
6725 struct cli_credentials *machine_credentials)
6728 struct dcerpc_pipe *p;
6730 struct policy_handle handle;
6732 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6733 if (!NT_STATUS_IS_OK(status)) {
6737 ret &= test_Connect(p, torture, &handle);
6739 ret &= test_EnumDomains(p, torture, &handle,
6740 TORTURE_SAMR_USER_PRIVILEGES,
6741 machine_credentials);
6743 ret &= test_samr_handle_Close(p, torture, &handle);
6748 struct torture_suite *torture_rpc_samr_user_privileges(TALLOC_CTX *mem_ctx)
6750 struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-USERS-PRIVILEGES");
6751 struct torture_rpc_tcase *tcase;
6753 tcase = torture_suite_add_machine_rpc_iface_tcase(suite, "samr",
6755 TEST_ACCOUNT_NAME_PWD);
6757 torture_rpc_tcase_add_test_creds(tcase, "delete_privileged_user",
6758 torture_rpc_samr_users_privileges_delete_user);
6763 static bool torture_rpc_samr_many_accounts(struct torture_context *torture,
6764 struct dcerpc_pipe *p2,
6765 struct cli_credentials *machine_credentials)
6768 struct dcerpc_pipe *p;
6770 struct policy_handle handle;
6772 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6773 if (!NT_STATUS_IS_OK(status)) {
6777 ret &= test_Connect(p, torture, &handle);
6779 ret &= test_EnumDomains(p, torture, &handle,
6780 TORTURE_SAMR_MANY_ACCOUNTS,
6781 machine_credentials);
6783 ret &= test_samr_handle_Close(p, torture, &handle);
6788 static bool torture_rpc_samr_many_groups(struct torture_context *torture,
6789 struct dcerpc_pipe *p2,
6790 struct cli_credentials *machine_credentials)
6793 struct dcerpc_pipe *p;
6795 struct policy_handle handle;
6797 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6798 if (!NT_STATUS_IS_OK(status)) {
6802 ret &= test_Connect(p, torture, &handle);
6804 ret &= test_EnumDomains(p, torture, &handle,
6805 TORTURE_SAMR_MANY_GROUPS,
6806 machine_credentials);
6808 ret &= test_samr_handle_Close(p, torture, &handle);
6813 static bool torture_rpc_samr_many_aliases(struct torture_context *torture,
6814 struct dcerpc_pipe *p2,
6815 struct cli_credentials *machine_credentials)
6818 struct dcerpc_pipe *p;
6820 struct policy_handle handle;
6822 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6823 if (!NT_STATUS_IS_OK(status)) {
6827 ret &= test_Connect(p, torture, &handle);
6829 ret &= test_EnumDomains(p, torture, &handle,
6830 TORTURE_SAMR_MANY_ALIASES,
6831 machine_credentials);
6833 ret &= test_samr_handle_Close(p, torture, &handle);
6838 struct torture_suite *torture_rpc_samr_large_dc(TALLOC_CTX *mem_ctx)
6840 struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-LARGE-DC");
6841 struct torture_rpc_tcase *tcase;
6843 tcase = torture_suite_add_machine_rpc_iface_tcase(suite, "samr",
6847 torture_rpc_tcase_add_test_creds(tcase, "many_aliases",
6848 torture_rpc_samr_many_aliases);
6849 torture_rpc_tcase_add_test_creds(tcase, "many_groups",
6850 torture_rpc_samr_many_groups);
6851 torture_rpc_tcase_add_test_creds(tcase, "many_accounts",
6852 torture_rpc_samr_many_accounts);