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 TEST_USERINFO_STRING(2, comment, 1, comment, "xx2-1 comment", 0);
343 TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
344 TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment",
347 test_account_name = talloc_asprintf(tctx, "%sxx7-1", base_account_name);
348 TEST_USERINFO_STRING(7, account_name, 1, account_name, base_account_name, 0);
349 test_account_name = talloc_asprintf(tctx, "%sxx7-3", base_account_name);
350 TEST_USERINFO_STRING(7, account_name, 3, account_name, base_account_name, 0);
351 test_account_name = talloc_asprintf(tctx, "%sxx7-5", base_account_name);
352 TEST_USERINFO_STRING(7, account_name, 5, account_name, base_account_name, 0);
353 test_account_name = talloc_asprintf(tctx, "%sxx7-6", base_account_name);
354 TEST_USERINFO_STRING(7, account_name, 6, account_name, base_account_name, 0);
355 test_account_name = talloc_asprintf(tctx, "%sxx7-7", base_account_name);
356 TEST_USERINFO_STRING(7, account_name, 7, account_name, base_account_name, 0);
357 test_account_name = talloc_asprintf(tctx, "%sxx7-21", base_account_name);
358 TEST_USERINFO_STRING(7, account_name, 21, account_name, base_account_name, 0);
359 test_account_name = base_account_name;
360 TEST_USERINFO_STRING(21, account_name, 21, account_name, base_account_name,
361 SAMR_FIELD_ACCOUNT_NAME);
363 TEST_USERINFO_STRING(6, full_name, 1, full_name, "xx6-1 full_name", 0);
364 TEST_USERINFO_STRING(6, full_name, 3, full_name, "xx6-3 full_name", 0);
365 TEST_USERINFO_STRING(6, full_name, 5, full_name, "xx6-5 full_name", 0);
366 TEST_USERINFO_STRING(6, full_name, 6, full_name, "xx6-6 full_name", 0);
367 TEST_USERINFO_STRING(6, full_name, 8, full_name, "xx6-8 full_name", 0);
368 TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
369 TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
370 TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name",
371 SAMR_FIELD_FULL_NAME);
373 TEST_USERINFO_STRING(6, full_name, 1, full_name, "", 0);
374 TEST_USERINFO_STRING(6, full_name, 3, full_name, "", 0);
375 TEST_USERINFO_STRING(6, full_name, 5, full_name, "", 0);
376 TEST_USERINFO_STRING(6, full_name, 6, full_name, "", 0);
377 TEST_USERINFO_STRING(6, full_name, 8, full_name, "", 0);
378 TEST_USERINFO_STRING(6, full_name, 21, full_name, "", 0);
379 TEST_USERINFO_STRING(8, full_name, 21, full_name, "", 0);
380 TEST_USERINFO_STRING(21, full_name, 21, full_name, "",
381 SAMR_FIELD_FULL_NAME);
383 TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
384 TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
385 TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
386 TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script",
387 SAMR_FIELD_LOGON_SCRIPT);
389 TEST_USERINFO_STRING(12, profile_path, 3, profile_path, "xx12-3 profile_path", 0);
390 TEST_USERINFO_STRING(12, profile_path, 5, profile_path, "xx12-5 profile_path", 0);
391 TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
392 TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path",
393 SAMR_FIELD_PROFILE_PATH);
395 TEST_USERINFO_STRING(10, home_directory, 3, home_directory, "xx10-3 home_directory", 0);
396 TEST_USERINFO_STRING(10, home_directory, 5, home_directory, "xx10-5 home_directory", 0);
397 TEST_USERINFO_STRING(10, home_directory, 21, home_directory, "xx10-21 home_directory", 0);
398 TEST_USERINFO_STRING(21, home_directory, 21, home_directory, "xx21-21 home_directory",
399 SAMR_FIELD_HOME_DIRECTORY);
400 TEST_USERINFO_STRING(21, home_directory, 10, home_directory, "xx21-10 home_directory",
401 SAMR_FIELD_HOME_DIRECTORY);
403 TEST_USERINFO_STRING(10, home_drive, 3, home_drive, "xx10-3 home_drive", 0);
404 TEST_USERINFO_STRING(10, home_drive, 5, home_drive, "xx10-5 home_drive", 0);
405 TEST_USERINFO_STRING(10, home_drive, 21, home_drive, "xx10-21 home_drive", 0);
406 TEST_USERINFO_STRING(21, home_drive, 21, home_drive, "xx21-21 home_drive",
407 SAMR_FIELD_HOME_DRIVE);
408 TEST_USERINFO_STRING(21, home_drive, 10, home_drive, "xx21-10 home_drive",
409 SAMR_FIELD_HOME_DRIVE);
411 TEST_USERINFO_STRING(13, description, 1, description, "xx13-1 description", 0);
412 TEST_USERINFO_STRING(13, description, 5, description, "xx13-5 description", 0);
413 TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
414 TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description",
415 SAMR_FIELD_DESCRIPTION);
417 TEST_USERINFO_STRING(14, workstations, 3, workstations, "14workstation3", 0);
418 TEST_USERINFO_STRING(14, workstations, 5, workstations, "14workstation4", 0);
419 TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
420 TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21",
421 SAMR_FIELD_WORKSTATIONS);
422 TEST_USERINFO_STRING(21, workstations, 3, workstations, "21workstation3",
423 SAMR_FIELD_WORKSTATIONS);
424 TEST_USERINFO_STRING(21, workstations, 5, workstations, "21workstation5",
425 SAMR_FIELD_WORKSTATIONS);
426 TEST_USERINFO_STRING(21, workstations, 14, workstations, "21workstation14",
427 SAMR_FIELD_WORKSTATIONS);
429 TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
430 TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "xx21-21 parameters",
431 SAMR_FIELD_PARAMETERS);
432 TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "xx21-20 parameters",
433 SAMR_FIELD_PARAMETERS);
434 /* also empty user parameters are allowed */
435 TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "", 0);
436 TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "",
437 SAMR_FIELD_PARAMETERS);
438 TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "",
439 SAMR_FIELD_PARAMETERS);
441 /* Samba 3 cannot store country_code and copy_page atm. - gd */
442 if (!torture_setting_bool(tctx, "samba3", false)) {
443 TEST_USERINFO_INT(2, country_code, 2, country_code, __LINE__, 0);
444 TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
445 TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__,
446 SAMR_FIELD_COUNTRY_CODE);
447 TEST_USERINFO_INT(21, country_code, 2, country_code, __LINE__,
448 SAMR_FIELD_COUNTRY_CODE);
450 TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
451 TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__,
452 SAMR_FIELD_CODE_PAGE);
453 TEST_USERINFO_INT(21, code_page, 2, code_page, __LINE__,
454 SAMR_FIELD_CODE_PAGE);
457 if (!torture_setting_bool(tctx, "samba3", false)) {
458 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, __LINE__, 0);
459 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, __LINE__, 0);
460 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, __LINE__,
461 SAMR_FIELD_ACCT_EXPIRY);
462 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, __LINE__,
463 SAMR_FIELD_ACCT_EXPIRY);
464 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, __LINE__,
465 SAMR_FIELD_ACCT_EXPIRY);
467 /* Samba 3 can only store seconds / time_t in passdb - gd */
469 unix_to_nt_time(&nt, time(NULL) + __LINE__);
470 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, nt, 0);
471 unix_to_nt_time(&nt, time(NULL) + __LINE__);
472 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, nt, 0);
473 unix_to_nt_time(&nt, time(NULL) + __LINE__);
474 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
475 unix_to_nt_time(&nt, time(NULL) + __LINE__);
476 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
477 unix_to_nt_time(&nt, time(NULL) + __LINE__);
478 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
481 TEST_USERINFO_INT(4, logon_hours.bits[3], 3, logon_hours.bits[3], 1, 0);
482 TEST_USERINFO_INT(4, logon_hours.bits[3], 5, logon_hours.bits[3], 2, 0);
483 TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
484 TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4,
485 SAMR_FIELD_LOGON_HOURS);
487 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
488 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
489 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
491 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
492 (base_acct_flags | ACB_DISABLED),
493 (base_acct_flags | ACB_DISABLED | user_extra_flags),
496 /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
497 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
498 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
499 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
501 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
502 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
503 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
507 /* The 'autolock' flag doesn't stick - check this */
508 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
509 (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK),
510 (base_acct_flags | ACB_DISABLED | user_extra_flags),
513 /* Removing the 'disabled' flag doesn't stick - check this */
514 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
516 (base_acct_flags | ACB_DISABLED | user_extra_flags),
520 /* Samba3 cannot store these atm */
521 if (!torture_setting_bool(tctx, "samba3", false)) {
522 /* The 'store plaintext' flag does stick */
523 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
524 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED),
525 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags),
527 /* The 'use DES' flag does stick */
528 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
529 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY),
530 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags),
532 /* The 'don't require kerberos pre-authentication flag does stick */
533 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
534 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH),
535 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags),
537 /* The 'no kerberos PAC required' flag sticks */
538 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
539 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD),
540 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags),
543 TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags,
544 (base_acct_flags | ACB_DISABLED),
545 (base_acct_flags | ACB_DISABLED | user_extra_flags),
546 SAMR_FIELD_ACCT_FLAGS);
549 /* these fail with win2003 - it appears you can't set the primary gid?
550 the set succeeds, but the gid isn't changed. Very weird! */
551 TEST_USERINFO_INT(9, primary_gid, 1, primary_gid, 513);
552 TEST_USERINFO_INT(9, primary_gid, 3, primary_gid, 513);
553 TEST_USERINFO_INT(9, primary_gid, 5, primary_gid, 513);
554 TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
561 generate a random password for password change tests
563 static char *samr_rand_pass_silent(TALLOC_CTX *mem_ctx, int min_len)
565 size_t len = MAX(8, min_len) + (random() % 6);
566 char *s = generate_random_str(mem_ctx, len);
570 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
572 char *s = samr_rand_pass_silent(mem_ctx, min_len);
573 printf("Generated password '%s'\n", s);
579 generate a random password for password change tests
581 static DATA_BLOB samr_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
584 DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
585 generate_random_buffer(password.data, password.length);
587 for (i=0; i < len; i++) {
588 if (((uint16_t *)password.data)[i] == 0) {
589 ((uint16_t *)password.data)[i] = 1;
597 generate a random password for password change tests (fixed length)
599 static char *samr_rand_pass_fixed_len(TALLOC_CTX *mem_ctx, int len)
601 char *s = generate_random_str(mem_ctx, len);
602 printf("Generated password '%s'\n", s);
606 static bool test_SetUserPass(struct dcerpc_pipe *p, struct torture_context *tctx,
607 struct policy_handle *handle, char **password)
610 struct samr_SetUserInfo s;
611 union samr_UserInfo u;
613 DATA_BLOB session_key;
615 struct samr_GetUserPwInfo pwp;
616 struct samr_PwInfo info;
617 int policy_min_pw_len = 0;
618 pwp.in.user_handle = handle;
619 pwp.out.info = &info;
621 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
622 if (NT_STATUS_IS_OK(status)) {
623 policy_min_pw_len = pwp.out.info->min_password_length;
625 newpass = samr_rand_pass(tctx, policy_min_pw_len);
627 s.in.user_handle = handle;
631 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
632 u.info24.password_expired = 0;
634 status = dcerpc_fetch_session_key(p, &session_key);
635 if (!NT_STATUS_IS_OK(status)) {
636 printf("SetUserInfo level %u - no session key - %s\n",
637 s.in.level, nt_errstr(status));
641 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
643 torture_comment(tctx, "Testing SetUserInfo level 24 (set password)\n");
645 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
646 if (!NT_STATUS_IS_OK(status)) {
647 printf("SetUserInfo level %u failed - %s\n",
648 s.in.level, nt_errstr(status));
658 static bool test_SetUserPass_23(struct dcerpc_pipe *p, struct torture_context *tctx,
659 struct policy_handle *handle, uint32_t fields_present,
663 struct samr_SetUserInfo s;
664 union samr_UserInfo u;
666 DATA_BLOB session_key;
668 struct samr_GetUserPwInfo pwp;
669 struct samr_PwInfo info;
670 int policy_min_pw_len = 0;
671 pwp.in.user_handle = handle;
672 pwp.out.info = &info;
674 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
675 if (NT_STATUS_IS_OK(status)) {
676 policy_min_pw_len = pwp.out.info->min_password_length;
678 newpass = samr_rand_pass(tctx, policy_min_pw_len);
680 s.in.user_handle = handle;
686 u.info23.info.fields_present = fields_present;
688 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
690 status = dcerpc_fetch_session_key(p, &session_key);
691 if (!NT_STATUS_IS_OK(status)) {
692 printf("SetUserInfo level %u - no session key - %s\n",
693 s.in.level, nt_errstr(status));
697 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
699 torture_comment(tctx, "Testing SetUserInfo level 23 (set password)\n");
701 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
702 if (!NT_STATUS_IS_OK(status)) {
703 printf("SetUserInfo level %u failed - %s\n",
704 s.in.level, nt_errstr(status));
710 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
712 status = dcerpc_fetch_session_key(p, &session_key);
713 if (!NT_STATUS_IS_OK(status)) {
714 printf("SetUserInfo level %u - no session key - %s\n",
715 s.in.level, nt_errstr(status));
719 /* This should break the key nicely */
720 session_key.length--;
721 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
723 torture_comment(tctx, "Testing SetUserInfo level 23 (set password) with wrong password\n");
725 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
726 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
727 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
728 s.in.level, nt_errstr(status));
736 static bool test_SetUserPassEx(struct dcerpc_pipe *p, struct torture_context *tctx,
737 struct policy_handle *handle, bool makeshort,
741 struct samr_SetUserInfo s;
742 union samr_UserInfo u;
744 DATA_BLOB session_key;
745 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
746 uint8_t confounder[16];
748 struct MD5Context ctx;
749 struct samr_GetUserPwInfo pwp;
750 struct samr_PwInfo info;
751 int policy_min_pw_len = 0;
752 pwp.in.user_handle = handle;
753 pwp.out.info = &info;
755 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
756 if (NT_STATUS_IS_OK(status)) {
757 policy_min_pw_len = pwp.out.info->min_password_length;
759 if (makeshort && policy_min_pw_len) {
760 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len - 1);
762 newpass = samr_rand_pass(tctx, policy_min_pw_len);
765 s.in.user_handle = handle;
769 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
770 u.info26.password_expired = 0;
772 status = dcerpc_fetch_session_key(p, &session_key);
773 if (!NT_STATUS_IS_OK(status)) {
774 printf("SetUserInfo level %u - no session key - %s\n",
775 s.in.level, nt_errstr(status));
779 generate_random_buffer((uint8_t *)confounder, 16);
782 MD5Update(&ctx, confounder, 16);
783 MD5Update(&ctx, session_key.data, session_key.length);
784 MD5Final(confounded_session_key.data, &ctx);
786 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
787 memcpy(&u.info26.password.data[516], confounder, 16);
789 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex)\n");
791 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
792 if (!NT_STATUS_IS_OK(status)) {
793 printf("SetUserInfo level %u failed - %s\n",
794 s.in.level, nt_errstr(status));
800 /* This should break the key nicely */
801 confounded_session_key.data[0]++;
803 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
804 memcpy(&u.info26.password.data[516], confounder, 16);
806 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
808 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
809 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
810 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
811 s.in.level, nt_errstr(status));
820 static bool test_SetUserPass_25(struct dcerpc_pipe *p, struct torture_context *tctx,
821 struct policy_handle *handle, uint32_t fields_present,
825 struct samr_SetUserInfo s;
826 union samr_UserInfo u;
828 DATA_BLOB session_key;
829 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
830 struct MD5Context ctx;
831 uint8_t confounder[16];
833 struct samr_GetUserPwInfo pwp;
834 struct samr_PwInfo info;
835 int policy_min_pw_len = 0;
836 pwp.in.user_handle = handle;
837 pwp.out.info = &info;
839 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
840 if (NT_STATUS_IS_OK(status)) {
841 policy_min_pw_len = pwp.out.info->min_password_length;
843 newpass = samr_rand_pass(tctx, policy_min_pw_len);
845 s.in.user_handle = handle;
851 u.info25.info.fields_present = fields_present;
853 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
855 status = dcerpc_fetch_session_key(p, &session_key);
856 if (!NT_STATUS_IS_OK(status)) {
857 printf("SetUserInfo level %u - no session key - %s\n",
858 s.in.level, nt_errstr(status));
862 generate_random_buffer((uint8_t *)confounder, 16);
865 MD5Update(&ctx, confounder, 16);
866 MD5Update(&ctx, session_key.data, session_key.length);
867 MD5Final(confounded_session_key.data, &ctx);
869 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
870 memcpy(&u.info25.password.data[516], confounder, 16);
872 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex)\n");
874 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
875 if (!NT_STATUS_IS_OK(status)) {
876 printf("SetUserInfo level %u failed - %s\n",
877 s.in.level, nt_errstr(status));
883 /* This should break the key nicely */
884 confounded_session_key.data[0]++;
886 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
887 memcpy(&u.info25.password.data[516], confounder, 16);
889 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
891 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
892 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
893 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
894 s.in.level, nt_errstr(status));
901 static bool test_SetUserPass_18(struct dcerpc_pipe *p, struct torture_context *tctx,
902 struct policy_handle *handle, char **password)
905 struct samr_SetUserInfo s;
906 union samr_UserInfo u;
908 DATA_BLOB session_key;
910 struct samr_GetUserPwInfo pwp;
911 struct samr_PwInfo info;
912 int policy_min_pw_len = 0;
913 uint8_t lm_hash[16], nt_hash[16];
915 pwp.in.user_handle = handle;
916 pwp.out.info = &info;
918 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
919 if (NT_STATUS_IS_OK(status)) {
920 policy_min_pw_len = pwp.out.info->min_password_length;
922 newpass = samr_rand_pass(tctx, policy_min_pw_len);
924 s.in.user_handle = handle;
930 u.info18.nt_pwd_active = true;
931 u.info18.lm_pwd_active = true;
933 E_md4hash(newpass, nt_hash);
934 E_deshash(newpass, lm_hash);
936 status = dcerpc_fetch_session_key(p, &session_key);
937 if (!NT_STATUS_IS_OK(status)) {
938 printf("SetUserInfo level %u - no session key - %s\n",
939 s.in.level, nt_errstr(status));
945 in = data_blob_const(nt_hash, 16);
946 out = data_blob_talloc_zero(tctx, 16);
947 sess_crypt_blob(&out, &in, &session_key, true);
948 memcpy(u.info18.nt_pwd.hash, out.data, out.length);
952 in = data_blob_const(lm_hash, 16);
953 out = data_blob_talloc_zero(tctx, 16);
954 sess_crypt_blob(&out, &in, &session_key, true);
955 memcpy(u.info18.lm_pwd.hash, out.data, out.length);
958 torture_comment(tctx, "Testing SetUserInfo level 18 (set password hash)\n");
960 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
961 if (!NT_STATUS_IS_OK(status)) {
962 printf("SetUserInfo level %u failed - %s\n",
963 s.in.level, nt_errstr(status));
972 static bool test_SetUserPass_21(struct dcerpc_pipe *p, struct torture_context *tctx,
973 struct policy_handle *handle, uint32_t fields_present,
977 struct samr_SetUserInfo s;
978 union samr_UserInfo u;
980 DATA_BLOB session_key;
982 struct samr_GetUserPwInfo pwp;
983 struct samr_PwInfo info;
984 int policy_min_pw_len = 0;
985 uint8_t lm_hash[16], nt_hash[16];
987 pwp.in.user_handle = handle;
988 pwp.out.info = &info;
990 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
991 if (NT_STATUS_IS_OK(status)) {
992 policy_min_pw_len = pwp.out.info->min_password_length;
994 newpass = samr_rand_pass(tctx, policy_min_pw_len);
996 s.in.user_handle = handle;
1000 E_md4hash(newpass, nt_hash);
1001 E_deshash(newpass, lm_hash);
1005 u.info21.fields_present = fields_present;
1007 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1008 u.info21.lm_owf_password.length = 16;
1009 u.info21.lm_owf_password.size = 16;
1010 u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
1011 u.info21.lm_password_set = true;
1014 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1015 u.info21.nt_owf_password.length = 16;
1016 u.info21.nt_owf_password.size = 16;
1017 u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
1018 u.info21.nt_password_set = true;
1021 status = dcerpc_fetch_session_key(p, &session_key);
1022 if (!NT_STATUS_IS_OK(status)) {
1023 printf("SetUserInfo level %u - no session key - %s\n",
1024 s.in.level, nt_errstr(status));
1028 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1030 in = data_blob_const(u.info21.lm_owf_password.array,
1031 u.info21.lm_owf_password.length);
1032 out = data_blob_talloc_zero(tctx, 16);
1033 sess_crypt_blob(&out, &in, &session_key, true);
1034 u.info21.lm_owf_password.array = (uint16_t *)out.data;
1037 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1039 in = data_blob_const(u.info21.nt_owf_password.array,
1040 u.info21.nt_owf_password.length);
1041 out = data_blob_talloc_zero(tctx, 16);
1042 sess_crypt_blob(&out, &in, &session_key, true);
1043 u.info21.nt_owf_password.array = (uint16_t *)out.data;
1046 torture_comment(tctx, "Testing SetUserInfo level 21 (set password hash)\n");
1048 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1049 if (!NT_STATUS_IS_OK(status)) {
1050 printf("SetUserInfo level %u failed - %s\n",
1051 s.in.level, nt_errstr(status));
1054 *password = newpass;
1057 /* try invalid length */
1058 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1060 u.info21.nt_owf_password.length++;
1062 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1064 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1065 printf("SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1066 s.in.level, nt_errstr(status));
1071 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1073 u.info21.lm_owf_password.length++;
1075 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1077 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1078 printf("SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1079 s.in.level, nt_errstr(status));
1087 static bool test_SetUserPass_level_ex(struct dcerpc_pipe *p,
1088 struct torture_context *tctx,
1089 struct policy_handle *handle,
1091 uint32_t fields_present,
1092 char **password, uint8_t password_expired,
1094 bool *matched_expected_error)
1097 NTSTATUS expected_error = NT_STATUS_OK;
1098 struct samr_SetUserInfo s;
1099 struct samr_SetUserInfo2 s2;
1100 union samr_UserInfo u;
1102 DATA_BLOB session_key;
1103 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
1104 struct MD5Context ctx;
1105 uint8_t confounder[16];
1107 struct samr_GetUserPwInfo pwp;
1108 struct samr_PwInfo info;
1109 int policy_min_pw_len = 0;
1110 const char *comment = NULL;
1111 uint8_t lm_hash[16], nt_hash[16];
1113 pwp.in.user_handle = handle;
1114 pwp.out.info = &info;
1116 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1117 if (NT_STATUS_IS_OK(status)) {
1118 policy_min_pw_len = pwp.out.info->min_password_length;
1120 newpass = samr_rand_pass_silent(tctx, policy_min_pw_len);
1123 s2.in.user_handle = handle;
1125 s2.in.level = level;
1127 s.in.user_handle = handle;
1132 if (fields_present & SAMR_FIELD_COMMENT) {
1133 comment = talloc_asprintf(tctx, "comment: %ld\n", time(NULL));
1140 E_md4hash(newpass, nt_hash);
1141 E_deshash(newpass, lm_hash);
1143 u.info18.nt_pwd_active = true;
1144 u.info18.lm_pwd_active = true;
1145 u.info18.password_expired = password_expired;
1147 memcpy(u.info18.lm_pwd.hash, lm_hash, 16);
1148 memcpy(u.info18.nt_pwd.hash, nt_hash, 16);
1152 E_md4hash(newpass, nt_hash);
1153 E_deshash(newpass, lm_hash);
1155 u.info21.fields_present = fields_present;
1156 u.info21.password_expired = password_expired;
1157 u.info21.comment.string = comment;
1159 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1160 u.info21.lm_owf_password.length = 16;
1161 u.info21.lm_owf_password.size = 16;
1162 u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
1163 u.info21.lm_password_set = true;
1166 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1167 u.info21.nt_owf_password.length = 16;
1168 u.info21.nt_owf_password.size = 16;
1169 u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
1170 u.info21.nt_password_set = true;
1175 u.info23.info.fields_present = fields_present;
1176 u.info23.info.password_expired = password_expired;
1177 u.info23.info.comment.string = comment;
1179 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
1183 u.info24.password_expired = password_expired;
1185 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
1189 u.info25.info.fields_present = fields_present;
1190 u.info25.info.password_expired = password_expired;
1191 u.info25.info.comment.string = comment;
1193 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
1197 u.info26.password_expired = password_expired;
1199 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
1204 status = dcerpc_fetch_session_key(p, &session_key);
1205 if (!NT_STATUS_IS_OK(status)) {
1206 printf("SetUserInfo level %u - no session key - %s\n",
1207 s.in.level, nt_errstr(status));
1211 generate_random_buffer((uint8_t *)confounder, 16);
1214 MD5Update(&ctx, confounder, 16);
1215 MD5Update(&ctx, session_key.data, session_key.length);
1216 MD5Final(confounded_session_key.data, &ctx);
1222 in = data_blob_const(u.info18.nt_pwd.hash, 16);
1223 out = data_blob_talloc_zero(tctx, 16);
1224 sess_crypt_blob(&out, &in, &session_key, true);
1225 memcpy(u.info18.nt_pwd.hash, out.data, out.length);
1229 in = data_blob_const(u.info18.lm_pwd.hash, 16);
1230 out = data_blob_talloc_zero(tctx, 16);
1231 sess_crypt_blob(&out, &in, &session_key, true);
1232 memcpy(u.info18.lm_pwd.hash, out.data, out.length);
1237 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1239 in = data_blob_const(u.info21.lm_owf_password.array,
1240 u.info21.lm_owf_password.length);
1241 out = data_blob_talloc_zero(tctx, 16);
1242 sess_crypt_blob(&out, &in, &session_key, true);
1243 u.info21.lm_owf_password.array = (uint16_t *)out.data;
1245 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1247 in = data_blob_const(u.info21.nt_owf_password.array,
1248 u.info21.nt_owf_password.length);
1249 out = data_blob_talloc_zero(tctx, 16);
1250 sess_crypt_blob(&out, &in, &session_key, true);
1251 u.info21.nt_owf_password.array = (uint16_t *)out.data;
1255 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
1258 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
1261 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
1262 memcpy(&u.info25.password.data[516], confounder, 16);
1265 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
1266 memcpy(&u.info26.password.data[516], confounder, 16);
1271 status = dcerpc_samr_SetUserInfo2(p, tctx, &s2);
1273 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1276 if (!NT_STATUS_IS_OK(status)) {
1277 if (fields_present == 0) {
1278 expected_error = NT_STATUS_INVALID_PARAMETER;
1280 if (fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
1281 expected_error = NT_STATUS_ACCESS_DENIED;
1285 if (!NT_STATUS_IS_OK(expected_error)) {
1287 torture_assert_ntstatus_equal(tctx,
1289 expected_error, "SetUserInfo2 failed");
1291 torture_assert_ntstatus_equal(tctx,
1293 expected_error, "SetUserInfo failed");
1295 *matched_expected_error = true;
1299 if (!NT_STATUS_IS_OK(status)) {
1300 printf("SetUserInfo%s level %u failed - %s\n",
1301 use_setinfo2 ? "2":"", level, nt_errstr(status));
1304 *password = newpass;
1310 static bool test_SetAliasInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1311 struct policy_handle *handle)
1314 struct samr_SetAliasInfo r;
1315 struct samr_QueryAliasInfo q;
1316 union samr_AliasInfo *info;
1317 uint16_t levels[] = {2, 3};
1321 /* Ignoring switch level 1, as that includes the number of members for the alias
1322 * and setting this to a wrong value might have negative consequences
1325 for (i=0;i<ARRAY_SIZE(levels);i++) {
1326 torture_comment(tctx, "Testing SetAliasInfo level %u\n", levels[i]);
1328 r.in.alias_handle = handle;
1329 r.in.level = levels[i];
1330 r.in.info = talloc(tctx, union samr_AliasInfo);
1331 switch (r.in.level) {
1332 case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
1333 case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
1334 "Test Description, should test I18N as well"); break;
1335 case ALIASINFOALL: printf("ALIASINFOALL ignored\n"); break;
1338 status = dcerpc_samr_SetAliasInfo(p, tctx, &r);
1339 if (!NT_STATUS_IS_OK(status)) {
1340 printf("SetAliasInfo level %u failed - %s\n",
1341 levels[i], nt_errstr(status));
1345 q.in.alias_handle = handle;
1346 q.in.level = levels[i];
1349 status = dcerpc_samr_QueryAliasInfo(p, tctx, &q);
1350 if (!NT_STATUS_IS_OK(status)) {
1351 printf("QueryAliasInfo level %u failed - %s\n",
1352 levels[i], nt_errstr(status));
1360 static bool test_GetGroupsForUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1361 struct policy_handle *user_handle)
1363 struct samr_GetGroupsForUser r;
1364 struct samr_RidWithAttributeArray *rids = NULL;
1367 torture_comment(tctx, "testing GetGroupsForUser\n");
1369 r.in.user_handle = user_handle;
1372 status = dcerpc_samr_GetGroupsForUser(p, tctx, &r);
1373 torture_assert_ntstatus_ok(tctx, status, "GetGroupsForUser");
1379 static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1380 struct lsa_String *domain_name)
1383 struct samr_GetDomPwInfo r;
1384 struct samr_PwInfo info;
1386 r.in.domain_name = domain_name;
1389 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1391 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1392 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1394 r.in.domain_name->string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1395 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1397 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1398 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1400 r.in.domain_name->string = "\\\\__NONAME__";
1401 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1403 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1404 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1406 r.in.domain_name->string = "\\\\Builtin";
1407 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1409 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1410 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1415 static bool test_GetUserPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1416 struct policy_handle *handle)
1419 struct samr_GetUserPwInfo r;
1420 struct samr_PwInfo info;
1422 torture_comment(tctx, "Testing GetUserPwInfo\n");
1424 r.in.user_handle = handle;
1427 status = dcerpc_samr_GetUserPwInfo(p, tctx, &r);
1428 torture_assert_ntstatus_ok(tctx, status, "GetUserPwInfo");
1433 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, struct torture_context *tctx,
1434 struct policy_handle *domain_handle, const char *name,
1438 struct samr_LookupNames n;
1439 struct lsa_String sname[2];
1440 struct samr_Ids rids, types;
1442 init_lsa_String(&sname[0], name);
1444 n.in.domain_handle = domain_handle;
1448 n.out.types = &types;
1449 status = dcerpc_samr_LookupNames(p, tctx, &n);
1450 if (NT_STATUS_IS_OK(status)) {
1451 *rid = n.out.rids->ids[0];
1456 init_lsa_String(&sname[1], "xxNONAMExx");
1458 status = dcerpc_samr_LookupNames(p, tctx, &n);
1459 if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
1460 printf("LookupNames[2] failed - %s\n", nt_errstr(status));
1461 if (NT_STATUS_IS_OK(status)) {
1462 return NT_STATUS_UNSUCCESSFUL;
1468 status = dcerpc_samr_LookupNames(p, tctx, &n);
1469 if (!NT_STATUS_IS_OK(status)) {
1470 printf("LookupNames[0] failed - %s\n", nt_errstr(status));
1474 init_lsa_String(&sname[0], "xxNONAMExx");
1476 status = dcerpc_samr_LookupNames(p, tctx, &n);
1477 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1478 printf("LookupNames[1 bad name] failed - %s\n", nt_errstr(status));
1479 if (NT_STATUS_IS_OK(status)) {
1480 return NT_STATUS_UNSUCCESSFUL;
1485 init_lsa_String(&sname[0], "xxNONAMExx");
1486 init_lsa_String(&sname[1], "xxNONAME2xx");
1488 status = dcerpc_samr_LookupNames(p, tctx, &n);
1489 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1490 printf("LookupNames[2 bad names] failed - %s\n", nt_errstr(status));
1491 if (NT_STATUS_IS_OK(status)) {
1492 return NT_STATUS_UNSUCCESSFUL;
1497 return NT_STATUS_OK;
1500 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p,
1501 struct torture_context *tctx,
1502 struct policy_handle *domain_handle,
1503 const char *name, struct policy_handle *user_handle)
1506 struct samr_OpenUser r;
1509 status = test_LookupName(p, tctx, domain_handle, name, &rid);
1510 if (!NT_STATUS_IS_OK(status)) {
1514 r.in.domain_handle = domain_handle;
1515 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1517 r.out.user_handle = user_handle;
1518 status = dcerpc_samr_OpenUser(p, tctx, &r);
1519 if (!NT_STATUS_IS_OK(status)) {
1520 printf("OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(status));
1527 static bool test_ChangePasswordNT3(struct dcerpc_pipe *p,
1528 struct torture_context *tctx,
1529 struct policy_handle *handle)
1532 struct samr_ChangePasswordUser r;
1534 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1535 struct policy_handle user_handle;
1536 char *oldpass = "test";
1537 char *newpass = "test2";
1538 uint8_t old_nt_hash[16], new_nt_hash[16];
1539 uint8_t old_lm_hash[16], new_lm_hash[16];
1541 status = test_OpenUser_byname(p, tctx, handle, "testuser", &user_handle);
1542 if (!NT_STATUS_IS_OK(status)) {
1546 printf("Testing ChangePasswordUser for user 'testuser'\n");
1548 printf("old password: %s\n", oldpass);
1549 printf("new password: %s\n", newpass);
1551 E_md4hash(oldpass, old_nt_hash);
1552 E_md4hash(newpass, new_nt_hash);
1553 E_deshash(oldpass, old_lm_hash);
1554 E_deshash(newpass, new_lm_hash);
1556 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1557 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1558 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1559 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1560 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1561 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1563 r.in.handle = &user_handle;
1564 r.in.lm_present = 1;
1565 r.in.old_lm_crypted = &hash1;
1566 r.in.new_lm_crypted = &hash2;
1567 r.in.nt_present = 1;
1568 r.in.old_nt_crypted = &hash3;
1569 r.in.new_nt_crypted = &hash4;
1570 r.in.cross1_present = 1;
1571 r.in.nt_cross = &hash5;
1572 r.in.cross2_present = 1;
1573 r.in.lm_cross = &hash6;
1575 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1576 if (!NT_STATUS_IS_OK(status)) {
1577 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1581 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
1589 static bool test_ChangePasswordUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1590 const char *acct_name,
1591 struct policy_handle *handle, char **password)
1594 struct samr_ChangePasswordUser r;
1596 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1597 struct policy_handle user_handle;
1599 uint8_t old_nt_hash[16], new_nt_hash[16];
1600 uint8_t old_lm_hash[16], new_lm_hash[16];
1601 bool changed = true;
1604 struct samr_GetUserPwInfo pwp;
1605 struct samr_PwInfo info;
1606 int policy_min_pw_len = 0;
1608 status = test_OpenUser_byname(p, tctx, handle, acct_name, &user_handle);
1609 if (!NT_STATUS_IS_OK(status)) {
1612 pwp.in.user_handle = &user_handle;
1613 pwp.out.info = &info;
1615 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1616 if (NT_STATUS_IS_OK(status)) {
1617 policy_min_pw_len = pwp.out.info->min_password_length;
1619 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1621 torture_comment(tctx, "Testing ChangePasswordUser\n");
1623 torture_assert(tctx, *password != NULL,
1624 "Failing ChangePasswordUser as old password was NULL. Previous test failed?");
1626 oldpass = *password;
1628 E_md4hash(oldpass, old_nt_hash);
1629 E_md4hash(newpass, new_nt_hash);
1630 E_deshash(oldpass, old_lm_hash);
1631 E_deshash(newpass, new_lm_hash);
1633 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1634 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1635 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1636 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1637 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1638 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1640 r.in.user_handle = &user_handle;
1641 r.in.lm_present = 1;
1642 /* Break the LM hash */
1644 r.in.old_lm_crypted = &hash1;
1645 r.in.new_lm_crypted = &hash2;
1646 r.in.nt_present = 1;
1647 r.in.old_nt_crypted = &hash3;
1648 r.in.new_nt_crypted = &hash4;
1649 r.in.cross1_present = 1;
1650 r.in.nt_cross = &hash5;
1651 r.in.cross2_present = 1;
1652 r.in.lm_cross = &hash6;
1654 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1655 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1656 "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash");
1658 /* Unbreak the LM hash */
1661 r.in.user_handle = &user_handle;
1662 r.in.lm_present = 1;
1663 r.in.old_lm_crypted = &hash1;
1664 r.in.new_lm_crypted = &hash2;
1665 /* Break the NT hash */
1667 r.in.nt_present = 1;
1668 r.in.old_nt_crypted = &hash3;
1669 r.in.new_nt_crypted = &hash4;
1670 r.in.cross1_present = 1;
1671 r.in.nt_cross = &hash5;
1672 r.in.cross2_present = 1;
1673 r.in.lm_cross = &hash6;
1675 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1676 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1677 "expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash");
1679 /* Unbreak the NT hash */
1682 r.in.user_handle = &user_handle;
1683 r.in.lm_present = 1;
1684 r.in.old_lm_crypted = &hash1;
1685 r.in.new_lm_crypted = &hash2;
1686 r.in.nt_present = 1;
1687 r.in.old_nt_crypted = &hash3;
1688 r.in.new_nt_crypted = &hash4;
1689 r.in.cross1_present = 1;
1690 r.in.nt_cross = &hash5;
1691 r.in.cross2_present = 1;
1692 /* Break the LM cross */
1694 r.in.lm_cross = &hash6;
1696 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1697 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1698 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status));
1702 /* Unbreak the LM cross */
1705 r.in.user_handle = &user_handle;
1706 r.in.lm_present = 1;
1707 r.in.old_lm_crypted = &hash1;
1708 r.in.new_lm_crypted = &hash2;
1709 r.in.nt_present = 1;
1710 r.in.old_nt_crypted = &hash3;
1711 r.in.new_nt_crypted = &hash4;
1712 r.in.cross1_present = 1;
1713 /* Break the NT cross */
1715 r.in.nt_cross = &hash5;
1716 r.in.cross2_present = 1;
1717 r.in.lm_cross = &hash6;
1719 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1720 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1721 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status));
1725 /* Unbreak the NT cross */
1729 /* Reset the hashes to not broken values */
1730 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1731 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1732 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1733 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1734 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1735 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1737 r.in.user_handle = &user_handle;
1738 r.in.lm_present = 1;
1739 r.in.old_lm_crypted = &hash1;
1740 r.in.new_lm_crypted = &hash2;
1741 r.in.nt_present = 1;
1742 r.in.old_nt_crypted = &hash3;
1743 r.in.new_nt_crypted = &hash4;
1744 r.in.cross1_present = 1;
1745 r.in.nt_cross = &hash5;
1746 r.in.cross2_present = 0;
1747 r.in.lm_cross = NULL;
1749 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1750 if (NT_STATUS_IS_OK(status)) {
1752 *password = newpass;
1753 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1754 printf("ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(status));
1759 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1761 E_md4hash(oldpass, old_nt_hash);
1762 E_md4hash(newpass, new_nt_hash);
1763 E_deshash(oldpass, old_lm_hash);
1764 E_deshash(newpass, new_lm_hash);
1767 /* Reset the hashes to not broken values */
1768 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1769 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1770 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1771 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1772 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1773 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1775 r.in.user_handle = &user_handle;
1776 r.in.lm_present = 1;
1777 r.in.old_lm_crypted = &hash1;
1778 r.in.new_lm_crypted = &hash2;
1779 r.in.nt_present = 1;
1780 r.in.old_nt_crypted = &hash3;
1781 r.in.new_nt_crypted = &hash4;
1782 r.in.cross1_present = 0;
1783 r.in.nt_cross = NULL;
1784 r.in.cross2_present = 1;
1785 r.in.lm_cross = &hash6;
1787 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1788 if (NT_STATUS_IS_OK(status)) {
1790 *password = newpass;
1791 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1792 printf("ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status));
1797 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1799 E_md4hash(oldpass, old_nt_hash);
1800 E_md4hash(newpass, new_nt_hash);
1801 E_deshash(oldpass, old_lm_hash);
1802 E_deshash(newpass, new_lm_hash);
1805 /* Reset the hashes to not broken values */
1806 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1807 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1808 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1809 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1810 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1811 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1813 r.in.user_handle = &user_handle;
1814 r.in.lm_present = 1;
1815 r.in.old_lm_crypted = &hash1;
1816 r.in.new_lm_crypted = &hash2;
1817 r.in.nt_present = 1;
1818 r.in.old_nt_crypted = &hash3;
1819 r.in.new_nt_crypted = &hash4;
1820 r.in.cross1_present = 1;
1821 r.in.nt_cross = &hash5;
1822 r.in.cross2_present = 1;
1823 r.in.lm_cross = &hash6;
1825 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1826 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1827 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1828 } else if (!NT_STATUS_IS_OK(status)) {
1829 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1833 *password = newpass;
1836 r.in.user_handle = &user_handle;
1837 r.in.lm_present = 1;
1838 r.in.old_lm_crypted = &hash1;
1839 r.in.new_lm_crypted = &hash2;
1840 r.in.nt_present = 1;
1841 r.in.old_nt_crypted = &hash3;
1842 r.in.new_nt_crypted = &hash4;
1843 r.in.cross1_present = 1;
1844 r.in.nt_cross = &hash5;
1845 r.in.cross2_present = 1;
1846 r.in.lm_cross = &hash6;
1849 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1850 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1851 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1852 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1853 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status));
1859 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
1867 static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
1868 const char *acct_name,
1869 struct policy_handle *handle, char **password)
1872 struct samr_OemChangePasswordUser2 r;
1874 struct samr_Password lm_verifier;
1875 struct samr_CryptPassword lm_pass;
1876 struct lsa_AsciiString server, account, account_bad;
1879 uint8_t old_lm_hash[16], new_lm_hash[16];
1881 struct samr_GetDomPwInfo dom_pw_info;
1882 struct samr_PwInfo info;
1883 int policy_min_pw_len = 0;
1885 struct lsa_String domain_name;
1887 domain_name.string = "";
1888 dom_pw_info.in.domain_name = &domain_name;
1889 dom_pw_info.out.info = &info;
1891 torture_comment(tctx, "Testing OemChangePasswordUser2\n");
1893 torture_assert(tctx, *password != NULL,
1894 "Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?");
1896 oldpass = *password;
1898 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
1899 if (NT_STATUS_IS_OK(status)) {
1900 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
1903 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1905 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1906 account.string = acct_name;
1908 E_deshash(oldpass, old_lm_hash);
1909 E_deshash(newpass, new_lm_hash);
1911 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1912 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1913 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1915 r.in.server = &server;
1916 r.in.account = &account;
1917 r.in.password = &lm_pass;
1918 r.in.hash = &lm_verifier;
1920 /* Break the verification */
1921 lm_verifier.hash[0]++;
1923 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1925 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1926 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1927 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1932 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1933 /* Break the old password */
1935 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1936 /* unbreak it for the next operation */
1938 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1940 r.in.server = &server;
1941 r.in.account = &account;
1942 r.in.password = &lm_pass;
1943 r.in.hash = &lm_verifier;
1945 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1947 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1948 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1949 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1954 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1955 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1957 r.in.server = &server;
1958 r.in.account = &account;
1959 r.in.password = &lm_pass;
1962 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1964 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1965 && !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1966 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
1971 /* This shouldn't be a valid name */
1972 account_bad.string = TEST_ACCOUNT_NAME "XX";
1973 r.in.account = &account_bad;
1975 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1977 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1978 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
1983 /* This shouldn't be a valid name */
1984 account_bad.string = TEST_ACCOUNT_NAME "XX";
1985 r.in.account = &account_bad;
1986 r.in.password = &lm_pass;
1987 r.in.hash = &lm_verifier;
1989 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1991 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1992 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1997 /* This shouldn't be a valid name */
1998 account_bad.string = TEST_ACCOUNT_NAME "XX";
1999 r.in.account = &account_bad;
2000 r.in.password = NULL;
2001 r.in.hash = &lm_verifier;
2003 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
2005 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
2006 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
2011 E_deshash(oldpass, old_lm_hash);
2012 E_deshash(newpass, new_lm_hash);
2014 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
2015 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2016 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
2018 r.in.server = &server;
2019 r.in.account = &account;
2020 r.in.password = &lm_pass;
2021 r.in.hash = &lm_verifier;
2023 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
2024 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2025 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
2026 } else if (!NT_STATUS_IS_OK(status)) {
2027 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
2030 *password = newpass;
2037 static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
2038 const char *acct_name,
2040 char *newpass, bool allow_password_restriction)
2043 struct samr_ChangePasswordUser2 r;
2045 struct lsa_String server, account;
2046 struct samr_CryptPassword nt_pass, lm_pass;
2047 struct samr_Password nt_verifier, lm_verifier;
2049 uint8_t old_nt_hash[16], new_nt_hash[16];
2050 uint8_t old_lm_hash[16], new_lm_hash[16];
2052 struct samr_GetDomPwInfo dom_pw_info;
2053 struct samr_PwInfo info;
2055 struct lsa_String domain_name;
2057 domain_name.string = "";
2058 dom_pw_info.in.domain_name = &domain_name;
2059 dom_pw_info.out.info = &info;
2061 torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name);
2063 torture_assert(tctx, *password != NULL,
2064 "Failing ChangePasswordUser2 as old password was NULL. Previous test failed?");
2065 oldpass = *password;
2068 int policy_min_pw_len = 0;
2069 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
2070 if (NT_STATUS_IS_OK(status)) {
2071 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
2074 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2077 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2078 init_lsa_String(&account, acct_name);
2080 E_md4hash(oldpass, old_nt_hash);
2081 E_md4hash(newpass, new_nt_hash);
2083 E_deshash(oldpass, old_lm_hash);
2084 E_deshash(newpass, new_lm_hash);
2086 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
2087 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2088 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2090 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2091 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2092 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2094 r.in.server = &server;
2095 r.in.account = &account;
2096 r.in.nt_password = &nt_pass;
2097 r.in.nt_verifier = &nt_verifier;
2099 r.in.lm_password = &lm_pass;
2100 r.in.lm_verifier = &lm_verifier;
2102 status = dcerpc_samr_ChangePasswordUser2(p, tctx, &r);
2103 if (allow_password_restriction && NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2104 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
2105 } else if (!NT_STATUS_IS_OK(status)) {
2106 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
2109 *password = newpass;
2116 bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tctx,
2117 const char *account_string,
2118 int policy_min_pw_len,
2120 const char *newpass,
2121 NTTIME last_password_change,
2122 bool handle_reject_reason)
2125 struct samr_ChangePasswordUser3 r;
2127 struct lsa_String server, account, account_bad;
2128 struct samr_CryptPassword nt_pass, lm_pass;
2129 struct samr_Password nt_verifier, lm_verifier;
2131 uint8_t old_nt_hash[16], new_nt_hash[16];
2132 uint8_t old_lm_hash[16], new_lm_hash[16];
2134 struct samr_DomInfo1 *dominfo = NULL;
2135 struct samr_ChangeReject *reject = NULL;
2137 torture_comment(tctx, "Testing ChangePasswordUser3\n");
2139 if (newpass == NULL) {
2141 if (policy_min_pw_len == 0) {
2142 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2144 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len);
2146 } while (check_password_quality(newpass) == false);
2148 torture_comment(tctx, "Using password '%s'\n", newpass);
2151 torture_assert(tctx, *password != NULL,
2152 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2154 oldpass = *password;
2155 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2156 init_lsa_String(&account, account_string);
2158 E_md4hash(oldpass, old_nt_hash);
2159 E_md4hash(newpass, new_nt_hash);
2161 E_deshash(oldpass, old_lm_hash);
2162 E_deshash(newpass, new_lm_hash);
2164 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2165 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2166 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2168 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2169 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2170 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2172 /* Break the verification */
2173 nt_verifier.hash[0]++;
2175 r.in.server = &server;
2176 r.in.account = &account;
2177 r.in.nt_password = &nt_pass;
2178 r.in.nt_verifier = &nt_verifier;
2180 r.in.lm_password = &lm_pass;
2181 r.in.lm_verifier = &lm_verifier;
2182 r.in.password3 = NULL;
2183 r.out.dominfo = &dominfo;
2184 r.out.reject = &reject;
2186 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2187 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
2188 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
2189 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
2194 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2195 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2196 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2198 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2199 /* Break the NT hash */
2201 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2202 /* Unbreak it again */
2204 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2206 r.in.server = &server;
2207 r.in.account = &account;
2208 r.in.nt_password = &nt_pass;
2209 r.in.nt_verifier = &nt_verifier;
2211 r.in.lm_password = &lm_pass;
2212 r.in.lm_verifier = &lm_verifier;
2213 r.in.password3 = NULL;
2214 r.out.dominfo = &dominfo;
2215 r.out.reject = &reject;
2217 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2218 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
2219 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
2220 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
2225 /* This shouldn't be a valid name */
2226 init_lsa_String(&account_bad, talloc_asprintf(tctx, "%sXX", account_string));
2228 r.in.account = &account_bad;
2229 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2230 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
2231 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
2236 E_md4hash(oldpass, old_nt_hash);
2237 E_md4hash(newpass, new_nt_hash);
2239 E_deshash(oldpass, old_lm_hash);
2240 E_deshash(newpass, new_lm_hash);
2242 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2243 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2244 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2246 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2247 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2248 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2250 r.in.server = &server;
2251 r.in.account = &account;
2252 r.in.nt_password = &nt_pass;
2253 r.in.nt_verifier = &nt_verifier;
2255 r.in.lm_password = &lm_pass;
2256 r.in.lm_verifier = &lm_verifier;
2257 r.in.password3 = NULL;
2258 r.out.dominfo = &dominfo;
2259 r.out.reject = &reject;
2261 unix_to_nt_time(&t, time(NULL));
2263 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2265 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
2268 && handle_reject_reason
2269 && (!null_nttime(last_password_change) || !dominfo->min_password_age)) {
2270 if (dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
2272 if (reject && (reject->reason != SAMR_REJECT_OTHER)) {
2273 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2274 SAMR_REJECT_OTHER, reject->reason);
2279 /* We tested the order of precendence which is as follows:
2288 if ((dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
2289 (last_password_change + dominfo->min_password_age > t)) {
2291 if (reject->reason != SAMR_REJECT_OTHER) {
2292 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2293 SAMR_REJECT_OTHER, reject->reason);
2297 } else if ((dominfo->min_password_length > 0) &&
2298 (strlen(newpass) < dominfo->min_password_length)) {
2300 if (reject->reason != SAMR_REJECT_TOO_SHORT) {
2301 printf("expected SAMR_REJECT_TOO_SHORT (%d), got %d\n",
2302 SAMR_REJECT_TOO_SHORT, reject->reason);
2306 } else if ((dominfo->password_history_length > 0) &&
2307 strequal(oldpass, newpass)) {
2309 if (reject->reason != SAMR_REJECT_IN_HISTORY) {
2310 printf("expected SAMR_REJECT_IN_HISTORY (%d), got %d\n",
2311 SAMR_REJECT_IN_HISTORY, reject->reason);
2314 } else if (dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
2316 if (reject->reason != SAMR_REJECT_COMPLEXITY) {
2317 printf("expected SAMR_REJECT_COMPLEXITY (%d), got %d\n",
2318 SAMR_REJECT_COMPLEXITY, reject->reason);
2324 if (reject->reason == SAMR_REJECT_TOO_SHORT) {
2325 /* retry with adjusted size */
2326 return test_ChangePasswordUser3(p, tctx, account_string,
2327 dominfo->min_password_length,
2328 password, NULL, 0, false);
2332 } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2333 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2334 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2335 SAMR_REJECT_OTHER, reject->reason);
2338 /* Perhaps the server has a 'min password age' set? */
2341 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3");
2342 *password = talloc_strdup(tctx, newpass);
2348 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_context *tctx,
2349 const char *account_string,
2350 struct policy_handle *handle,
2354 struct samr_ChangePasswordUser3 r;
2355 struct samr_SetUserInfo s;
2356 union samr_UserInfo u;
2357 DATA_BLOB session_key;
2358 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
2359 uint8_t confounder[16];
2360 struct MD5Context ctx;
2363 struct lsa_String server, account;
2364 struct samr_CryptPassword nt_pass;
2365 struct samr_Password nt_verifier;
2366 DATA_BLOB new_random_pass;
2369 uint8_t old_nt_hash[16], new_nt_hash[16];
2371 struct samr_DomInfo1 *dominfo = NULL;
2372 struct samr_ChangeReject *reject = NULL;
2374 new_random_pass = samr_very_rand_pass(tctx, 128);
2376 torture_assert(tctx, *password != NULL,
2377 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2379 oldpass = *password;
2380 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2381 init_lsa_String(&account, account_string);
2383 s.in.user_handle = handle;
2389 u.info25.info.fields_present = SAMR_FIELD_NT_PASSWORD_PRESENT;
2391 set_pw_in_buffer(u.info25.password.data, &new_random_pass);
2393 status = dcerpc_fetch_session_key(p, &session_key);
2394 if (!NT_STATUS_IS_OK(status)) {
2395 printf("SetUserInfo level %u - no session key - %s\n",
2396 s.in.level, nt_errstr(status));
2400 generate_random_buffer((uint8_t *)confounder, 16);
2403 MD5Update(&ctx, confounder, 16);
2404 MD5Update(&ctx, session_key.data, session_key.length);
2405 MD5Final(confounded_session_key.data, &ctx);
2407 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
2408 memcpy(&u.info25.password.data[516], confounder, 16);
2410 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
2412 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
2413 if (!NT_STATUS_IS_OK(status)) {
2414 printf("SetUserInfo level %u failed - %s\n",
2415 s.in.level, nt_errstr(status));
2419 torture_comment(tctx, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
2421 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2423 new_random_pass = samr_very_rand_pass(tctx, 128);
2425 mdfour(new_nt_hash, new_random_pass.data, new_random_pass.length);
2427 set_pw_in_buffer(nt_pass.data, &new_random_pass);
2428 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2429 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2431 r.in.server = &server;
2432 r.in.account = &account;
2433 r.in.nt_password = &nt_pass;
2434 r.in.nt_verifier = &nt_verifier;
2436 r.in.lm_password = NULL;
2437 r.in.lm_verifier = NULL;
2438 r.in.password3 = NULL;
2439 r.out.dominfo = &dominfo;
2440 r.out.reject = &reject;
2442 unix_to_nt_time(&t, time(NULL));
2444 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2446 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2447 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2448 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2449 SAMR_REJECT_OTHER, reject->reason);
2452 /* Perhaps the server has a 'min password age' set? */
2454 } else if (!NT_STATUS_IS_OK(status)) {
2455 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
2459 newpass = samr_rand_pass(tctx, 128);
2461 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2463 E_md4hash(newpass, new_nt_hash);
2465 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2466 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2467 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2469 r.in.server = &server;
2470 r.in.account = &account;
2471 r.in.nt_password = &nt_pass;
2472 r.in.nt_verifier = &nt_verifier;
2474 r.in.lm_password = NULL;
2475 r.in.lm_verifier = NULL;
2476 r.in.password3 = NULL;
2477 r.out.dominfo = &dominfo;
2478 r.out.reject = &reject;
2480 unix_to_nt_time(&t, time(NULL));
2482 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2484 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2485 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2486 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2487 SAMR_REJECT_OTHER, reject->reason);
2490 /* Perhaps the server has a 'min password age' set? */
2493 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3 (on second random password)");
2494 *password = talloc_strdup(tctx, newpass);
2501 static bool test_GetMembersInAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2502 struct policy_handle *alias_handle)
2504 struct samr_GetMembersInAlias r;
2505 struct lsa_SidArray sids;
2508 torture_comment(tctx, "Testing GetMembersInAlias\n");
2510 r.in.alias_handle = alias_handle;
2513 status = dcerpc_samr_GetMembersInAlias(p, tctx, &r);
2514 torture_assert_ntstatus_ok(tctx, status, "GetMembersInAlias");
2519 static bool test_AddMemberToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2520 struct policy_handle *alias_handle,
2521 const struct dom_sid *domain_sid)
2523 struct samr_AddAliasMember r;
2524 struct samr_DeleteAliasMember d;
2526 struct dom_sid *sid;
2528 sid = dom_sid_add_rid(tctx, domain_sid, 512);
2530 torture_comment(tctx, "testing AddAliasMember\n");
2531 r.in.alias_handle = alias_handle;
2534 status = dcerpc_samr_AddAliasMember(p, tctx, &r);
2535 torture_assert_ntstatus_ok(tctx, status, "AddAliasMember");
2537 d.in.alias_handle = alias_handle;
2540 status = dcerpc_samr_DeleteAliasMember(p, tctx, &d);
2541 torture_assert_ntstatus_ok(tctx, status, "DelAliasMember");
2546 static bool test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2547 struct policy_handle *alias_handle)
2549 struct samr_AddMultipleMembersToAlias a;
2550 struct samr_RemoveMultipleMembersFromAlias r;
2552 struct lsa_SidArray sids;
2554 torture_comment(tctx, "testing AddMultipleMembersToAlias\n");
2555 a.in.alias_handle = alias_handle;
2559 sids.sids = talloc_array(tctx, struct lsa_SidPtr, 3);
2561 sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2562 sids.sids[1].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-2");
2563 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-3");
2565 status = dcerpc_samr_AddMultipleMembersToAlias(p, tctx, &a);
2566 torture_assert_ntstatus_ok(tctx, status, "AddMultipleMembersToAlias");
2569 torture_comment(tctx, "testing RemoveMultipleMembersFromAlias\n");
2570 r.in.alias_handle = alias_handle;
2573 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2574 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2576 /* strange! removing twice doesn't give any error */
2577 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2578 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2580 /* but removing an alias that isn't there does */
2581 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-4");
2583 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2584 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, "RemoveMultipleMembersFromAlias");
2589 static bool test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2590 struct policy_handle *user_handle)
2592 struct samr_TestPrivateFunctionsUser r;
2595 torture_comment(tctx, "Testing TestPrivateFunctionsUser\n");
2597 r.in.user_handle = user_handle;
2599 status = dcerpc_samr_TestPrivateFunctionsUser(p, tctx, &r);
2600 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsUser");
2605 static bool test_QueryUserInfo_pwdlastset(struct dcerpc_pipe *p,
2606 struct torture_context *tctx,
2607 struct policy_handle *handle,
2612 uint16_t levels[] = { /* 3, */ 5, 21 };
2614 NTTIME pwdlastset3 = 0;
2615 NTTIME pwdlastset5 = 0;
2616 NTTIME pwdlastset21 = 0;
2618 torture_comment(tctx, "Testing QueryUserInfo%s level 5 and 21 call ",
2619 use_info2 ? "2":"");
2621 for (i=0; i<ARRAY_SIZE(levels); i++) {
2623 struct samr_QueryUserInfo r;
2624 struct samr_QueryUserInfo2 r2;
2625 union samr_UserInfo *info;
2628 r2.in.user_handle = handle;
2629 r2.in.level = levels[i];
2630 r2.out.info = &info;
2631 status = dcerpc_samr_QueryUserInfo2(p, tctx, &r2);
2634 r.in.user_handle = handle;
2635 r.in.level = levels[i];
2637 status = dcerpc_samr_QueryUserInfo(p, tctx, &r);
2640 if (!NT_STATUS_IS_OK(status) &&
2641 !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
2642 printf("QueryUserInfo%s level %u failed - %s\n",
2643 use_info2 ? "2":"", levels[i], nt_errstr(status));
2647 switch (levels[i]) {
2649 pwdlastset3 = info->info3.last_password_change;
2652 pwdlastset5 = info->info5.last_password_change;
2655 pwdlastset21 = info->info21.last_password_change;
2661 /* torture_assert_int_equal(tctx, pwdlastset3, pwdlastset5,
2662 "pwdlastset mixup"); */
2663 torture_assert_int_equal(tctx, pwdlastset5, pwdlastset21,
2664 "pwdlastset mixup");
2666 *pwdlastset = pwdlastset21;
2668 torture_comment(tctx, "(pwdlastset: %lld)\n", *pwdlastset);
2673 static bool test_SamLogon(struct torture_context *tctx,
2674 struct dcerpc_pipe *p,
2675 struct cli_credentials *test_credentials,
2676 NTSTATUS expected_result)
2679 struct netr_LogonSamLogonEx r;
2680 union netr_LogonLevel logon;
2681 union netr_Validation validation;
2682 uint8_t authoritative;
2683 struct netr_NetworkInfo ninfo;
2684 DATA_BLOB names_blob, chal, lm_resp, nt_resp;
2685 int flags = CLI_CRED_NTLM_AUTH;
2686 uint32_t samlogon_flags = 0;
2688 if (lp_client_lanman_auth(tctx->lp_ctx)) {
2689 flags |= CLI_CRED_LANMAN_AUTH;
2692 if (lp_client_ntlmv2_auth(tctx->lp_ctx)) {
2693 flags |= CLI_CRED_NTLMv2_AUTH;
2696 cli_credentials_get_ntlm_username_domain(test_credentials, tctx,
2697 &ninfo.identity_info.account_name.string,
2698 &ninfo.identity_info.domain_name.string);
2700 generate_random_buffer(ninfo.challenge,
2701 sizeof(ninfo.challenge));
2702 chal = data_blob_const(ninfo.challenge,
2703 sizeof(ninfo.challenge));
2705 names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(test_credentials),
2706 cli_credentials_get_domain(test_credentials));
2708 status = cli_credentials_get_ntlm_response(test_credentials, tctx,
2714 torture_assert_ntstatus_ok(tctx, status, "cli_credentials_get_ntlm_response failed");
2716 ninfo.lm.data = lm_resp.data;
2717 ninfo.lm.length = lm_resp.length;
2719 ninfo.nt.data = nt_resp.data;
2720 ninfo.nt.length = nt_resp.length;
2722 ninfo.identity_info.parameter_control =
2723 MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT |
2724 MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;
2725 ninfo.identity_info.logon_id_low = 0;
2726 ninfo.identity_info.logon_id_high = 0;
2727 ninfo.identity_info.workstation.string = cli_credentials_get_workstation(test_credentials);
2729 logon.network = &ninfo;
2731 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2732 r.in.computer_name = cli_credentials_get_workstation(test_credentials);
2733 r.in.logon_level = NetlogonNetworkInformation;
2734 r.in.logon = &logon;
2735 r.in.flags = &samlogon_flags;
2736 r.out.flags = &samlogon_flags;
2737 r.out.validation = &validation;
2738 r.out.authoritative = &authoritative;
2740 d_printf("Testing LogonSamLogon with name %s\n", ninfo.identity_info.account_name.string);
2742 r.in.validation_level = 6;
2744 status = dcerpc_netr_LogonSamLogonEx(p, tctx, &r);
2745 if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
2746 r.in.validation_level = 3;
2747 status = dcerpc_netr_LogonSamLogonEx(p, tctx, &r);
2749 if (!NT_STATUS_IS_OK(status)) {
2750 torture_assert_ntstatus_equal(tctx, status, expected_result, "LogonSamLogonEx failed");
2753 torture_assert_ntstatus_ok(tctx, status, "LogonSamLogonEx failed");
2759 static bool test_SamLogon_with_creds(struct torture_context *tctx,
2760 struct dcerpc_pipe *p,
2761 struct cli_credentials *machine_creds,
2762 const char *acct_name,
2764 NTSTATUS expected_samlogon_result)
2767 struct cli_credentials *test_credentials;
2769 test_credentials = cli_credentials_init(tctx);
2771 cli_credentials_set_workstation(test_credentials,
2772 cli_credentials_get_workstation(machine_creds), CRED_SPECIFIED);
2773 cli_credentials_set_domain(test_credentials,
2774 cli_credentials_get_domain(machine_creds), CRED_SPECIFIED);
2775 cli_credentials_set_username(test_credentials,
2776 acct_name, CRED_SPECIFIED);
2777 cli_credentials_set_password(test_credentials,
2778 password, CRED_SPECIFIED);
2780 printf("testing samlogon as %s password: %s\n",
2781 acct_name, password);
2783 if (!test_SamLogon(tctx, p, test_credentials,
2784 expected_samlogon_result)) {
2785 torture_warning(tctx, "new password did not work\n");
2792 static bool test_SetPassword_level(struct dcerpc_pipe *p,
2793 struct dcerpc_pipe *np,
2794 struct torture_context *tctx,
2795 struct policy_handle *handle,
2797 uint32_t fields_present,
2798 uint8_t password_expired,
2799 bool *matched_expected_error,
2801 const char *acct_name,
2803 struct cli_credentials *machine_creds,
2804 bool use_queryinfo2,
2806 NTSTATUS expected_samlogon_result)
2808 const char *fields = NULL;
2815 fields = talloc_asprintf(tctx, "(fields_present: 0x%08x)",
2822 torture_comment(tctx, "Testing SetUserInfo%s level %d call "
2823 "(password_expired: %d) %s\n",
2824 use_setinfo2 ? "2":"", level, password_expired,
2825 fields ? fields : "");
2827 if (!test_SetUserPass_level_ex(p, tctx, handle, level,
2832 matched_expected_error)) {
2836 if (!test_QueryUserInfo_pwdlastset(p, tctx, handle,
2842 if (*matched_expected_error == true) {
2846 if (!test_SamLogon_with_creds(tctx, np,
2850 expected_samlogon_result)) {
2857 static bool test_SetPassword_pwdlastset(struct dcerpc_pipe *p,
2858 struct torture_context *tctx,
2859 uint32_t acct_flags,
2860 const char *acct_name,
2861 struct policy_handle *handle,
2863 struct cli_credentials *machine_credentials)
2865 int s = 0, q = 0, f = 0, l = 0, z = 0;
2866 struct dcerpc_binding *b;
2869 bool set_levels[] = { false, true };
2870 bool query_levels[] = { false, true };
2871 uint32_t levels[] = { 18, 21, 26, 23, 24, 25 }; /* Second half only used when TEST_ALL_LEVELS defined */
2872 uint32_t nonzeros[] = { 1, 24 };
2873 uint32_t fields_present[] = {
2875 SAMR_FIELD_EXPIRED_FLAG,
2876 SAMR_FIELD_LAST_PWD_CHANGE,
2877 SAMR_FIELD_EXPIRED_FLAG | SAMR_FIELD_LAST_PWD_CHANGE,
2879 SAMR_FIELD_NT_PASSWORD_PRESENT,
2880 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
2881 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
2882 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
2883 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
2884 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
2885 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE | SAMR_FIELD_EXPIRED_FLAG
2888 struct dcerpc_pipe *np = NULL;
2890 if (torture_setting_bool(tctx, "samba3", false)) {
2892 printf("Samba3 has second granularity, setting delay to: %d\n",
2896 status = torture_rpc_binding(tctx, &b);
2897 if (!NT_STATUS_IS_OK(status)) {
2902 /* We have to use schannel, otherwise the SamLogonEx fails
2903 * with INTERNAL_ERROR */
2905 b->flags &= ~DCERPC_AUTH_OPTIONS;
2906 b->flags |= DCERPC_SCHANNEL | DCERPC_SIGN | DCERPC_SCHANNEL_128;
2908 status = dcerpc_pipe_connect_b(tctx, &np, b,
2909 &ndr_table_netlogon,
2910 machine_credentials, tctx->ev, tctx->lp_ctx);
2912 if (!NT_STATUS_IS_OK(status)) {
2913 d_printf("RPC pipe connect as domain member failed: %s\n", nt_errstr(status));
2918 /* set to 1 to enable testing for all possible opcode
2919 (SetUserInfo, SetUserInfo2, QueryUserInfo, QueryUserInfo2)
2922 #define TEST_ALL_LEVELS 1
2923 #define TEST_SET_LEVELS 1
2924 #define TEST_QUERY_LEVELS 1
2926 #ifdef TEST_ALL_LEVELS
2927 for (l=0; l<ARRAY_SIZE(levels); l++) {
2929 for (l=0; l<(ARRAY_SIZE(levels))/2; l++) {
2931 for (z=0; z<ARRAY_SIZE(nonzeros); z++) {
2932 for (f=0; f<ARRAY_SIZE(fields_present); f++) {
2933 #ifdef TEST_SET_LEVELS
2934 for (s=0; s<ARRAY_SIZE(set_levels); s++) {
2936 #ifdef TEST_QUERY_LEVELS
2937 for (q=0; q<ARRAY_SIZE(query_levels); q++) {
2939 NTTIME pwdlastset_old = 0;
2940 NTTIME pwdlastset_new = 0;
2941 bool matched_expected_error = false;
2942 NTSTATUS expected_samlogon_result = NT_STATUS_ACCOUNT_DISABLED;
2944 torture_comment(tctx, "------------------------------\n"
2945 "Testing pwdLastSet attribute for flags: 0x%08x "
2946 "(s: %d (l: %d), q: %d)\n",
2947 acct_flags, s, levels[l], q);
2949 switch (levels[l]) {
2953 if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
2954 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT))) {
2955 expected_samlogon_result = NT_STATUS_WRONG_PASSWORD;
2963 /* set a password and force password change (pwdlastset 0) by
2964 * setting the password expired flag to a non-0 value */
2966 if (!test_SetPassword_level(p, np, tctx, handle,
2970 &matched_expected_error,
2974 machine_credentials,
2977 expected_samlogon_result)) {
2981 if (matched_expected_error == true) {
2982 /* skipping on expected failure */
2986 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
2987 * set without the SAMR_FIELD_EXPIRED_FLAG */
2989 switch (levels[l]) {
2993 if ((pwdlastset_new != 0) &&
2994 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
2995 torture_comment(tctx, "not considering a non-0 "
2996 "pwdLastSet as a an error as the "
2997 "SAMR_FIELD_EXPIRED_FLAG has not "
3002 if (pwdlastset_new != 0) {
3003 torture_warning(tctx, "pwdLastSet test failed: "
3004 "expected pwdLastSet 0 but got %lld\n",
3011 switch (levels[l]) {
3015 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3016 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3017 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3018 (pwdlastset_old >= pwdlastset_new)) {
3019 torture_warning(tctx, "pwdlastset not increasing\n");
3024 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3025 (pwdlastset_old >= pwdlastset_new)) {
3026 torture_warning(tctx, "pwdlastset not increasing\n");
3036 /* set a password, pwdlastset needs to get updated (increased
3037 * value), password_expired value used here is 0 */
3039 if (!test_SetPassword_level(p, np, tctx, handle,
3043 &matched_expected_error,
3047 machine_credentials,
3050 expected_samlogon_result)) {
3054 /* when a password has been changed, pwdlastset must not be 0 afterwards
3055 * and must be larger then the old value */
3057 switch (levels[l]) {
3062 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3063 * password has been changed, old and new pwdlastset
3064 * need to be the same value */
3066 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3067 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3068 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3070 torture_assert_int_equal(tctx, pwdlastset_old,
3071 pwdlastset_new, "pwdlastset must be equal");
3075 if (pwdlastset_old >= pwdlastset_new) {
3076 torture_warning(tctx, "pwdLastSet test failed: "
3077 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
3078 pwdlastset_old, pwdlastset_new);
3081 if (pwdlastset_new == 0) {
3082 torture_warning(tctx, "pwdLastSet test failed: "
3083 "expected non-0 pwdlastset, got: %lld\n",
3089 switch (levels[l]) {
3093 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3094 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3095 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3096 (pwdlastset_old >= pwdlastset_new)) {
3097 torture_warning(tctx, "pwdlastset not increasing\n");
3102 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3103 (pwdlastset_old >= pwdlastset_new)) {
3104 torture_warning(tctx, "pwdlastset not increasing\n");
3110 pwdlastset_old = pwdlastset_new;
3116 /* set a password, pwdlastset needs to get updated (increased
3117 * value), password_expired value used here is 0 */
3119 if (!test_SetPassword_level(p, np, tctx, handle,
3123 &matched_expected_error,
3127 machine_credentials,
3130 expected_samlogon_result)) {
3134 /* when a password has been changed, pwdlastset must not be 0 afterwards
3135 * and must be larger then the old value */
3137 switch (levels[l]) {
3142 /* if no password has been changed, old and new pwdlastset
3143 * need to be the same value */
3145 if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3146 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3148 torture_assert_int_equal(tctx, pwdlastset_old,
3149 pwdlastset_new, "pwdlastset must be equal");
3153 if (pwdlastset_old >= pwdlastset_new) {
3154 torture_warning(tctx, "pwdLastSet test failed: "
3155 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
3156 pwdlastset_old, pwdlastset_new);
3159 if (pwdlastset_new == 0) {
3160 torture_warning(tctx, "pwdLastSet test failed: "
3161 "expected non-0 pwdlastset, got: %lld\n",
3169 /* set a password and force password change (pwdlastset 0) by
3170 * setting the password expired flag to a non-0 value */
3172 if (!test_SetPassword_level(p, np, tctx, handle,
3176 &matched_expected_error,
3180 machine_credentials,
3183 expected_samlogon_result)) {
3187 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3188 * set without the SAMR_FIELD_EXPIRED_FLAG */
3190 switch (levels[l]) {
3194 if ((pwdlastset_new != 0) &&
3195 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
3196 torture_comment(tctx, "not considering a non-0 "
3197 "pwdLastSet as a an error as the "
3198 "SAMR_FIELD_EXPIRED_FLAG has not "
3203 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3204 * password has been changed, old and new pwdlastset
3205 * need to be the same value */
3207 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3208 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3209 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3211 torture_assert_int_equal(tctx, pwdlastset_old,
3212 pwdlastset_new, "pwdlastset must be equal");
3217 if (pwdlastset_old == pwdlastset_new) {
3218 torture_warning(tctx, "pwdLastSet test failed: "
3219 "expected last pwdlastset (%lld) != new pwdlastset (%lld)\n",
3220 pwdlastset_old, pwdlastset_new);
3224 if (pwdlastset_new != 0) {
3225 torture_warning(tctx, "pwdLastSet test failed: "
3226 "expected pwdLastSet 0, got %lld\n",
3233 switch (levels[l]) {
3237 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3238 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3239 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3240 (pwdlastset_old >= pwdlastset_new)) {
3241 torture_warning(tctx, "pwdlastset not increasing\n");
3246 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3247 (pwdlastset_old >= pwdlastset_new)) {
3248 torture_warning(tctx, "pwdlastset not increasing\n");
3254 /* if the level we are testing does not have a fields_present
3255 * field, skip all fields present tests by setting f to to
3257 switch (levels[l]) {
3261 f = ARRAY_SIZE(fields_present);
3265 #ifdef TEST_QUERY_LEVELS
3268 #ifdef TEST_SET_LEVELS
3271 } /* fields present */
3275 #undef TEST_SET_LEVELS
3276 #undef TEST_QUERY_LEVELS
3281 static bool test_DeleteUser_with_privs(struct dcerpc_pipe *p,
3282 struct dcerpc_pipe *lp,
3283 struct torture_context *tctx,
3284 struct policy_handle *domain_handle,
3285 struct policy_handle *lsa_handle,
3286 struct policy_handle *user_handle,
3287 const struct dom_sid *domain_sid,
3289 struct cli_credentials *machine_credentials)
3294 struct policy_handle lsa_acct_handle;
3295 struct dom_sid *user_sid;
3297 user_sid = dom_sid_add_rid(tctx, domain_sid, rid);
3300 struct lsa_EnumAccountRights r;
3301 struct lsa_RightSet rights;
3303 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
3305 r.in.handle = lsa_handle;
3306 r.in.sid = user_sid;
3307 r.out.rights = &rights;
3309 status = dcerpc_lsa_EnumAccountRights(lp, tctx, &r);
3310 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3311 "Expected enum rights for account to fail");
3315 struct lsa_RightSet rights;
3316 struct lsa_StringLarge names[2];
3317 struct lsa_AddAccountRights r;
3319 torture_comment(tctx, "Testing LSA AddAccountRights\n");
3321 init_lsa_StringLarge(&names[0], "SeMachineAccountPrivilege");
3322 init_lsa_StringLarge(&names[1], NULL);
3325 rights.names = names;
3327 r.in.handle = lsa_handle;
3328 r.in.sid = user_sid;
3329 r.in.rights = &rights;
3331 status = dcerpc_lsa_AddAccountRights(lp, tctx, &r);
3332 torture_assert_ntstatus_ok(tctx, status,
3333 "Failed to add privileges");
3337 struct lsa_EnumAccounts r;
3338 uint32_t resume_handle = 0;
3339 struct lsa_SidArray lsa_sid_array;
3341 bool found_sid = false;
3343 torture_comment(tctx, "Testing LSA EnumAccounts\n");
3345 r.in.handle = lsa_handle;
3346 r.in.num_entries = 0x1000;
3347 r.in.resume_handle = &resume_handle;
3348 r.out.sids = &lsa_sid_array;
3349 r.out.resume_handle = &resume_handle;
3351 status = dcerpc_lsa_EnumAccounts(lp, tctx, &r);
3352 torture_assert_ntstatus_ok(tctx, status,
3353 "Failed to enum accounts");
3355 for (i=0; i < lsa_sid_array.num_sids; i++) {
3356 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
3361 torture_assert(tctx, found_sid,
3362 "failed to list privileged account");
3366 struct lsa_EnumAccountRights r;
3367 struct lsa_RightSet user_rights;
3369 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
3371 r.in.handle = lsa_handle;
3372 r.in.sid = user_sid;
3373 r.out.rights = &user_rights;
3375 status = dcerpc_lsa_EnumAccountRights(lp, tctx, &r);
3376 torture_assert_ntstatus_ok(tctx, status,
3377 "Failed to enum rights for account");
3379 if (user_rights.count < 1) {
3380 torture_warning(tctx, "failed to find newly added rights");
3386 struct lsa_OpenAccount r;
3388 torture_comment(tctx, "Testing LSA OpenAccount\n");
3390 r.in.handle = lsa_handle;
3391 r.in.sid = user_sid;
3392 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3393 r.out.acct_handle = &lsa_acct_handle;
3395 status = dcerpc_lsa_OpenAccount(lp, tctx, &r);
3396 torture_assert_ntstatus_ok(tctx, status,
3397 "Failed to open lsa account");
3401 struct lsa_GetSystemAccessAccount r;
3402 uint32_t access_mask;
3404 torture_comment(tctx, "Testing LSA GetSystemAccessAccount\n");
3406 r.in.handle = &lsa_acct_handle;
3407 r.out.access_mask = &access_mask;
3409 status = dcerpc_lsa_GetSystemAccessAccount(lp, tctx, &r);
3410 torture_assert_ntstatus_ok(tctx, status,
3411 "Failed to get lsa system access account");
3417 torture_comment(tctx, "Testing LSA Close\n");
3419 r.in.handle = &lsa_acct_handle;
3420 r.out.handle = &lsa_acct_handle;
3422 status = dcerpc_lsa_Close(lp, tctx, &r);
3423 torture_assert_ntstatus_ok(tctx, status,
3424 "Failed to close lsa");
3428 struct samr_DeleteUser r;
3430 torture_comment(tctx, "Testing SAMR DeleteUser\n");
3432 r.in.user_handle = user_handle;
3433 r.out.user_handle = user_handle;
3435 status = dcerpc_samr_DeleteUser(p, tctx, &r);
3436 torture_assert_ntstatus_ok(tctx, status, "Delete User failed");
3440 struct lsa_EnumAccounts r;
3441 uint32_t resume_handle = 0;
3442 struct lsa_SidArray lsa_sid_array;
3444 bool found_sid = false;
3446 torture_comment(tctx, "Testing LSA EnumAccounts\n");
3448 r.in.handle = lsa_handle;
3449 r.in.num_entries = 0x1000;
3450 r.in.resume_handle = &resume_handle;
3451 r.out.sids = &lsa_sid_array;
3452 r.out.resume_handle = &resume_handle;
3454 status = dcerpc_lsa_EnumAccounts(lp, tctx, &r);
3455 torture_assert_ntstatus_ok(tctx, status,
3456 "Failed to enum accounts");
3458 for (i=0; i < lsa_sid_array.num_sids; i++) {
3459 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
3464 torture_assert(tctx, found_sid,
3465 "failed to list privileged account");
3469 struct lsa_EnumAccountRights r;
3470 struct lsa_RightSet user_rights;
3472 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
3474 r.in.handle = lsa_handle;
3475 r.in.sid = user_sid;
3476 r.out.rights = &user_rights;
3478 status = dcerpc_lsa_EnumAccountRights(lp, tctx, &r);
3479 torture_assert_ntstatus_ok(tctx, status,
3480 "Failed to enum rights for account");
3482 if (user_rights.count < 1) {
3483 torture_warning(tctx, "failed to find newly added rights");
3489 struct lsa_OpenAccount r;
3491 torture_comment(tctx, "Testing LSA OpenAccount\n");
3493 r.in.handle = lsa_handle;
3494 r.in.sid = user_sid;
3495 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3496 r.out.acct_handle = &lsa_acct_handle;
3498 status = dcerpc_lsa_OpenAccount(lp, tctx, &r);
3499 torture_assert_ntstatus_ok(tctx, status,
3500 "Failed to open lsa account");
3504 struct lsa_GetSystemAccessAccount r;
3505 uint32_t access_mask;
3507 torture_comment(tctx, "Testing LSA GetSystemAccessAccount\n");
3509 r.in.handle = &lsa_acct_handle;
3510 r.out.access_mask = &access_mask;
3512 status = dcerpc_lsa_GetSystemAccessAccount(lp, tctx, &r);
3513 torture_assert_ntstatus_ok(tctx, status,
3514 "Failed to get lsa system access account");
3518 struct lsa_DeleteObject r;
3520 torture_comment(tctx, "Testing LSA DeleteObject\n");
3522 r.in.handle = &lsa_acct_handle;
3523 r.out.handle = &lsa_acct_handle;
3525 status = dcerpc_lsa_DeleteObject(lp, tctx, &r);
3526 torture_assert_ntstatus_ok(tctx, status,
3527 "Failed to delete object");
3531 struct lsa_EnumAccounts r;
3532 uint32_t resume_handle = 0;
3533 struct lsa_SidArray lsa_sid_array;
3535 bool found_sid = false;
3537 torture_comment(tctx, "Testing LSA EnumAccounts\n");
3539 r.in.handle = lsa_handle;
3540 r.in.num_entries = 0x1000;
3541 r.in.resume_handle = &resume_handle;
3542 r.out.sids = &lsa_sid_array;
3543 r.out.resume_handle = &resume_handle;
3545 status = dcerpc_lsa_EnumAccounts(lp, tctx, &r);
3546 torture_assert_ntstatus_ok(tctx, status,
3547 "Failed to enum accounts");
3549 for (i=0; i < lsa_sid_array.num_sids; i++) {
3550 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
3555 torture_assert(tctx, !found_sid,
3556 "should not have listed privileged account");
3560 struct lsa_EnumAccountRights r;
3561 struct lsa_RightSet user_rights;
3563 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
3565 r.in.handle = lsa_handle;
3566 r.in.sid = user_sid;
3567 r.out.rights = &user_rights;
3569 status = dcerpc_lsa_EnumAccountRights(lp, tctx, &r);
3570 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3571 "Failed to enum rights for account");
3577 static bool test_user_ops(struct dcerpc_pipe *p,
3578 struct torture_context *tctx,
3579 struct policy_handle *user_handle,
3580 struct policy_handle *domain_handle,
3581 const struct dom_sid *domain_sid,
3582 uint32_t base_acct_flags,
3583 const char *base_acct_name, enum torture_samr_choice which_ops,
3584 struct cli_credentials *machine_credentials)
3586 char *password = NULL;
3587 struct samr_QueryUserInfo q;
3588 union samr_UserInfo *info;
3594 const uint32_t password_fields[] = {
3595 SAMR_FIELD_NT_PASSWORD_PRESENT,
3596 SAMR_FIELD_LM_PASSWORD_PRESENT,
3597 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
3601 status = test_LookupName(p, tctx, domain_handle, base_acct_name, &rid);
3602 if (!NT_STATUS_IS_OK(status)) {
3606 switch (which_ops) {
3607 case TORTURE_SAMR_USER_ATTRIBUTES:
3608 if (!test_QuerySecurity(p, tctx, user_handle)) {
3612 if (!test_QueryUserInfo(p, tctx, user_handle)) {
3616 if (!test_QueryUserInfo2(p, tctx, user_handle)) {
3620 if (!test_SetUserInfo(p, tctx, user_handle, base_acct_flags,
3625 if (!test_GetUserPwInfo(p, tctx, user_handle)) {
3629 if (!test_TestPrivateFunctionsUser(p, tctx, user_handle)) {
3633 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
3637 case TORTURE_SAMR_PASSWORDS:
3638 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
3639 char simple_pass[9];
3640 char *v = generate_random_str(tctx, 1);
3642 ZERO_STRUCT(simple_pass);
3643 memset(simple_pass, *v, sizeof(simple_pass) - 1);
3645 printf("Testing machine account password policy rules\n");
3647 /* Workstation trust accounts don't seem to need to honour password quality policy */
3648 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
3652 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
3656 /* reset again, to allow another 'user' password change */
3657 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
3661 /* Try a 'short' password */
3662 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
3666 /* Try a compleatly random password */
3667 if (!test_ChangePasswordRandomBytes(p, tctx, base_acct_name, user_handle, &password)) {
3672 for (i = 0; password_fields[i]; i++) {
3673 if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
3677 /* check it was set right */
3678 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3683 for (i = 0; password_fields[i]; i++) {
3684 if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
3688 /* check it was set right */
3689 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3694 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
3698 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
3702 if (torture_setting_bool(tctx, "samba4", false)) {
3703 printf("skipping Set Password level 18 and 21 against Samba4\n");
3706 if (!test_SetUserPass_18(p, tctx, user_handle, &password)) {
3710 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3714 for (i = 0; password_fields[i]; i++) {
3716 if (password_fields[i] == SAMR_FIELD_LM_PASSWORD_PRESENT) {
3717 /* we need to skip as that would break
3718 * the ChangePasswordUser3 verify */
3722 if (!test_SetUserPass_21(p, tctx, user_handle, password_fields[i], &password)) {
3726 /* check it was set right */
3727 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3733 q.in.user_handle = user_handle;
3737 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
3738 if (!NT_STATUS_IS_OK(status)) {
3739 printf("QueryUserInfo level %u failed - %s\n",
3740 q.in.level, nt_errstr(status));
3743 uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
3744 if ((info->info5.acct_flags) != expected_flags) {
3745 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
3746 info->info5.acct_flags,
3749 if (!torture_setting_bool(tctx, "samba3", false)) {
3753 if (info->info5.rid != rid) {
3754 printf("QuerUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
3755 info->info5.rid, rid);
3762 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
3764 /* test last password change timestamp behaviour */
3765 if (!test_SetPassword_pwdlastset(p, tctx, base_acct_flags,
3767 user_handle, &password,
3768 machine_credentials)) {
3773 torture_comment(tctx, "pwdLastSet test succeeded\n");
3775 torture_warning(tctx, "pwdLastSet test failed\n");
3780 case TORTURE_SAMR_USER_PRIVILEGES: {
3782 struct dcerpc_pipe *lp;
3783 struct policy_handle *lsa_handle;
3785 status = torture_rpc_connection(tctx, &lp, &ndr_table_lsarpc);
3786 torture_assert_ntstatus_ok(tctx, status, "Failed to open LSA pipe");
3788 if (!test_lsa_OpenPolicy2(lp, tctx, &lsa_handle)) {
3792 if (!test_DeleteUser_with_privs(p, lp, tctx,
3793 domain_handle, lsa_handle, user_handle,
3795 machine_credentials)) {
3799 if (!test_lsa_Close(lp, tctx, lsa_handle)) {
3804 torture_warning(tctx, "privileged user delete test failed\n");
3809 case TORTURE_SAMR_OTHER:
3810 /* We just need the account to exist */
3816 static bool test_alias_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
3817 struct policy_handle *alias_handle,
3818 const struct dom_sid *domain_sid)
3822 if (!torture_setting_bool(tctx, "samba3", false)) {
3823 if (!test_QuerySecurity(p, tctx, alias_handle)) {
3828 if (!test_QueryAliasInfo(p, tctx, alias_handle)) {
3832 if (!test_SetAliasInfo(p, tctx, alias_handle)) {
3836 if (!test_AddMemberToAlias(p, tctx, alias_handle, domain_sid)) {
3840 if (torture_setting_bool(tctx, "samba3", false) ||
3841 torture_setting_bool(tctx, "samba4", false)) {
3842 printf("skipping MultipleMembers Alias tests against Samba\n");
3846 if (!test_AddMultipleMembersToAlias(p, tctx, alias_handle)) {
3854 static bool test_DeleteUser(struct dcerpc_pipe *p, struct torture_context *tctx,
3855 struct policy_handle *user_handle)
3857 struct samr_DeleteUser d;
3859 torture_comment(tctx, "Testing DeleteUser\n");
3861 d.in.user_handle = user_handle;
3862 d.out.user_handle = user_handle;
3864 status = dcerpc_samr_DeleteUser(p, tctx, &d);
3865 torture_assert_ntstatus_ok(tctx, status, "DeleteUser");
3870 bool test_DeleteUser_byname(struct dcerpc_pipe *p,
3871 struct torture_context *tctx,
3872 struct policy_handle *handle, const char *name)
3875 struct samr_DeleteUser d;
3876 struct policy_handle user_handle;
3879 status = test_LookupName(p, tctx, handle, name, &rid);
3880 if (!NT_STATUS_IS_OK(status)) {
3884 status = test_OpenUser_byname(p, tctx, handle, name, &user_handle);
3885 if (!NT_STATUS_IS_OK(status)) {
3889 d.in.user_handle = &user_handle;
3890 d.out.user_handle = &user_handle;
3891 status = dcerpc_samr_DeleteUser(p, tctx, &d);
3892 if (!NT_STATUS_IS_OK(status)) {
3899 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
3904 static bool test_DeleteGroup_byname(struct dcerpc_pipe *p,
3905 struct torture_context *tctx,
3906 struct policy_handle *handle, const char *name)
3909 struct samr_OpenGroup r;
3910 struct samr_DeleteDomainGroup d;
3911 struct policy_handle group_handle;
3914 status = test_LookupName(p, tctx, handle, name, &rid);
3915 if (!NT_STATUS_IS_OK(status)) {
3919 r.in.domain_handle = handle;
3920 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3922 r.out.group_handle = &group_handle;
3923 status = dcerpc_samr_OpenGroup(p, tctx, &r);
3924 if (!NT_STATUS_IS_OK(status)) {
3928 d.in.group_handle = &group_handle;
3929 d.out.group_handle = &group_handle;
3930 status = dcerpc_samr_DeleteDomainGroup(p, tctx, &d);
3931 if (!NT_STATUS_IS_OK(status)) {
3938 printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
3943 static bool test_DeleteAlias_byname(struct dcerpc_pipe *p,
3944 struct torture_context *tctx,
3945 struct policy_handle *domain_handle,
3949 struct samr_OpenAlias r;
3950 struct samr_DeleteDomAlias d;
3951 struct policy_handle alias_handle;
3954 printf("testing DeleteAlias_byname\n");
3956 status = test_LookupName(p, tctx, domain_handle, name, &rid);
3957 if (!NT_STATUS_IS_OK(status)) {
3961 r.in.domain_handle = domain_handle;
3962 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3964 r.out.alias_handle = &alias_handle;
3965 status = dcerpc_samr_OpenAlias(p, tctx, &r);
3966 if (!NT_STATUS_IS_OK(status)) {
3970 d.in.alias_handle = &alias_handle;
3971 d.out.alias_handle = &alias_handle;
3972 status = dcerpc_samr_DeleteDomAlias(p, tctx, &d);
3973 if (!NT_STATUS_IS_OK(status)) {
3980 printf("DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
3984 static bool test_DeleteAlias(struct dcerpc_pipe *p,
3985 struct torture_context *tctx,
3986 struct policy_handle *alias_handle)
3988 struct samr_DeleteDomAlias d;
3991 printf("Testing DeleteAlias\n");
3993 d.in.alias_handle = alias_handle;
3994 d.out.alias_handle = alias_handle;
3996 status = dcerpc_samr_DeleteDomAlias(p, tctx, &d);
3997 if (!NT_STATUS_IS_OK(status)) {
3998 printf("DeleteAlias failed - %s\n", nt_errstr(status));
4005 static bool test_CreateAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
4006 struct policy_handle *domain_handle,
4007 const char *alias_name,
4008 struct policy_handle *alias_handle,
4009 const struct dom_sid *domain_sid,
4013 struct samr_CreateDomAlias r;
4014 struct lsa_String name;
4018 init_lsa_String(&name, alias_name);
4019 r.in.domain_handle = domain_handle;
4020 r.in.alias_name = &name;
4021 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4022 r.out.alias_handle = alias_handle;
4025 printf("Testing CreateAlias (%s)\n", r.in.alias_name->string);
4027 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
4029 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
4030 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
4031 printf("Server correctly refused create of '%s'\n", r.in.alias_name->string);
4034 printf("Server should have refused create of '%s', got %s instead\n", r.in.alias_name->string,
4040 if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
4041 if (!test_DeleteAlias_byname(p, tctx, domain_handle, r.in.alias_name->string)) {
4044 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
4047 if (!NT_STATUS_IS_OK(status)) {
4048 printf("CreateAlias failed - %s\n", nt_errstr(status));
4056 if (!test_alias_ops(p, tctx, alias_handle, domain_sid)) {
4063 static bool test_ChangePassword(struct dcerpc_pipe *p,
4064 struct torture_context *tctx,
4065 const char *acct_name,
4066 struct policy_handle *domain_handle, char **password)
4074 if (!test_ChangePasswordUser(p, tctx, acct_name, domain_handle, password)) {
4078 if (!test_ChangePasswordUser2(p, tctx, acct_name, password, 0, true)) {
4082 if (!test_OemChangePasswordUser2(p, tctx, acct_name, domain_handle, password)) {
4086 /* test what happens when setting the old password again */
4087 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, *password, 0, true)) {
4092 char simple_pass[9];
4093 char *v = generate_random_str(tctx, 1);
4095 ZERO_STRUCT(simple_pass);
4096 memset(simple_pass, *v, sizeof(simple_pass) - 1);
4098 /* test what happens when picking a simple password */
4099 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, simple_pass, 0, true)) {
4104 /* set samr_SetDomainInfo level 1 with min_length 5 */
4106 struct samr_QueryDomainInfo r;
4107 union samr_DomainInfo *info = NULL;
4108 struct samr_SetDomainInfo s;
4109 uint16_t len_old, len;
4110 uint32_t pwd_prop_old;
4111 int64_t min_pwd_age_old;
4116 r.in.domain_handle = domain_handle;
4120 printf("testing samr_QueryDomainInfo level 1\n");
4121 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
4122 if (!NT_STATUS_IS_OK(status)) {
4126 s.in.domain_handle = domain_handle;
4130 /* remember the old min length, so we can reset it */
4131 len_old = s.in.info->info1.min_password_length;
4132 s.in.info->info1.min_password_length = len;
4133 pwd_prop_old = s.in.info->info1.password_properties;
4134 /* turn off password complexity checks for this test */
4135 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
4137 min_pwd_age_old = s.in.info->info1.min_password_age;
4138 s.in.info->info1.min_password_age = 0;
4140 printf("testing samr_SetDomainInfo level 1\n");
4141 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
4142 if (!NT_STATUS_IS_OK(status)) {
4146 printf("calling test_ChangePasswordUser3 with too short password\n");
4148 if (!test_ChangePasswordUser3(p, tctx, acct_name, len - 1, password, NULL, 0, true)) {
4152 s.in.info->info1.min_password_length = len_old;
4153 s.in.info->info1.password_properties = pwd_prop_old;
4154 s.in.info->info1.min_password_age = min_pwd_age_old;
4156 printf("testing samr_SetDomainInfo level 1\n");
4157 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
4158 if (!NT_STATUS_IS_OK(status)) {
4166 struct samr_OpenUser r;
4167 struct samr_QueryUserInfo q;
4168 union samr_UserInfo *info;
4169 struct samr_LookupNames n;
4170 struct policy_handle user_handle;
4171 struct samr_Ids rids, types;
4173 n.in.domain_handle = domain_handle;
4175 n.in.names = talloc_array(tctx, struct lsa_String, 1);
4176 n.in.names[0].string = acct_name;
4178 n.out.types = &types;
4180 status = dcerpc_samr_LookupNames(p, tctx, &n);
4181 if (!NT_STATUS_IS_OK(status)) {
4182 printf("LookupNames failed - %s\n", nt_errstr(status));
4186 r.in.domain_handle = domain_handle;
4187 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4188 r.in.rid = n.out.rids->ids[0];
4189 r.out.user_handle = &user_handle;
4191 status = dcerpc_samr_OpenUser(p, tctx, &r);
4192 if (!NT_STATUS_IS_OK(status)) {
4193 printf("OpenUser(%u) failed - %s\n", n.out.rids->ids[0], nt_errstr(status));
4197 q.in.user_handle = &user_handle;
4201 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
4202 if (!NT_STATUS_IS_OK(status)) {
4203 printf("QueryUserInfo failed - %s\n", nt_errstr(status));
4207 printf("calling test_ChangePasswordUser3 with too early password change\n");
4209 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL,
4210 info->info5.last_password_change, true)) {
4215 /* we change passwords twice - this has the effect of verifying
4216 they were changed correctly for the final call */
4217 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
4221 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
4228 static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
4229 struct policy_handle *domain_handle,
4230 const char *user_name,
4231 struct policy_handle *user_handle_out,
4232 struct dom_sid *domain_sid,
4233 enum torture_samr_choice which_ops,
4234 struct cli_credentials *machine_credentials,
4238 TALLOC_CTX *user_ctx;
4241 struct samr_CreateUser r;
4242 struct samr_QueryUserInfo q;
4243 union samr_UserInfo *info;
4244 struct samr_DeleteUser d;
4247 /* This call creates a 'normal' account - check that it really does */
4248 const uint32_t acct_flags = ACB_NORMAL;
4249 struct lsa_String name;
4252 struct policy_handle user_handle;
4253 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
4254 init_lsa_String(&name, user_name);
4256 r.in.domain_handle = domain_handle;
4257 r.in.account_name = &name;
4258 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4259 r.out.user_handle = &user_handle;
4262 printf("Testing CreateUser(%s)\n", r.in.account_name->string);
4264 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
4266 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
4267 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
4268 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
4271 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
4277 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
4278 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
4279 talloc_free(user_ctx);
4282 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
4285 if (!NT_STATUS_IS_OK(status)) {
4286 talloc_free(user_ctx);
4287 printf("CreateUser failed - %s\n", nt_errstr(status));
4292 if (user_handle_out) {
4293 *user_handle_out = user_handle;
4299 q.in.user_handle = &user_handle;
4303 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
4304 if (!NT_STATUS_IS_OK(status)) {
4305 printf("QueryUserInfo level %u failed - %s\n",
4306 q.in.level, nt_errstr(status));
4309 if ((info->info16.acct_flags & acct_flags) != acct_flags) {
4310 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
4311 info->info16.acct_flags,
4317 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
4318 domain_sid, acct_flags, name.string, which_ops,
4319 machine_credentials)) {
4323 if (user_handle_out) {
4324 *user_handle_out = user_handle;
4326 printf("Testing DeleteUser (createuser test)\n");
4328 d.in.user_handle = &user_handle;
4329 d.out.user_handle = &user_handle;
4331 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
4332 if (!NT_STATUS_IS_OK(status)) {
4333 printf("DeleteUser failed - %s\n", nt_errstr(status));
4340 talloc_free(user_ctx);
4346 static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
4347 struct policy_handle *domain_handle,
4348 struct dom_sid *domain_sid,
4349 enum torture_samr_choice which_ops,
4350 struct cli_credentials *machine_credentials)
4353 struct samr_CreateUser2 r;
4354 struct samr_QueryUserInfo q;
4355 union samr_UserInfo *info;
4356 struct samr_DeleteUser d;
4357 struct policy_handle user_handle;
4359 struct lsa_String name;
4364 uint32_t acct_flags;
4365 const char *account_name;
4367 } account_types[] = {
4368 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
4369 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
4370 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
4371 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
4372 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
4373 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
4374 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
4375 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
4376 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
4377 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_ACCESS_DENIED },
4378 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
4379 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
4380 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
4381 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
4382 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
4385 for (i = 0; account_types[i].account_name; i++) {
4386 TALLOC_CTX *user_ctx;
4387 uint32_t acct_flags = account_types[i].acct_flags;
4388 uint32_t access_granted;
4389 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
4390 init_lsa_String(&name, account_types[i].account_name);
4392 r.in.domain_handle = domain_handle;
4393 r.in.account_name = &name;
4394 r.in.acct_flags = acct_flags;
4395 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4396 r.out.user_handle = &user_handle;
4397 r.out.access_granted = &access_granted;
4400 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
4402 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
4404 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
4405 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
4406 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
4409 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
4416 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
4417 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
4418 talloc_free(user_ctx);
4422 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
4425 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
4426 printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
4427 nt_errstr(status), nt_errstr(account_types[i].nt_status));
4431 if (NT_STATUS_IS_OK(status)) {
4432 q.in.user_handle = &user_handle;
4436 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
4437 if (!NT_STATUS_IS_OK(status)) {
4438 printf("QueryUserInfo level %u failed - %s\n",
4439 q.in.level, nt_errstr(status));
4442 uint32_t expected_flags = (acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
4443 if (acct_flags == ACB_NORMAL) {
4444 expected_flags |= ACB_PW_EXPIRED;
4446 if ((info->info5.acct_flags) != expected_flags) {
4447 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
4448 info->info5.acct_flags,
4452 switch (acct_flags) {
4454 if (info->info5.primary_gid != DOMAIN_RID_DCS) {
4455 printf("QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n",
4456 DOMAIN_RID_DCS, info->info5.primary_gid);
4461 if (info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
4462 printf("QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
4463 DOMAIN_RID_DOMAIN_MEMBERS, info->info5.primary_gid);
4468 if (info->info5.primary_gid != DOMAIN_RID_USERS) {
4469 printf("QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n",
4470 DOMAIN_RID_USERS, info->info5.primary_gid);
4477 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
4478 domain_sid, acct_flags, name.string, which_ops,
4479 machine_credentials)) {
4483 if (!policy_handle_empty(&user_handle)) {
4484 printf("Testing DeleteUser (createuser2 test)\n");
4486 d.in.user_handle = &user_handle;
4487 d.out.user_handle = &user_handle;
4489 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
4490 if (!NT_STATUS_IS_OK(status)) {
4491 printf("DeleteUser failed - %s\n", nt_errstr(status));
4496 talloc_free(user_ctx);
4502 static bool test_QueryAliasInfo(struct dcerpc_pipe *p,
4503 struct torture_context *tctx,
4504 struct policy_handle *handle)
4507 struct samr_QueryAliasInfo r;
4508 union samr_AliasInfo *info;
4509 uint16_t levels[] = {1, 2, 3};
4513 for (i=0;i<ARRAY_SIZE(levels);i++) {
4514 printf("Testing QueryAliasInfo level %u\n", levels[i]);
4516 r.in.alias_handle = handle;
4517 r.in.level = levels[i];
4520 status = dcerpc_samr_QueryAliasInfo(p, tctx, &r);
4521 if (!NT_STATUS_IS_OK(status)) {
4522 printf("QueryAliasInfo level %u failed - %s\n",
4523 levels[i], nt_errstr(status));
4531 static bool test_QueryGroupInfo(struct dcerpc_pipe *p,
4532 struct torture_context *tctx,
4533 struct policy_handle *handle)
4536 struct samr_QueryGroupInfo r;
4537 union samr_GroupInfo *info;
4538 uint16_t levels[] = {1, 2, 3, 4, 5};
4542 for (i=0;i<ARRAY_SIZE(levels);i++) {
4543 printf("Testing QueryGroupInfo level %u\n", levels[i]);
4545 r.in.group_handle = handle;
4546 r.in.level = levels[i];
4549 status = dcerpc_samr_QueryGroupInfo(p, tctx, &r);
4550 if (!NT_STATUS_IS_OK(status)) {
4551 printf("QueryGroupInfo level %u failed - %s\n",
4552 levels[i], nt_errstr(status));
4560 static bool test_QueryGroupMember(struct dcerpc_pipe *p,
4561 struct torture_context *tctx,
4562 struct policy_handle *handle)
4565 struct samr_QueryGroupMember r;
4566 struct samr_RidTypeArray *rids = NULL;
4569 printf("Testing QueryGroupMember\n");
4571 r.in.group_handle = handle;
4574 status = dcerpc_samr_QueryGroupMember(p, tctx, &r);
4575 if (!NT_STATUS_IS_OK(status)) {
4576 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
4584 static bool test_SetGroupInfo(struct dcerpc_pipe *p,
4585 struct torture_context *tctx,
4586 struct policy_handle *handle)
4589 struct samr_QueryGroupInfo r;
4590 union samr_GroupInfo *info;
4591 struct samr_SetGroupInfo s;
4592 uint16_t levels[] = {1, 2, 3, 4};
4593 uint16_t set_ok[] = {0, 1, 1, 1};
4597 for (i=0;i<ARRAY_SIZE(levels);i++) {
4598 printf("Testing QueryGroupInfo level %u\n", levels[i]);
4600 r.in.group_handle = handle;
4601 r.in.level = levels[i];
4604 status = dcerpc_samr_QueryGroupInfo(p, tctx, &r);
4605 if (!NT_STATUS_IS_OK(status)) {
4606 printf("QueryGroupInfo level %u failed - %s\n",
4607 levels[i], nt_errstr(status));
4611 printf("Testing SetGroupInfo level %u\n", levels[i]);
4613 s.in.group_handle = handle;
4614 s.in.level = levels[i];
4615 s.in.info = *r.out.info;
4618 /* disabled this, as it changes the name only from the point of view of samr,
4619 but leaves the name from the point of view of w2k3 internals (and ldap). This means
4620 the name is still reserved, so creating the old name fails, but deleting by the old name
4622 if (s.in.level == 2) {
4623 init_lsa_String(&s.in.info->string, "NewName");
4627 if (s.in.level == 4) {
4628 init_lsa_String(&s.in.info->description, "test description");
4631 status = dcerpc_samr_SetGroupInfo(p, tctx, &s);
4633 if (!NT_STATUS_IS_OK(status)) {
4634 printf("SetGroupInfo level %u failed - %s\n",
4635 r.in.level, nt_errstr(status));
4640 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
4641 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
4642 r.in.level, nt_errstr(status));
4652 static bool test_QueryUserInfo(struct dcerpc_pipe *p,
4653 struct torture_context *tctx,
4654 struct policy_handle *handle)
4657 struct samr_QueryUserInfo r;
4658 union samr_UserInfo *info;
4659 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
4660 11, 12, 13, 14, 16, 17, 20, 21};
4664 for (i=0;i<ARRAY_SIZE(levels);i++) {
4665 printf("Testing QueryUserInfo level %u\n", levels[i]);
4667 r.in.user_handle = handle;
4668 r.in.level = levels[i];
4671 status = dcerpc_samr_QueryUserInfo(p, tctx, &r);
4672 if (!NT_STATUS_IS_OK(status)) {
4673 printf("QueryUserInfo level %u failed - %s\n",
4674 levels[i], nt_errstr(status));
4682 static bool test_QueryUserInfo2(struct dcerpc_pipe *p,
4683 struct torture_context *tctx,
4684 struct policy_handle *handle)
4687 struct samr_QueryUserInfo2 r;
4688 union samr_UserInfo *info;
4689 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
4690 11, 12, 13, 14, 16, 17, 20, 21};
4694 for (i=0;i<ARRAY_SIZE(levels);i++) {
4695 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
4697 r.in.user_handle = handle;
4698 r.in.level = levels[i];
4701 status = dcerpc_samr_QueryUserInfo2(p, tctx, &r);
4702 if (!NT_STATUS_IS_OK(status)) {
4703 printf("QueryUserInfo2 level %u failed - %s\n",
4704 levels[i], nt_errstr(status));
4712 static bool test_OpenUser(struct dcerpc_pipe *p,
4713 struct torture_context *tctx,
4714 struct policy_handle *handle, uint32_t rid)
4717 struct samr_OpenUser r;
4718 struct policy_handle user_handle;
4721 printf("Testing OpenUser(%u)\n", rid);
4723 r.in.domain_handle = handle;
4724 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4726 r.out.user_handle = &user_handle;
4728 status = dcerpc_samr_OpenUser(p, tctx, &r);
4729 if (!NT_STATUS_IS_OK(status)) {
4730 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
4734 if (!test_QuerySecurity(p, tctx, &user_handle)) {
4738 if (!test_QueryUserInfo(p, tctx, &user_handle)) {
4742 if (!test_QueryUserInfo2(p, tctx, &user_handle)) {
4746 if (!test_GetUserPwInfo(p, tctx, &user_handle)) {
4750 if (!test_GetGroupsForUser(p,tctx, &user_handle)) {
4754 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
4761 static bool test_OpenGroup(struct dcerpc_pipe *p,
4762 struct torture_context *tctx,
4763 struct policy_handle *handle, uint32_t rid)
4766 struct samr_OpenGroup r;
4767 struct policy_handle group_handle;
4770 printf("Testing OpenGroup(%u)\n", rid);
4772 r.in.domain_handle = handle;
4773 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4775 r.out.group_handle = &group_handle;
4777 status = dcerpc_samr_OpenGroup(p, tctx, &r);
4778 if (!NT_STATUS_IS_OK(status)) {
4779 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
4783 if (!torture_setting_bool(tctx, "samba3", false)) {
4784 if (!test_QuerySecurity(p, tctx, &group_handle)) {
4789 if (!test_QueryGroupInfo(p, tctx, &group_handle)) {
4793 if (!test_QueryGroupMember(p, tctx, &group_handle)) {
4797 if (!test_samr_handle_Close(p, tctx, &group_handle)) {
4804 static bool test_OpenAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
4805 struct policy_handle *handle, uint32_t rid)
4808 struct samr_OpenAlias r;
4809 struct policy_handle alias_handle;
4812 torture_comment(tctx, "Testing OpenAlias(%u)\n", rid);
4814 r.in.domain_handle = handle;
4815 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4817 r.out.alias_handle = &alias_handle;
4819 status = dcerpc_samr_OpenAlias(p, tctx, &r);
4820 if (!NT_STATUS_IS_OK(status)) {
4821 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
4825 if (!torture_setting_bool(tctx, "samba3", false)) {
4826 if (!test_QuerySecurity(p, tctx, &alias_handle)) {
4831 if (!test_QueryAliasInfo(p, tctx, &alias_handle)) {
4835 if (!test_GetMembersInAlias(p, tctx, &alias_handle)) {
4839 if (!test_samr_handle_Close(p, tctx, &alias_handle)) {
4846 static bool check_mask(struct dcerpc_pipe *p, struct torture_context *tctx,
4847 struct policy_handle *handle, uint32_t rid,
4848 uint32_t acct_flag_mask)
4851 struct samr_OpenUser r;
4852 struct samr_QueryUserInfo q;
4853 union samr_UserInfo *info;
4854 struct policy_handle user_handle;
4857 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
4859 r.in.domain_handle = handle;
4860 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4862 r.out.user_handle = &user_handle;
4864 status = dcerpc_samr_OpenUser(p, tctx, &r);
4865 if (!NT_STATUS_IS_OK(status)) {
4866 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
4870 q.in.user_handle = &user_handle;
4874 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
4875 if (!NT_STATUS_IS_OK(status)) {
4876 printf("QueryUserInfo level 16 failed - %s\n",
4880 if ((acct_flag_mask & info->info16.acct_flags) == 0) {
4881 printf("Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
4882 acct_flag_mask, info->info16.acct_flags, rid);
4887 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
4894 static bool test_EnumDomainUsers_all(struct dcerpc_pipe *p,
4895 struct torture_context *tctx,
4896 struct policy_handle *handle)
4898 NTSTATUS status = STATUS_MORE_ENTRIES;
4899 struct samr_EnumDomainUsers r;
4900 uint32_t mask, resume_handle=0;
4903 struct samr_LookupNames n;
4904 struct samr_LookupRids lr ;
4905 struct lsa_Strings names;
4906 struct samr_Ids rids, types;
4907 struct samr_SamArray *sam = NULL;
4908 uint32_t num_entries = 0;
4910 uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
4911 ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
4912 ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
4915 printf("Testing EnumDomainUsers\n");
4917 for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
4918 r.in.domain_handle = handle;
4919 r.in.resume_handle = &resume_handle;
4920 r.in.acct_flags = mask = masks[mask_idx];
4921 r.in.max_size = (uint32_t)-1;
4922 r.out.resume_handle = &resume_handle;
4923 r.out.num_entries = &num_entries;
4926 status = dcerpc_samr_EnumDomainUsers(p, tctx, &r);
4927 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
4928 !NT_STATUS_IS_OK(status)) {
4929 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
4933 torture_assert(tctx, sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
4935 if (sam->count == 0) {
4939 for (i=0;i<sam->count;i++) {
4941 if (!check_mask(p, tctx, handle, sam->entries[i].idx, mask)) {
4944 } else if (!test_OpenUser(p, tctx, handle, sam->entries[i].idx)) {
4950 printf("Testing LookupNames\n");
4951 n.in.domain_handle = handle;
4952 n.in.num_names = sam->count;
4953 n.in.names = talloc_array(tctx, struct lsa_String, sam->count);
4955 n.out.types = &types;
4956 for (i=0;i<sam->count;i++) {
4957 n.in.names[i].string = sam->entries[i].name.string;
4959 status = dcerpc_samr_LookupNames(p, tctx, &n);
4960 if (!NT_STATUS_IS_OK(status)) {
4961 printf("LookupNames failed - %s\n", nt_errstr(status));
4966 printf("Testing LookupRids\n");
4967 lr.in.domain_handle = handle;
4968 lr.in.num_rids = sam->count;
4969 lr.in.rids = talloc_array(tctx, uint32_t, sam->count);
4970 lr.out.names = &names;
4971 lr.out.types = &types;
4972 for (i=0;i<sam->count;i++) {
4973 lr.in.rids[i] = sam->entries[i].idx;
4975 status = dcerpc_samr_LookupRids(p, tctx, &lr);
4976 torture_assert_ntstatus_ok(tctx, status, "LookupRids");
4982 try blasting the server with a bunch of sync requests
4984 static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, struct torture_context *tctx,
4985 struct policy_handle *handle)
4988 struct samr_EnumDomainUsers r;
4989 uint32_t resume_handle=0;
4991 #define ASYNC_COUNT 100
4992 struct rpc_request *req[ASYNC_COUNT];
4994 if (!torture_setting_bool(tctx, "dangerous", false)) {
4995 torture_skip(tctx, "samr async test disabled - enable dangerous tests to use\n");
4998 torture_comment(tctx, "Testing EnumDomainUsers_async\n");
5000 r.in.domain_handle = handle;
5001 r.in.resume_handle = &resume_handle;
5002 r.in.acct_flags = 0;
5003 r.in.max_size = (uint32_t)-1;
5004 r.out.resume_handle = &resume_handle;
5006 for (i=0;i<ASYNC_COUNT;i++) {
5007 req[i] = dcerpc_samr_EnumDomainUsers_send(p, tctx, &r);
5010 for (i=0;i<ASYNC_COUNT;i++) {
5011 status = dcerpc_ndr_request_recv(req[i]);
5012 if (!NT_STATUS_IS_OK(status)) {
5013 printf("EnumDomainUsers[%d] failed - %s\n",
5014 i, nt_errstr(status));
5019 torture_comment(tctx, "%d async requests OK\n", i);
5024 static bool test_EnumDomainGroups_all(struct dcerpc_pipe *p,
5025 struct torture_context *tctx,
5026 struct policy_handle *handle)
5029 struct samr_EnumDomainGroups r;
5030 uint32_t resume_handle=0;
5031 struct samr_SamArray *sam = NULL;
5032 uint32_t num_entries = 0;
5036 printf("Testing EnumDomainGroups\n");
5038 r.in.domain_handle = handle;
5039 r.in.resume_handle = &resume_handle;
5040 r.in.max_size = (uint32_t)-1;
5041 r.out.resume_handle = &resume_handle;
5042 r.out.num_entries = &num_entries;
5045 status = dcerpc_samr_EnumDomainGroups(p, tctx, &r);
5046 if (!NT_STATUS_IS_OK(status)) {
5047 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
5055 for (i=0;i<sam->count;i++) {
5056 if (!test_OpenGroup(p, tctx, handle, sam->entries[i].idx)) {
5064 static bool test_EnumDomainAliases_all(struct dcerpc_pipe *p,
5065 struct torture_context *tctx,
5066 struct policy_handle *handle)
5069 struct samr_EnumDomainAliases r;
5070 uint32_t resume_handle=0;
5071 struct samr_SamArray *sam = NULL;
5072 uint32_t num_entries = 0;
5076 printf("Testing EnumDomainAliases\n");
5078 r.in.domain_handle = handle;
5079 r.in.resume_handle = &resume_handle;
5080 r.in.max_size = (uint32_t)-1;
5082 r.out.num_entries = &num_entries;
5083 r.out.resume_handle = &resume_handle;
5085 status = dcerpc_samr_EnumDomainAliases(p, tctx, &r);
5086 if (!NT_STATUS_IS_OK(status)) {
5087 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
5095 for (i=0;i<sam->count;i++) {
5096 if (!test_OpenAlias(p, tctx, handle, sam->entries[i].idx)) {
5104 static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p,
5105 struct torture_context *tctx,
5106 struct policy_handle *handle)
5109 struct samr_GetDisplayEnumerationIndex r;
5111 uint16_t levels[] = {1, 2, 3, 4, 5};
5112 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
5113 struct lsa_String name;
5117 for (i=0;i<ARRAY_SIZE(levels);i++) {
5118 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
5120 init_lsa_String(&name, TEST_ACCOUNT_NAME);
5122 r.in.domain_handle = handle;
5123 r.in.level = levels[i];
5127 status = dcerpc_samr_GetDisplayEnumerationIndex(p, tctx, &r);
5130 !NT_STATUS_IS_OK(status) &&
5131 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
5132 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
5133 levels[i], nt_errstr(status));
5137 init_lsa_String(&name, "zzzzzzzz");
5139 status = dcerpc_samr_GetDisplayEnumerationIndex(p, tctx, &r);
5141 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
5142 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
5143 levels[i], nt_errstr(status));
5151 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p,
5152 struct torture_context *tctx,
5153 struct policy_handle *handle)
5156 struct samr_GetDisplayEnumerationIndex2 r;
5158 uint16_t levels[] = {1, 2, 3, 4, 5};
5159 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
5160 struct lsa_String name;
5164 for (i=0;i<ARRAY_SIZE(levels);i++) {
5165 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
5167 init_lsa_String(&name, TEST_ACCOUNT_NAME);
5169 r.in.domain_handle = handle;
5170 r.in.level = levels[i];
5174 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, tctx, &r);
5176 !NT_STATUS_IS_OK(status) &&
5177 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
5178 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
5179 levels[i], nt_errstr(status));
5183 init_lsa_String(&name, "zzzzzzzz");
5185 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, tctx, &r);
5186 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
5187 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
5188 levels[i], nt_errstr(status));
5196 #define STRING_EQUAL_QUERY(s1, s2, user) \
5197 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
5198 /* odd, but valid */ \
5199 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
5200 printf("%s mismatch for %s: %s != %s (%s)\n", \
5201 #s1, user.string, s1.string, s2.string, __location__); \
5204 #define INT_EQUAL_QUERY(s1, s2, user) \
5206 printf("%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
5207 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
5211 static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p,
5212 struct torture_context *tctx,
5213 struct samr_QueryDisplayInfo *querydisplayinfo,
5214 bool *seen_testuser)
5216 struct samr_OpenUser r;
5217 struct samr_QueryUserInfo q;
5218 union samr_UserInfo *info;
5219 struct policy_handle user_handle;
5222 r.in.domain_handle = querydisplayinfo->in.domain_handle;
5223 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5224 for (i = 0; ; i++) {
5225 switch (querydisplayinfo->in.level) {
5227 if (i >= querydisplayinfo->out.info->info1.count) {
5230 r.in.rid = querydisplayinfo->out.info->info1.entries[i].rid;
5233 if (i >= querydisplayinfo->out.info->info2.count) {
5236 r.in.rid = querydisplayinfo->out.info->info2.entries[i].rid;
5242 /* Not interested in validating just the account name */
5246 r.out.user_handle = &user_handle;
5248 switch (querydisplayinfo->in.level) {
5251 status = dcerpc_samr_OpenUser(p, tctx, &r);
5252 if (!NT_STATUS_IS_OK(status)) {
5253 printf("OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(status));
5258 q.in.user_handle = &user_handle;
5261 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
5262 if (!NT_STATUS_IS_OK(status)) {
5263 printf("QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(status));
5267 switch (querydisplayinfo->in.level) {
5269 if (seen_testuser && strcmp(info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
5270 *seen_testuser = true;
5272 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].full_name,
5273 info->info21.full_name, info->info21.account_name);
5274 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].account_name,
5275 info->info21.account_name, info->info21.account_name);
5276 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].description,
5277 info->info21.description, info->info21.account_name);
5278 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].rid,
5279 info->info21.rid, info->info21.account_name);
5280 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].acct_flags,
5281 info->info21.acct_flags, info->info21.account_name);
5285 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].account_name,
5286 info->info21.account_name, info->info21.account_name);
5287 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].description,
5288 info->info21.description, info->info21.account_name);
5289 INT_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].rid,
5290 info->info21.rid, info->info21.account_name);
5291 INT_EQUAL_QUERY((querydisplayinfo->out.info->info2.entries[i].acct_flags & ~ACB_NORMAL),
5292 info->info21.acct_flags, info->info21.account_name);
5294 if (!(querydisplayinfo->out.info->info2.entries[i].acct_flags & ACB_NORMAL)) {
5295 printf("Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
5296 info->info21.account_name.string);
5299 if (!(info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
5300 printf("Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
5301 info->info21.account_name.string,
5302 querydisplayinfo->out.info->info2.entries[i].acct_flags,
5303 info->info21.acct_flags);
5310 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
5317 static bool test_QueryDisplayInfo(struct dcerpc_pipe *p,
5318 struct torture_context *tctx,
5319 struct policy_handle *handle)
5322 struct samr_QueryDisplayInfo r;
5323 struct samr_QueryDomainInfo dom_info;
5324 union samr_DomainInfo *info = NULL;
5326 uint16_t levels[] = {1, 2, 3, 4, 5};
5328 bool seen_testuser = false;
5329 uint32_t total_size;
5330 uint32_t returned_size;
5331 union samr_DispInfo disp_info;
5334 for (i=0;i<ARRAY_SIZE(levels);i++) {
5335 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
5338 status = STATUS_MORE_ENTRIES;
5339 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
5340 r.in.domain_handle = handle;
5341 r.in.level = levels[i];
5342 r.in.max_entries = 2;
5343 r.in.buf_size = (uint32_t)-1;
5344 r.out.total_size = &total_size;
5345 r.out.returned_size = &returned_size;
5346 r.out.info = &disp_info;
5348 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &r);
5349 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(status)) {
5350 printf("QueryDisplayInfo level %u failed - %s\n",
5351 levels[i], nt_errstr(status));
5354 switch (r.in.level) {
5356 if (!test_each_DisplayInfo_user(p, tctx, &r, &seen_testuser)) {
5359 r.in.start_idx += r.out.info->info1.count;
5362 if (!test_each_DisplayInfo_user(p, tctx, &r, NULL)) {
5365 r.in.start_idx += r.out.info->info2.count;
5368 r.in.start_idx += r.out.info->info3.count;
5371 r.in.start_idx += r.out.info->info4.count;
5374 r.in.start_idx += r.out.info->info5.count;
5378 dom_info.in.domain_handle = handle;
5379 dom_info.in.level = 2;
5380 dom_info.out.info = &info;
5382 /* Check number of users returned is correct */
5383 status = dcerpc_samr_QueryDomainInfo(p, tctx, &dom_info);
5384 if (!NT_STATUS_IS_OK(status)) {
5385 printf("QueryDomainInfo level %u failed - %s\n",
5386 r.in.level, nt_errstr(status));
5390 switch (r.in.level) {
5393 if (info->general.num_users < r.in.start_idx) {
5394 printf("QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
5395 r.in.start_idx, info->general.num_groups,
5396 info->general.domain_name.string);
5399 if (!seen_testuser) {
5400 struct policy_handle user_handle;
5401 if (NT_STATUS_IS_OK(test_OpenUser_byname(p, tctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
5402 printf("Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
5403 info->general.domain_name.string);
5405 test_samr_handle_Close(p, tctx, &user_handle);
5411 if (info->general.num_groups != r.in.start_idx) {
5412 printf("QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
5413 r.in.start_idx, info->general.num_groups,
5414 info->general.domain_name.string);
5426 static bool test_QueryDisplayInfo2(struct dcerpc_pipe *p,
5427 struct torture_context *tctx,
5428 struct policy_handle *handle)
5431 struct samr_QueryDisplayInfo2 r;
5433 uint16_t levels[] = {1, 2, 3, 4, 5};
5435 uint32_t total_size;
5436 uint32_t returned_size;
5437 union samr_DispInfo info;
5439 for (i=0;i<ARRAY_SIZE(levels);i++) {
5440 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
5442 r.in.domain_handle = handle;
5443 r.in.level = levels[i];
5445 r.in.max_entries = 1000;
5446 r.in.buf_size = (uint32_t)-1;
5447 r.out.total_size = &total_size;
5448 r.out.returned_size = &returned_size;
5451 status = dcerpc_samr_QueryDisplayInfo2(p, tctx, &r);
5452 if (!NT_STATUS_IS_OK(status)) {
5453 printf("QueryDisplayInfo2 level %u failed - %s\n",
5454 levels[i], nt_errstr(status));
5462 static bool test_QueryDisplayInfo3(struct dcerpc_pipe *p, struct torture_context *tctx,
5463 struct policy_handle *handle)
5466 struct samr_QueryDisplayInfo3 r;
5468 uint16_t levels[] = {1, 2, 3, 4, 5};
5470 uint32_t total_size;
5471 uint32_t returned_size;
5472 union samr_DispInfo info;
5474 for (i=0;i<ARRAY_SIZE(levels);i++) {
5475 torture_comment(tctx, "Testing QueryDisplayInfo3 level %u\n", levels[i]);
5477 r.in.domain_handle = handle;
5478 r.in.level = levels[i];
5480 r.in.max_entries = 1000;
5481 r.in.buf_size = (uint32_t)-1;
5482 r.out.total_size = &total_size;
5483 r.out.returned_size = &returned_size;
5486 status = dcerpc_samr_QueryDisplayInfo3(p, tctx, &r);
5487 if (!NT_STATUS_IS_OK(status)) {
5488 printf("QueryDisplayInfo3 level %u failed - %s\n",
5489 levels[i], nt_errstr(status));
5498 static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p,
5499 struct torture_context *tctx,
5500 struct policy_handle *handle)
5503 struct samr_QueryDisplayInfo r;
5505 uint32_t total_size;
5506 uint32_t returned_size;
5507 union samr_DispInfo info;
5509 printf("Testing QueryDisplayInfo continuation\n");
5511 r.in.domain_handle = handle;
5514 r.in.max_entries = 1;
5515 r.in.buf_size = (uint32_t)-1;
5516 r.out.total_size = &total_size;
5517 r.out.returned_size = &returned_size;
5521 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &r);
5522 if (NT_STATUS_IS_OK(status) && *r.out.returned_size != 0) {
5523 if (r.out.info->info1.entries[0].idx != r.in.start_idx + 1) {
5524 printf("expected idx %d but got %d\n",
5526 r.out.info->info1.entries[0].idx);
5530 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
5531 !NT_STATUS_IS_OK(status)) {
5532 printf("QueryDisplayInfo level %u failed - %s\n",
5533 r.in.level, nt_errstr(status));
5538 } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
5539 NT_STATUS_IS_OK(status)) &&
5540 *r.out.returned_size != 0);
5545 static bool test_QueryDomainInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
5546 struct policy_handle *handle)
5549 struct samr_QueryDomainInfo r;
5550 union samr_DomainInfo *info = NULL;
5551 struct samr_SetDomainInfo s;
5552 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
5553 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
5556 const char *domain_comment = talloc_asprintf(tctx,
5557 "Tortured by Samba4 RPC-SAMR: %s",
5558 timestring(tctx, time(NULL)));
5560 s.in.domain_handle = handle;
5562 s.in.info = talloc(tctx, union samr_DomainInfo);
5564 s.in.info->oem.oem_information.string = domain_comment;
5565 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
5566 if (!NT_STATUS_IS_OK(status)) {
5567 printf("SetDomainInfo level %u (set comment) failed - %s\n",
5568 s.in.level, nt_errstr(status));
5572 for (i=0;i<ARRAY_SIZE(levels);i++) {
5573 torture_comment(tctx, "Testing QueryDomainInfo level %u\n", levels[i]);
5575 r.in.domain_handle = handle;
5576 r.in.level = levels[i];
5579 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
5580 if (!NT_STATUS_IS_OK(status)) {
5581 printf("QueryDomainInfo level %u failed - %s\n",
5582 r.in.level, nt_errstr(status));
5587 switch (levels[i]) {
5589 if (strcmp(info->general.oem_information.string, domain_comment) != 0) {
5590 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
5591 levels[i], info->general.oem_information.string, domain_comment);
5592 if (!torture_setting_bool(tctx, "samba3", false)) {
5596 if (!info->general.primary.string) {
5597 printf("QueryDomainInfo level %u returned no PDC name\n",
5600 } else if (info->general.role == SAMR_ROLE_DOMAIN_PDC) {
5601 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), info->general.primary.string) != 0) {
5602 printf("QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
5603 levels[i], info->general.primary.string, dcerpc_server_name(p));
5608 if (strcmp(info->oem.oem_information.string, domain_comment) != 0) {
5609 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
5610 levels[i], info->oem.oem_information.string, domain_comment);
5611 if (!torture_setting_bool(tctx, "samba3", false)) {
5617 if (!info->info6.primary.string) {
5618 printf("QueryDomainInfo level %u returned no PDC name\n",
5624 if (strcmp(info->general2.general.oem_information.string, domain_comment) != 0) {
5625 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
5626 levels[i], info->general2.general.oem_information.string, domain_comment);
5627 if (!torture_setting_bool(tctx, "samba3", false)) {
5634 torture_comment(tctx, "Testing SetDomainInfo level %u\n", levels[i]);
5636 s.in.domain_handle = handle;
5637 s.in.level = levels[i];
5640 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
5642 if (!NT_STATUS_IS_OK(status)) {
5643 printf("SetDomainInfo level %u failed - %s\n",
5644 r.in.level, nt_errstr(status));
5649 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
5650 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
5651 r.in.level, nt_errstr(status));
5657 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
5658 if (!NT_STATUS_IS_OK(status)) {
5659 printf("QueryDomainInfo level %u failed - %s\n",
5660 r.in.level, nt_errstr(status));
5670 static bool test_QueryDomainInfo2(struct dcerpc_pipe *p, struct torture_context *tctx,
5671 struct policy_handle *handle)
5674 struct samr_QueryDomainInfo2 r;
5675 union samr_DomainInfo *info = NULL;
5676 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
5680 for (i=0;i<ARRAY_SIZE(levels);i++) {
5681 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
5683 r.in.domain_handle = handle;
5684 r.in.level = levels[i];
5687 status = dcerpc_samr_QueryDomainInfo2(p, tctx, &r);
5688 if (!NT_STATUS_IS_OK(status)) {
5689 printf("QueryDomainInfo2 level %u failed - %s\n",
5690 r.in.level, nt_errstr(status));
5699 /* Test whether querydispinfo level 5 and enumdomgroups return the same
5700 set of group names. */
5701 static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx,
5702 struct policy_handle *handle)
5704 struct samr_EnumDomainGroups q1;
5705 struct samr_QueryDisplayInfo q2;
5707 uint32_t resume_handle=0;
5708 struct samr_SamArray *sam = NULL;
5709 uint32_t num_entries = 0;
5712 uint32_t total_size;
5713 uint32_t returned_size;
5714 union samr_DispInfo info;
5717 const char **names = NULL;
5719 torture_comment(tctx, "Testing coherency of querydispinfo vs enumdomgroups\n");
5721 q1.in.domain_handle = handle;
5722 q1.in.resume_handle = &resume_handle;
5724 q1.out.resume_handle = &resume_handle;
5725 q1.out.num_entries = &num_entries;
5728 status = STATUS_MORE_ENTRIES;
5729 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
5730 status = dcerpc_samr_EnumDomainGroups(p, tctx, &q1);
5732 if (!NT_STATUS_IS_OK(status) &&
5733 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
5736 for (i=0; i<*q1.out.num_entries; i++) {
5737 add_string_to_array(tctx,
5738 sam->entries[i].name.string,
5739 &names, &num_names);
5743 torture_assert_ntstatus_ok(tctx, status, "EnumDomainGroups");
5745 torture_assert(tctx, sam, "EnumDomainGroups failed to return sam");
5747 q2.in.domain_handle = handle;
5749 q2.in.start_idx = 0;
5750 q2.in.max_entries = 5;
5751 q2.in.buf_size = (uint32_t)-1;
5752 q2.out.total_size = &total_size;
5753 q2.out.returned_size = &returned_size;
5754 q2.out.info = &info;
5756 status = STATUS_MORE_ENTRIES;
5757 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
5758 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &q2);
5760 if (!NT_STATUS_IS_OK(status) &&
5761 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
5764 for (i=0; i<q2.out.info->info5.count; i++) {
5766 const char *name = q2.out.info->info5.entries[i].account_name.string;
5768 for (j=0; j<num_names; j++) {
5769 if (names[j] == NULL)
5771 if (strequal(names[j], name)) {
5779 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
5784 q2.in.start_idx += q2.out.info->info5.count;
5787 if (!NT_STATUS_IS_OK(status)) {
5788 printf("QueryDisplayInfo level 5 failed - %s\n",
5793 for (i=0; i<num_names; i++) {
5794 if (names[i] != NULL) {
5795 printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
5804 static bool test_DeleteDomainGroup(struct dcerpc_pipe *p, struct torture_context *tctx,
5805 struct policy_handle *group_handle)
5807 struct samr_DeleteDomainGroup d;
5810 torture_comment(tctx, "Testing DeleteDomainGroup\n");
5812 d.in.group_handle = group_handle;
5813 d.out.group_handle = group_handle;
5815 status = dcerpc_samr_DeleteDomainGroup(p, tctx, &d);
5816 torture_assert_ntstatus_ok(tctx, status, "DeleteDomainGroup");
5821 static bool test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
5822 struct policy_handle *domain_handle)
5824 struct samr_TestPrivateFunctionsDomain r;
5828 torture_comment(tctx, "Testing TestPrivateFunctionsDomain\n");
5830 r.in.domain_handle = domain_handle;
5832 status = dcerpc_samr_TestPrivateFunctionsDomain(p, tctx, &r);
5833 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsDomain");
5838 static bool test_RidToSid(struct dcerpc_pipe *p, struct torture_context *tctx,
5839 struct dom_sid *domain_sid,
5840 struct policy_handle *domain_handle)
5842 struct samr_RidToSid r;
5845 struct dom_sid *calc_sid, *out_sid;
5846 int rids[] = { 0, 42, 512, 10200 };
5849 for (i=0;i<ARRAY_SIZE(rids);i++) {
5850 torture_comment(tctx, "Testing RidToSid\n");
5852 calc_sid = dom_sid_dup(tctx, domain_sid);
5853 r.in.domain_handle = domain_handle;
5855 r.out.sid = &out_sid;
5857 status = dcerpc_samr_RidToSid(p, tctx, &r);
5858 if (!NT_STATUS_IS_OK(status)) {
5859 printf("RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
5862 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
5864 if (!dom_sid_equal(calc_sid, out_sid)) {
5865 printf("RidToSid for %d failed - got %s, expected %s\n", rids[i],
5866 dom_sid_string(tctx, out_sid),
5867 dom_sid_string(tctx, calc_sid));
5876 static bool test_GetBootKeyInformation(struct dcerpc_pipe *p, struct torture_context *tctx,
5877 struct policy_handle *domain_handle)
5879 struct samr_GetBootKeyInformation r;
5882 uint32_t unknown = 0;
5884 torture_comment(tctx, "Testing GetBootKeyInformation\n");
5886 r.in.domain_handle = domain_handle;
5887 r.out.unknown = &unknown;
5889 status = dcerpc_samr_GetBootKeyInformation(p, tctx, &r);
5890 if (!NT_STATUS_IS_OK(status)) {
5891 /* w2k3 seems to fail this sometimes and pass it sometimes */
5892 torture_comment(tctx, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
5898 static bool test_AddGroupMember(struct dcerpc_pipe *p, struct torture_context *tctx,
5899 struct policy_handle *domain_handle,
5900 struct policy_handle *group_handle)
5903 struct samr_AddGroupMember r;
5904 struct samr_DeleteGroupMember d;
5905 struct samr_QueryGroupMember q;
5906 struct samr_RidTypeArray *rids = NULL;
5907 struct samr_SetMemberAttributesOfGroup s;
5909 bool found_member = false;
5912 status = test_LookupName(p, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
5913 torture_assert_ntstatus_ok(tctx, status, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME);
5915 r.in.group_handle = group_handle;
5917 r.in.flags = 0; /* ??? */
5919 torture_comment(tctx, "Testing AddGroupMember, QueryGroupMember and DeleteGroupMember\n");
5921 d.in.group_handle = group_handle;
5924 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
5925 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_NOT_IN_GROUP, status, "DeleteGroupMember");
5927 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5928 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
5930 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5931 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_IN_GROUP, status, "AddGroupMember");
5933 if (torture_setting_bool(tctx, "samba4", false) ||
5934 torture_setting_bool(tctx, "samba3", false)) {
5935 torture_comment(tctx, "skipping SetMemberAttributesOfGroup test against Samba\n");
5937 /* this one is quite strange. I am using random inputs in the
5938 hope of triggering an error that might give us a clue */
5940 s.in.group_handle = group_handle;
5941 s.in.unknown1 = random();
5942 s.in.unknown2 = random();
5944 status = dcerpc_samr_SetMemberAttributesOfGroup(p, tctx, &s);
5945 torture_assert_ntstatus_ok(tctx, status, "SetMemberAttributesOfGroup");
5948 q.in.group_handle = group_handle;
5951 status = dcerpc_samr_QueryGroupMember(p, tctx, &q);
5952 torture_assert_ntstatus_ok(tctx, status, "QueryGroupMember");
5953 torture_assert(tctx, rids, "QueryGroupMember did not fill in rids structure");
5955 for (i=0; i < rids->count; i++) {
5956 if (rids->rids[i] == rid) {
5957 found_member = true;
5961 torture_assert(tctx, found_member, "QueryGroupMember did not list newly added member");
5963 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
5964 torture_assert_ntstatus_ok(tctx, status, "DeleteGroupMember");
5967 found_member = false;
5969 status = dcerpc_samr_QueryGroupMember(p, tctx, &q);
5970 torture_assert_ntstatus_ok(tctx, status, "QueryGroupMember");
5971 torture_assert(tctx, rids, "QueryGroupMember did not fill in rids structure");
5973 for (i=0; i < rids->count; i++) {
5974 if (rids->rids[i] == rid) {
5975 found_member = true;
5979 torture_assert(tctx, !found_member, "QueryGroupMember does still list removed member");
5981 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5982 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
5988 static bool test_CreateDomainGroup(struct dcerpc_pipe *p,
5989 struct torture_context *tctx,
5990 struct policy_handle *domain_handle,
5991 const char *group_name,
5992 struct policy_handle *group_handle,
5993 struct dom_sid *domain_sid,
5997 struct samr_CreateDomainGroup r;
5999 struct lsa_String name;
6002 init_lsa_String(&name, group_name);
6004 r.in.domain_handle = domain_handle;
6006 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6007 r.out.group_handle = group_handle;
6010 printf("Testing CreateDomainGroup(%s)\n", r.in.name->string);
6012 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
6014 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
6015 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
6016 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.name->string);
6019 printf("Server should have refused create of '%s', got %s instead\n", r.in.name->string,
6025 if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS)) {
6026 if (!test_DeleteGroup_byname(p, tctx, domain_handle, r.in.name->string)) {
6027 printf("CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
6031 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
6033 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
6034 if (!test_DeleteUser_byname(p, tctx, domain_handle, r.in.name->string)) {
6036 printf("CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
6040 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
6042 torture_assert_ntstatus_ok(tctx, status, "CreateDomainGroup");
6048 if (!test_AddGroupMember(p, tctx, domain_handle, group_handle)) {
6049 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
6053 if (!test_SetGroupInfo(p, tctx, group_handle)) {
6062 its not totally clear what this does. It seems to accept any sid you like.
6064 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p,
6065 struct torture_context *tctx,
6066 struct policy_handle *domain_handle)
6069 struct samr_RemoveMemberFromForeignDomain r;
6071 r.in.domain_handle = domain_handle;
6072 r.in.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-12-34-56-78");
6074 status = dcerpc_samr_RemoveMemberFromForeignDomain(p, tctx, &r);
6075 torture_assert_ntstatus_ok(tctx, status, "RemoveMemberFromForeignDomain");
6080 static bool test_EnumDomainUsers(struct dcerpc_pipe *p,
6081 struct torture_context *tctx,
6082 struct policy_handle *domain_handle,
6083 uint32_t *total_num_entries_p)
6086 struct samr_EnumDomainUsers r;
6087 uint32_t resume_handle = 0;
6088 uint32_t num_entries = 0;
6089 uint32_t total_num_entries = 0;
6090 struct samr_SamArray *sam;
6092 r.in.domain_handle = domain_handle;
6093 r.in.acct_flags = 0;
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 EnumDomainUsers\n");
6104 status = dcerpc_samr_EnumDomainUsers(p, tctx, &r);
6105 if (NT_STATUS_IS_ERR(status)) {
6106 torture_assert_ntstatus_ok(tctx, status,
6107 "failed to enumerate users");
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_EnumDomainGroups(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_EnumDomainGroups 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 EnumDomainGroups\n");
6143 status = dcerpc_samr_EnumDomainGroups(p, tctx, &r);
6144 if (NT_STATUS_IS_ERR(status)) {
6145 torture_assert_ntstatus_ok(tctx, status,
6146 "failed to enumerate groups");
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_EnumDomainAliases(struct dcerpc_pipe *p,
6160 struct torture_context *tctx,
6161 struct policy_handle *domain_handle,
6162 uint32_t *total_num_entries_p)
6165 struct samr_EnumDomainAliases r;
6166 uint32_t resume_handle = 0;
6167 uint32_t num_entries = 0;
6168 uint32_t total_num_entries = 0;
6169 struct samr_SamArray *sam;
6171 r.in.domain_handle = domain_handle;
6172 r.in.max_size = (uint32_t)-1;
6173 r.in.resume_handle = &resume_handle;
6176 r.out.num_entries = &num_entries;
6177 r.out.resume_handle = &resume_handle;
6179 printf("Testing EnumDomainAliases\n");
6182 status = dcerpc_samr_EnumDomainAliases(p, tctx, &r);
6183 if (NT_STATUS_IS_ERR(status)) {
6184 torture_assert_ntstatus_ok(tctx, status,
6185 "failed to enumerate aliases");
6188 total_num_entries += num_entries;
6189 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
6191 if (total_num_entries_p) {
6192 *total_num_entries_p = total_num_entries;
6198 static bool test_QueryDisplayInfo_level(struct dcerpc_pipe *p,
6199 struct torture_context *tctx,
6200 struct policy_handle *handle,
6202 uint32_t *total_num_entries_p)
6205 struct samr_QueryDisplayInfo r;
6206 uint32_t total_num_entries = 0;
6208 r.in.domain_handle = handle;
6211 r.in.max_entries = (uint32_t)-1;
6212 r.in.buf_size = (uint32_t)-1;
6214 printf("Testing QueryDisplayInfo\n");
6217 uint32_t total_size;
6218 uint32_t returned_size;
6219 union samr_DispInfo info;
6221 r.out.total_size = &total_size;
6222 r.out.returned_size = &returned_size;
6225 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &r);
6226 if (NT_STATUS_IS_ERR(status)) {
6227 torture_assert_ntstatus_ok(tctx, status,
6228 "failed to query displayinfo");
6231 if (*r.out.returned_size == 0) {
6235 switch (r.in.level) {
6237 total_num_entries += info.info1.count;
6238 r.in.start_idx += info.info1.entries[info.info1.count - 1].idx + 1;
6241 total_num_entries += info.info2.count;
6242 r.in.start_idx += info.info2.entries[info.info2.count - 1].idx + 1;
6245 total_num_entries += info.info3.count;
6246 r.in.start_idx += info.info3.entries[info.info3.count - 1].idx + 1;
6249 total_num_entries += info.info4.count;
6250 r.in.start_idx += info.info4.entries[info.info4.count - 1].idx + 1;
6253 total_num_entries += info.info5.count;
6254 r.in.start_idx += info.info5.entries[info.info5.count - 1].idx + 1;
6260 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
6262 if (total_num_entries_p) {
6263 *total_num_entries_p = total_num_entries;
6269 static bool test_ManyObjects(struct dcerpc_pipe *p,
6270 struct torture_context *tctx,
6271 struct policy_handle *domain_handle,
6272 struct dom_sid *domain_sid,
6273 enum torture_samr_choice which_ops)
6275 uint32_t num_total = 1500;
6276 uint32_t num_enum = 0;
6277 uint32_t num_disp = 0;
6278 uint32_t num_created = 0;
6279 uint32_t num_anounced = 0;
6284 struct policy_handle *handles = talloc_zero_array(tctx, struct policy_handle, num_total);
6289 struct samr_QueryDomainInfo2 r;
6290 union samr_DomainInfo *info;
6291 r.in.domain_handle = domain_handle;
6295 status = dcerpc_samr_QueryDomainInfo2(p, tctx, &r);
6296 torture_assert_ntstatus_ok(tctx, status,
6297 "failed to query domain info");
6299 switch (which_ops) {
6300 case TORTURE_SAMR_MANY_ACCOUNTS:
6301 num_anounced = info->general.num_users;
6303 case TORTURE_SAMR_MANY_GROUPS:
6304 num_anounced = info->general.num_groups;
6306 case TORTURE_SAMR_MANY_ALIASES:
6307 num_anounced = info->general.num_aliases;
6316 for (i=0; i < num_total; i++) {
6318 const char *name = NULL;
6320 switch (which_ops) {
6321 case TORTURE_SAMR_MANY_ACCOUNTS:
6322 name = talloc_asprintf(tctx, "%s%04d", TEST_ACCOUNT_NAME, i);
6323 ret &= test_CreateUser(p, tctx, domain_handle, name, &handles[i], domain_sid, 0, NULL, false);
6325 case TORTURE_SAMR_MANY_GROUPS:
6326 name = talloc_asprintf(tctx, "%s%04d", TEST_GROUPNAME, i);
6327 ret &= test_CreateDomainGroup(p, tctx, domain_handle, name, &handles[i], domain_sid, false);
6329 case TORTURE_SAMR_MANY_ALIASES:
6330 name = talloc_asprintf(tctx, "%s%04d", TEST_ALIASNAME, i);
6331 ret &= test_CreateAlias(p, tctx, domain_handle, name, &handles[i], domain_sid, false);
6336 if (!policy_handle_empty(&handles[i])) {
6343 switch (which_ops) {
6344 case TORTURE_SAMR_MANY_ACCOUNTS:
6345 ret &= test_EnumDomainUsers(p, tctx, domain_handle, &num_enum);
6347 case TORTURE_SAMR_MANY_GROUPS:
6348 ret &= test_EnumDomainGroups(p, tctx, domain_handle, &num_enum);
6350 case TORTURE_SAMR_MANY_ALIASES:
6351 ret &= test_EnumDomainAliases(p, tctx, domain_handle, &num_enum);
6359 switch (which_ops) {
6360 case TORTURE_SAMR_MANY_ACCOUNTS:
6361 ret &= test_QueryDisplayInfo_level(p, tctx, domain_handle, 1, &num_disp);
6363 case TORTURE_SAMR_MANY_GROUPS:
6364 ret &= test_QueryDisplayInfo_level(p, tctx, domain_handle, 3, &num_disp);
6366 case TORTURE_SAMR_MANY_ALIASES:
6367 /* no aliases in dispinfo */
6373 /* close or delete */
6375 for (i=0; i < num_total; i++) {
6377 if (policy_handle_empty(&handles[i])) {
6381 if (torture_setting_bool(tctx, "samba3", false)) {
6382 ret &= test_samr_handle_Close(p, tctx, &handles[i]);
6384 switch (which_ops) {
6385 case TORTURE_SAMR_MANY_ACCOUNTS:
6386 ret &= test_DeleteUser(p, tctx, &handles[i]);
6388 case TORTURE_SAMR_MANY_GROUPS:
6389 ret &= test_DeleteDomainGroup(p, tctx, &handles[i]);
6391 case TORTURE_SAMR_MANY_ALIASES:
6392 ret &= test_DeleteAlias(p, tctx, &handles[i]);
6400 talloc_free(handles);
6402 if (which_ops == TORTURE_SAMR_MANY_ACCOUNTS && num_enum != num_anounced + num_created) {
6403 torture_comment(tctx,
6404 "unexpected number of results (%u) returned in enum call, expected %u\n",
6405 num_enum, num_anounced + num_created);
6407 torture_comment(tctx,
6408 "unexpected number of results (%u) returned in dispinfo, call, expected %u\n",
6409 num_disp, num_anounced + num_created);
6414 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
6415 struct policy_handle *handle);
6417 static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
6418 struct policy_handle *handle, struct dom_sid *sid,
6419 enum torture_samr_choice which_ops,
6420 struct cli_credentials *machine_credentials)
6423 struct samr_OpenDomain r;
6424 struct policy_handle domain_handle;
6425 struct policy_handle alias_handle;
6426 struct policy_handle user_handle;
6427 struct policy_handle group_handle;
6430 ZERO_STRUCT(alias_handle);
6431 ZERO_STRUCT(user_handle);
6432 ZERO_STRUCT(group_handle);
6433 ZERO_STRUCT(domain_handle);
6435 torture_comment(tctx, "Testing OpenDomain of %s\n", dom_sid_string(tctx, sid));
6437 r.in.connect_handle = handle;
6438 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6440 r.out.domain_handle = &domain_handle;
6442 status = dcerpc_samr_OpenDomain(p, tctx, &r);
6443 torture_assert_ntstatus_ok(tctx, status, "OpenDomain");
6445 /* run the domain tests with the main handle closed - this tests
6446 the servers reference counting */
6447 torture_assert(tctx, test_samr_handle_Close(p, tctx, handle), "Failed to close SAMR handle");
6449 switch (which_ops) {
6450 case TORTURE_SAMR_PASSWORDS:
6451 case TORTURE_SAMR_USER_PRIVILEGES:
6452 if (!torture_setting_bool(tctx, "samba3", false)) {
6453 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops, NULL);
6455 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, which_ops, NULL, true);
6457 printf("Testing PASSWORDS or PRIVILAGES on domain %s failed!\n", dom_sid_string(tctx, sid));
6460 case TORTURE_SAMR_USER_ATTRIBUTES:
6461 if (!torture_setting_bool(tctx, "samba3", false)) {
6462 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops, NULL);
6464 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, which_ops, NULL, true);
6465 /* This test needs 'complex' users to validate */
6466 ret &= test_QueryDisplayInfo(p, tctx, &domain_handle);
6468 printf("Testing ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
6471 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
6472 if (!torture_setting_bool(tctx, "samba3", false)) {
6473 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops, machine_credentials);
6475 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, which_ops, machine_credentials, true);
6477 printf("Testing PASSWORDS PWDLASTSET on domain %s failed!\n", dom_sid_string(tctx, sid));
6480 case TORTURE_SAMR_MANY_ACCOUNTS:
6481 case TORTURE_SAMR_MANY_GROUPS:
6482 case TORTURE_SAMR_MANY_ALIASES:
6483 ret &= test_ManyObjects(p, tctx, &domain_handle, sid, which_ops);
6485 printf("Testing MANY-{ACCOUNTS,GROUPS,ALIASES} on domain %s failed!\n", dom_sid_string(tctx, sid));
6488 case TORTURE_SAMR_OTHER:
6489 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, which_ops, NULL, true);
6491 printf("Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid));
6493 if (!torture_setting_bool(tctx, "samba3", false)) {
6494 ret &= test_QuerySecurity(p, tctx, &domain_handle);
6496 ret &= test_RemoveMemberFromForeignDomain(p, tctx, &domain_handle);
6497 ret &= test_CreateAlias(p, tctx, &domain_handle, TEST_ALIASNAME, &alias_handle, sid, true);
6498 ret &= test_CreateDomainGroup(p, tctx, &domain_handle, TEST_GROUPNAME, &group_handle, sid, true);
6499 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
6500 ret &= test_QueryDomainInfo2(p, tctx, &domain_handle);
6501 ret &= test_EnumDomainUsers_all(p, tctx, &domain_handle);
6502 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
6503 ret &= test_EnumDomainGroups_all(p, tctx, &domain_handle);
6504 ret &= test_EnumDomainAliases_all(p, tctx, &domain_handle);
6505 ret &= test_QueryDisplayInfo2(p, tctx, &domain_handle);
6506 ret &= test_QueryDisplayInfo3(p, tctx, &domain_handle);
6507 ret &= test_QueryDisplayInfo_continue(p, tctx, &domain_handle);
6509 if (torture_setting_bool(tctx, "samba4", false)) {
6510 torture_comment(tctx, "skipping GetDisplayEnumerationIndex test against Samba4\n");
6512 ret &= test_GetDisplayEnumerationIndex(p, tctx, &domain_handle);
6513 ret &= test_GetDisplayEnumerationIndex2(p, tctx, &domain_handle);
6515 ret &= test_GroupList(p, tctx, &domain_handle);
6516 ret &= test_TestPrivateFunctionsDomain(p, tctx, &domain_handle);
6517 ret &= test_RidToSid(p, tctx, sid, &domain_handle);
6518 ret &= test_GetBootKeyInformation(p, tctx, &domain_handle);
6520 torture_comment(tctx, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx, sid));
6525 if (!policy_handle_empty(&user_handle) &&
6526 !test_DeleteUser(p, tctx, &user_handle)) {
6530 if (!policy_handle_empty(&alias_handle) &&
6531 !test_DeleteAlias(p, tctx, &alias_handle)) {
6535 if (!policy_handle_empty(&group_handle) &&
6536 !test_DeleteDomainGroup(p, tctx, &group_handle)) {
6540 torture_assert(tctx, test_samr_handle_Close(p, tctx, &domain_handle), "Failed to close SAMR domain handle");
6542 torture_assert(tctx, test_Connect(p, tctx, handle), "Faile to re-connect SAMR handle");
6543 /* reconnect the main handle */
6546 printf("Testing domain %s failed!\n", dom_sid_string(tctx, sid));
6552 static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
6553 struct policy_handle *handle, const char *domain,
6554 enum torture_samr_choice which_ops,
6555 struct cli_credentials *machine_credentials)
6558 struct samr_LookupDomain r;
6559 struct dom_sid2 *sid = NULL;
6560 struct lsa_String n1;
6561 struct lsa_String n2;
6564 torture_comment(tctx, "Testing LookupDomain(%s)\n", domain);
6566 /* check for correct error codes */
6567 r.in.connect_handle = handle;
6568 r.in.domain_name = &n2;
6572 status = dcerpc_samr_LookupDomain(p, tctx, &r);
6573 torture_assert_ntstatus_equal(tctx, NT_STATUS_INVALID_PARAMETER, status, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
6575 init_lsa_String(&n2, "xxNODOMAINxx");
6577 status = dcerpc_samr_LookupDomain(p, tctx, &r);
6578 torture_assert_ntstatus_equal(tctx, NT_STATUS_NO_SUCH_DOMAIN, status, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
6580 r.in.connect_handle = handle;
6582 init_lsa_String(&n1, domain);
6583 r.in.domain_name = &n1;
6585 status = dcerpc_samr_LookupDomain(p, tctx, &r);
6586 torture_assert_ntstatus_ok(tctx, status, "LookupDomain");
6588 if (!test_GetDomPwInfo(p, tctx, &n1)) {
6592 if (!test_OpenDomain(p, tctx, handle, *r.out.sid, which_ops,
6593 machine_credentials)) {
6601 static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
6602 struct policy_handle *handle, enum torture_samr_choice which_ops,
6603 struct cli_credentials *machine_credentials)
6606 struct samr_EnumDomains r;
6607 uint32_t resume_handle = 0;
6608 uint32_t num_entries = 0;
6609 struct samr_SamArray *sam = NULL;
6613 r.in.connect_handle = handle;
6614 r.in.resume_handle = &resume_handle;
6615 r.in.buf_size = (uint32_t)-1;
6616 r.out.resume_handle = &resume_handle;
6617 r.out.num_entries = &num_entries;
6620 status = dcerpc_samr_EnumDomains(p, tctx, &r);
6621 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
6627 for (i=0;i<sam->count;i++) {
6628 if (!test_LookupDomain(p, tctx, handle,
6629 sam->entries[i].name.string, which_ops,
6630 machine_credentials)) {
6635 status = dcerpc_samr_EnumDomains(p, tctx, &r);
6636 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
6642 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
6643 struct policy_handle *handle)
6646 struct samr_Connect r;
6647 struct samr_Connect2 r2;
6648 struct samr_Connect3 r3;
6649 struct samr_Connect4 r4;
6650 struct samr_Connect5 r5;
6651 union samr_ConnectInfo info;
6652 struct policy_handle h;
6653 uint32_t level_out = 0;
6654 bool ret = true, got_handle = false;
6656 torture_comment(tctx, "testing samr_Connect\n");
6658 r.in.system_name = 0;
6659 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6660 r.out.connect_handle = &h;
6662 status = dcerpc_samr_Connect(p, tctx, &r);
6663 if (!NT_STATUS_IS_OK(status)) {
6664 torture_comment(tctx, "Connect failed - %s\n", nt_errstr(status));
6671 torture_comment(tctx, "testing samr_Connect2\n");
6673 r2.in.system_name = NULL;
6674 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6675 r2.out.connect_handle = &h;
6677 status = dcerpc_samr_Connect2(p, tctx, &r2);
6678 if (!NT_STATUS_IS_OK(status)) {
6679 torture_comment(tctx, "Connect2 failed - %s\n", nt_errstr(status));
6683 test_samr_handle_Close(p, tctx, handle);
6689 torture_comment(tctx, "testing samr_Connect3\n");
6691 r3.in.system_name = NULL;
6693 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6694 r3.out.connect_handle = &h;
6696 status = dcerpc_samr_Connect3(p, tctx, &r3);
6697 if (!NT_STATUS_IS_OK(status)) {
6698 printf("Connect3 failed - %s\n", nt_errstr(status));
6702 test_samr_handle_Close(p, tctx, handle);
6708 torture_comment(tctx, "testing samr_Connect4\n");
6710 r4.in.system_name = "";
6711 r4.in.client_version = 0;
6712 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6713 r4.out.connect_handle = &h;
6715 status = dcerpc_samr_Connect4(p, tctx, &r4);
6716 if (!NT_STATUS_IS_OK(status)) {
6717 printf("Connect4 failed - %s\n", nt_errstr(status));
6721 test_samr_handle_Close(p, tctx, handle);
6727 torture_comment(tctx, "testing samr_Connect5\n");
6729 info.info1.client_version = 0;
6730 info.info1.unknown2 = 0;
6732 r5.in.system_name = "";
6733 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6735 r5.out.level_out = &level_out;
6736 r5.in.info_in = &info;
6737 r5.out.info_out = &info;
6738 r5.out.connect_handle = &h;
6740 status = dcerpc_samr_Connect5(p, tctx, &r5);
6741 if (!NT_STATUS_IS_OK(status)) {
6742 printf("Connect5 failed - %s\n", nt_errstr(status));
6746 test_samr_handle_Close(p, tctx, handle);
6756 bool torture_rpc_samr(struct torture_context *torture)
6759 struct dcerpc_pipe *p;
6761 struct policy_handle handle;
6763 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6764 if (!NT_STATUS_IS_OK(status)) {
6768 ret &= test_Connect(p, torture, &handle);
6770 if (!torture_setting_bool(torture, "samba3", false)) {
6771 ret &= test_QuerySecurity(p, torture, &handle);
6774 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_OTHER, NULL);
6776 ret &= test_SetDsrmPassword(p, torture, &handle);
6778 ret &= test_Shutdown(p, torture, &handle);
6780 ret &= test_samr_handle_Close(p, torture, &handle);
6786 bool torture_rpc_samr_users(struct torture_context *torture)
6789 struct dcerpc_pipe *p;
6791 struct policy_handle handle;
6793 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6794 if (!NT_STATUS_IS_OK(status)) {
6798 ret &= test_Connect(p, torture, &handle);
6800 if (!torture_setting_bool(torture, "samba3", false)) {
6801 ret &= test_QuerySecurity(p, torture, &handle);
6804 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_USER_ATTRIBUTES, NULL);
6806 ret &= test_SetDsrmPassword(p, torture, &handle);
6808 ret &= test_Shutdown(p, torture, &handle);
6810 ret &= test_samr_handle_Close(p, torture, &handle);
6816 bool torture_rpc_samr_passwords(struct torture_context *torture)
6819 struct dcerpc_pipe *p;
6821 struct policy_handle handle;
6823 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6824 if (!NT_STATUS_IS_OK(status)) {
6828 ret &= test_Connect(p, torture, &handle);
6830 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_PASSWORDS, NULL);
6832 ret &= test_samr_handle_Close(p, torture, &handle);
6837 static bool torture_rpc_samr_pwdlastset(struct torture_context *torture,
6838 struct dcerpc_pipe *p2,
6839 struct cli_credentials *machine_credentials)
6842 struct dcerpc_pipe *p;
6844 struct policy_handle handle;
6846 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6847 if (!NT_STATUS_IS_OK(status)) {
6851 ret &= test_Connect(p, torture, &handle);
6853 ret &= test_EnumDomains(p, torture, &handle,
6854 TORTURE_SAMR_PASSWORDS_PWDLASTSET,
6855 machine_credentials);
6857 ret &= test_samr_handle_Close(p, torture, &handle);
6862 struct torture_suite *torture_rpc_samr_passwords_pwdlastset(TALLOC_CTX *mem_ctx)
6864 struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-PASSWORDS-PWDLASTSET");
6865 struct torture_rpc_tcase *tcase;
6867 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
6869 TEST_ACCOUNT_NAME_PWD);
6871 torture_rpc_tcase_add_test_creds(tcase, "pwdLastSet",
6872 torture_rpc_samr_pwdlastset);
6877 static bool torture_rpc_samr_users_privileges_delete_user(struct torture_context *torture,
6878 struct dcerpc_pipe *p2,
6879 struct cli_credentials *machine_credentials)
6882 struct dcerpc_pipe *p;
6884 struct policy_handle handle;
6886 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6887 if (!NT_STATUS_IS_OK(status)) {
6891 ret &= test_Connect(p, torture, &handle);
6893 ret &= test_EnumDomains(p, torture, &handle,
6894 TORTURE_SAMR_USER_PRIVILEGES,
6895 machine_credentials);
6897 ret &= test_samr_handle_Close(p, torture, &handle);
6902 struct torture_suite *torture_rpc_samr_user_privileges(TALLOC_CTX *mem_ctx)
6904 struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-USERS-PRIVILEGES");
6905 struct torture_rpc_tcase *tcase;
6907 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
6909 TEST_ACCOUNT_NAME_PWD);
6911 torture_rpc_tcase_add_test_creds(tcase, "delete_privileged_user",
6912 torture_rpc_samr_users_privileges_delete_user);
6917 static bool torture_rpc_samr_many_accounts(struct torture_context *torture,
6918 struct dcerpc_pipe *p2,
6919 struct cli_credentials *machine_credentials)
6922 struct dcerpc_pipe *p;
6924 struct policy_handle handle;
6926 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6927 if (!NT_STATUS_IS_OK(status)) {
6931 ret &= test_Connect(p, torture, &handle);
6933 ret &= test_EnumDomains(p, torture, &handle,
6934 TORTURE_SAMR_MANY_ACCOUNTS,
6935 machine_credentials);
6937 ret &= test_samr_handle_Close(p, torture, &handle);
6942 static bool torture_rpc_samr_many_groups(struct torture_context *torture,
6943 struct dcerpc_pipe *p2,
6944 struct cli_credentials *machine_credentials)
6947 struct dcerpc_pipe *p;
6949 struct policy_handle handle;
6951 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6952 if (!NT_STATUS_IS_OK(status)) {
6956 ret &= test_Connect(p, torture, &handle);
6958 ret &= test_EnumDomains(p, torture, &handle,
6959 TORTURE_SAMR_MANY_GROUPS,
6960 machine_credentials);
6962 ret &= test_samr_handle_Close(p, torture, &handle);
6967 static bool torture_rpc_samr_many_aliases(struct torture_context *torture,
6968 struct dcerpc_pipe *p2,
6969 struct cli_credentials *machine_credentials)
6972 struct dcerpc_pipe *p;
6974 struct policy_handle handle;
6976 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6977 if (!NT_STATUS_IS_OK(status)) {
6981 ret &= test_Connect(p, torture, &handle);
6983 ret &= test_EnumDomains(p, torture, &handle,
6984 TORTURE_SAMR_MANY_ALIASES,
6985 machine_credentials);
6987 ret &= test_samr_handle_Close(p, torture, &handle);
6992 struct torture_suite *torture_rpc_samr_large_dc(TALLOC_CTX *mem_ctx)
6994 struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-LARGE-DC");
6995 struct torture_rpc_tcase *tcase;
6997 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
7001 torture_rpc_tcase_add_test_creds(tcase, "many_aliases",
7002 torture_rpc_samr_many_aliases);
7003 torture_rpc_tcase_add_test_creds(tcase, "many_groups",
7004 torture_rpc_samr_many_groups);
7005 torture_rpc_tcase_add_test_creds(tcase, "many_accounts",
7006 torture_rpc_samr_many_accounts);