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 torture_warning(tctx, "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 torture_warning(tctx, "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 torture_warning(tctx, "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 torture_warning(tctx, "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 torture_warning(tctx, "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 torture_warning(tctx, "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 torture_warning(tctx, "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 torture_warning(tctx, "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 torture_warning(tctx, "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 torture_warning(tctx, "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 torture_warning(tctx, "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 torture_warning(tctx, "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 torture_warning(tctx, "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 torture_warning(tctx, "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 torture_warning(tctx, "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 torture_warning(tctx, "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 torture_warning(tctx, "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 torture_warning(tctx, "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 torture_warning(tctx, "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 torture_warning(tctx, "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: torture_comment(tctx, "ALIASINFOALL ignored\n"); break;
1338 status = dcerpc_samr_SetAliasInfo(p, tctx, &r);
1339 if (!NT_STATUS_IS_OK(status)) {
1340 torture_warning(tctx, "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 torture_warning(tctx, "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 torture_warning(tctx, "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 torture_warning(tctx, "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 torture_warning(tctx, "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 torture_warning(tctx, "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 torture_warning(tctx, "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 torture_comment(tctx, "Testing ChangePasswordUser for user 'testuser'\n");
1548 torture_comment(tctx, "old password: %s\n", oldpass);
1549 torture_comment(tctx, "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 torture_warning(tctx, "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 torture_warning(tctx, "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 torture_warning(tctx, "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 torture_warning(tctx, "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 torture_warning(tctx, "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 torture_comment(tctx, "ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1828 } else if (!NT_STATUS_IS_OK(status)) {
1829 torture_warning(tctx, "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 torture_comment(tctx, "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 torture_warning(tctx, "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 torture_warning(tctx, "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 torture_warning(tctx, "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 torture_warning(tctx, "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 torture_warning(tctx, "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 torture_warning(tctx, "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 torture_warning(tctx, "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 torture_comment(tctx, "OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
2026 } else if (!NT_STATUS_IS_OK(status)) {
2027 torture_warning(tctx, "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 torture_comment(tctx, "ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
2105 } else if (!NT_STATUS_IS_OK(status)) {
2106 torture_warning(tctx, "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 torture_warning(tctx, "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 torture_warning(tctx, "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 torture_warning(tctx, "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 torture_warning(tctx, "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 torture_warning(tctx, "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 torture_warning(tctx, "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 torture_warning(tctx, "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 torture_warning(tctx, "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 torture_warning(tctx, "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 torture_warning(tctx, "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 torture_warning(tctx, "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 torture_warning(tctx, "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 torture_warning(tctx, "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 torture_warning(tctx, "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 torture_warning(tctx, "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 torture_comment(tctx, "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 torture_comment(tctx, "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 torture_comment(tctx, "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 torture_warning(tctx, "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 torture_comment(tctx, "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 torture_comment(tctx, "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 torture_warning(tctx, "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 torture_warning(tctx, "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 torture_warning(tctx, "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 torture_comment(tctx, "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 torture_warning(tctx, "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 torture_warning(tctx, "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 torture_comment(tctx, "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 torture_warning(tctx, "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;
3992 torture_comment(tctx, "Testing DeleteAlias\n");
3994 d.in.alias_handle = alias_handle;
3995 d.out.alias_handle = alias_handle;
3997 status = dcerpc_samr_DeleteDomAlias(p, tctx, &d);
3998 if (!NT_STATUS_IS_OK(status)) {
3999 torture_warning(tctx, "DeleteAlias failed - %s\n", nt_errstr(status));
4006 static bool test_CreateAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
4007 struct policy_handle *domain_handle,
4008 const char *alias_name,
4009 struct policy_handle *alias_handle,
4010 const struct dom_sid *domain_sid,
4014 struct samr_CreateDomAlias r;
4015 struct lsa_String name;
4019 init_lsa_String(&name, alias_name);
4020 r.in.domain_handle = domain_handle;
4021 r.in.alias_name = &name;
4022 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4023 r.out.alias_handle = alias_handle;
4026 torture_comment(tctx, "Testing CreateAlias (%s)\n", r.in.alias_name->string);
4028 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
4030 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
4031 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
4032 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.alias_name->string);
4035 torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.alias_name->string,
4041 if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
4042 if (!test_DeleteAlias_byname(p, tctx, domain_handle, r.in.alias_name->string)) {
4045 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
4048 if (!NT_STATUS_IS_OK(status)) {
4049 torture_warning(tctx, "CreateAlias failed - %s\n", nt_errstr(status));
4057 if (!test_alias_ops(p, tctx, alias_handle, domain_sid)) {
4064 static bool test_ChangePassword(struct dcerpc_pipe *p,
4065 struct torture_context *tctx,
4066 const char *acct_name,
4067 struct policy_handle *domain_handle, char **password)
4075 if (!test_ChangePasswordUser(p, tctx, acct_name, domain_handle, password)) {
4079 if (!test_ChangePasswordUser2(p, tctx, acct_name, password, 0, true)) {
4083 if (!test_OemChangePasswordUser2(p, tctx, acct_name, domain_handle, password)) {
4087 /* test what happens when setting the old password again */
4088 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, *password, 0, true)) {
4093 char simple_pass[9];
4094 char *v = generate_random_str(tctx, 1);
4096 ZERO_STRUCT(simple_pass);
4097 memset(simple_pass, *v, sizeof(simple_pass) - 1);
4099 /* test what happens when picking a simple password */
4100 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, simple_pass, 0, true)) {
4105 /* set samr_SetDomainInfo level 1 with min_length 5 */
4107 struct samr_QueryDomainInfo r;
4108 union samr_DomainInfo *info = NULL;
4109 struct samr_SetDomainInfo s;
4110 uint16_t len_old, len;
4111 uint32_t pwd_prop_old;
4112 int64_t min_pwd_age_old;
4117 r.in.domain_handle = domain_handle;
4121 torture_comment(tctx, "testing samr_QueryDomainInfo level 1\n");
4122 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
4123 if (!NT_STATUS_IS_OK(status)) {
4127 s.in.domain_handle = domain_handle;
4131 /* remember the old min length, so we can reset it */
4132 len_old = s.in.info->info1.min_password_length;
4133 s.in.info->info1.min_password_length = len;
4134 pwd_prop_old = s.in.info->info1.password_properties;
4135 /* turn off password complexity checks for this test */
4136 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
4138 min_pwd_age_old = s.in.info->info1.min_password_age;
4139 s.in.info->info1.min_password_age = 0;
4141 torture_comment(tctx, "testing samr_SetDomainInfo level 1\n");
4142 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
4143 if (!NT_STATUS_IS_OK(status)) {
4147 torture_comment(tctx, "calling test_ChangePasswordUser3 with too short password\n");
4149 if (!test_ChangePasswordUser3(p, tctx, acct_name, len - 1, password, NULL, 0, true)) {
4153 s.in.info->info1.min_password_length = len_old;
4154 s.in.info->info1.password_properties = pwd_prop_old;
4155 s.in.info->info1.min_password_age = min_pwd_age_old;
4157 torture_comment(tctx, "testing samr_SetDomainInfo level 1\n");
4158 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
4159 if (!NT_STATUS_IS_OK(status)) {
4167 struct samr_OpenUser r;
4168 struct samr_QueryUserInfo q;
4169 union samr_UserInfo *info;
4170 struct samr_LookupNames n;
4171 struct policy_handle user_handle;
4172 struct samr_Ids rids, types;
4174 n.in.domain_handle = domain_handle;
4176 n.in.names = talloc_array(tctx, struct lsa_String, 1);
4177 n.in.names[0].string = acct_name;
4179 n.out.types = &types;
4181 status = dcerpc_samr_LookupNames(p, tctx, &n);
4182 if (!NT_STATUS_IS_OK(status)) {
4183 torture_warning(tctx, "LookupNames failed - %s\n", nt_errstr(status));
4187 r.in.domain_handle = domain_handle;
4188 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4189 r.in.rid = n.out.rids->ids[0];
4190 r.out.user_handle = &user_handle;
4192 status = dcerpc_samr_OpenUser(p, tctx, &r);
4193 if (!NT_STATUS_IS_OK(status)) {
4194 torture_warning(tctx, "OpenUser(%u) failed - %s\n", n.out.rids->ids[0], nt_errstr(status));
4198 q.in.user_handle = &user_handle;
4202 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
4203 if (!NT_STATUS_IS_OK(status)) {
4204 torture_warning(tctx, "QueryUserInfo failed - %s\n", nt_errstr(status));
4208 torture_comment(tctx, "calling test_ChangePasswordUser3 with too early password change\n");
4210 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL,
4211 info->info5.last_password_change, true)) {
4216 /* we change passwords twice - this has the effect of verifying
4217 they were changed correctly for the final call */
4218 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
4222 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
4229 static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
4230 struct policy_handle *domain_handle,
4231 const char *user_name,
4232 struct policy_handle *user_handle_out,
4233 struct dom_sid *domain_sid,
4234 enum torture_samr_choice which_ops,
4235 struct cli_credentials *machine_credentials,
4239 TALLOC_CTX *user_ctx;
4242 struct samr_CreateUser r;
4243 struct samr_QueryUserInfo q;
4244 union samr_UserInfo *info;
4245 struct samr_DeleteUser d;
4248 /* This call creates a 'normal' account - check that it really does */
4249 const uint32_t acct_flags = ACB_NORMAL;
4250 struct lsa_String name;
4253 struct policy_handle user_handle;
4254 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
4255 init_lsa_String(&name, user_name);
4257 r.in.domain_handle = domain_handle;
4258 r.in.account_name = &name;
4259 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4260 r.out.user_handle = &user_handle;
4263 torture_comment(tctx, "Testing CreateUser(%s)\n", r.in.account_name->string);
4265 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
4267 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
4268 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
4269 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.account_name->string);
4272 torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
4278 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
4279 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
4280 talloc_free(user_ctx);
4283 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
4286 if (!NT_STATUS_IS_OK(status)) {
4287 talloc_free(user_ctx);
4288 torture_warning(tctx, "CreateUser failed - %s\n", nt_errstr(status));
4293 if (user_handle_out) {
4294 *user_handle_out = user_handle;
4300 q.in.user_handle = &user_handle;
4304 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
4305 if (!NT_STATUS_IS_OK(status)) {
4306 torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
4307 q.in.level, nt_errstr(status));
4310 if ((info->info16.acct_flags & acct_flags) != acct_flags) {
4311 torture_warning(tctx, "QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
4312 info->info16.acct_flags,
4318 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
4319 domain_sid, acct_flags, name.string, which_ops,
4320 machine_credentials)) {
4324 if (user_handle_out) {
4325 *user_handle_out = user_handle;
4327 torture_comment(tctx, "Testing DeleteUser (createuser test)\n");
4329 d.in.user_handle = &user_handle;
4330 d.out.user_handle = &user_handle;
4332 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
4333 if (!NT_STATUS_IS_OK(status)) {
4334 torture_warning(tctx, "DeleteUser failed - %s\n", nt_errstr(status));
4341 talloc_free(user_ctx);
4347 static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
4348 struct policy_handle *domain_handle,
4349 struct dom_sid *domain_sid,
4350 enum torture_samr_choice which_ops,
4351 struct cli_credentials *machine_credentials)
4354 struct samr_CreateUser2 r;
4355 struct samr_QueryUserInfo q;
4356 union samr_UserInfo *info;
4357 struct samr_DeleteUser d;
4358 struct policy_handle user_handle;
4360 struct lsa_String name;
4365 uint32_t acct_flags;
4366 const char *account_name;
4368 } account_types[] = {
4369 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
4370 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
4371 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
4372 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
4373 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
4374 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
4375 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
4376 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
4377 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
4378 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_ACCESS_DENIED },
4379 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
4380 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
4381 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
4382 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
4383 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
4386 for (i = 0; account_types[i].account_name; i++) {
4387 TALLOC_CTX *user_ctx;
4388 uint32_t acct_flags = account_types[i].acct_flags;
4389 uint32_t access_granted;
4390 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
4391 init_lsa_String(&name, account_types[i].account_name);
4393 r.in.domain_handle = domain_handle;
4394 r.in.account_name = &name;
4395 r.in.acct_flags = acct_flags;
4396 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4397 r.out.user_handle = &user_handle;
4398 r.out.access_granted = &access_granted;
4401 torture_comment(tctx, "Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
4403 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
4405 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
4406 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
4407 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.account_name->string);
4410 torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
4417 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
4418 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
4419 talloc_free(user_ctx);
4423 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
4426 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
4427 torture_warning(tctx, "CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
4428 nt_errstr(status), nt_errstr(account_types[i].nt_status));
4432 if (NT_STATUS_IS_OK(status)) {
4433 q.in.user_handle = &user_handle;
4437 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
4438 if (!NT_STATUS_IS_OK(status)) {
4439 torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
4440 q.in.level, nt_errstr(status));
4443 uint32_t expected_flags = (acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
4444 if (acct_flags == ACB_NORMAL) {
4445 expected_flags |= ACB_PW_EXPIRED;
4447 if ((info->info5.acct_flags) != expected_flags) {
4448 torture_warning(tctx, "QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
4449 info->info5.acct_flags,
4453 switch (acct_flags) {
4455 if (info->info5.primary_gid != DOMAIN_RID_DCS) {
4456 torture_warning(tctx, "QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n",
4457 DOMAIN_RID_DCS, info->info5.primary_gid);
4462 if (info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
4463 torture_warning(tctx, "QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
4464 DOMAIN_RID_DOMAIN_MEMBERS, info->info5.primary_gid);
4469 if (info->info5.primary_gid != DOMAIN_RID_USERS) {
4470 torture_warning(tctx, "QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n",
4471 DOMAIN_RID_USERS, info->info5.primary_gid);
4478 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
4479 domain_sid, acct_flags, name.string, which_ops,
4480 machine_credentials)) {
4484 if (!policy_handle_empty(&user_handle)) {
4485 torture_comment(tctx, "Testing DeleteUser (createuser2 test)\n");
4487 d.in.user_handle = &user_handle;
4488 d.out.user_handle = &user_handle;
4490 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
4491 if (!NT_STATUS_IS_OK(status)) {
4492 torture_warning(tctx, "DeleteUser failed - %s\n", nt_errstr(status));
4497 talloc_free(user_ctx);
4503 static bool test_QueryAliasInfo(struct dcerpc_pipe *p,
4504 struct torture_context *tctx,
4505 struct policy_handle *handle)
4508 struct samr_QueryAliasInfo r;
4509 union samr_AliasInfo *info;
4510 uint16_t levels[] = {1, 2, 3};
4514 for (i=0;i<ARRAY_SIZE(levels);i++) {
4515 torture_comment(tctx, "Testing QueryAliasInfo level %u\n", levels[i]);
4517 r.in.alias_handle = handle;
4518 r.in.level = levels[i];
4521 status = dcerpc_samr_QueryAliasInfo(p, tctx, &r);
4522 if (!NT_STATUS_IS_OK(status)) {
4523 torture_warning(tctx, "QueryAliasInfo level %u failed - %s\n",
4524 levels[i], nt_errstr(status));
4532 static bool test_QueryGroupInfo(struct dcerpc_pipe *p,
4533 struct torture_context *tctx,
4534 struct policy_handle *handle)
4537 struct samr_QueryGroupInfo r;
4538 union samr_GroupInfo *info;
4539 uint16_t levels[] = {1, 2, 3, 4, 5};
4543 for (i=0;i<ARRAY_SIZE(levels);i++) {
4544 torture_comment(tctx, "Testing QueryGroupInfo level %u\n", levels[i]);
4546 r.in.group_handle = handle;
4547 r.in.level = levels[i];
4550 status = dcerpc_samr_QueryGroupInfo(p, tctx, &r);
4551 if (!NT_STATUS_IS_OK(status)) {
4552 torture_warning(tctx, "QueryGroupInfo level %u failed - %s\n",
4553 levels[i], nt_errstr(status));
4561 static bool test_QueryGroupMember(struct dcerpc_pipe *p,
4562 struct torture_context *tctx,
4563 struct policy_handle *handle)
4566 struct samr_QueryGroupMember r;
4567 struct samr_RidTypeArray *rids = NULL;
4570 torture_comment(tctx, "Testing QueryGroupMember\n");
4572 r.in.group_handle = handle;
4575 status = dcerpc_samr_QueryGroupMember(p, tctx, &r);
4576 if (!NT_STATUS_IS_OK(status)) {
4577 torture_warning(tctx, "QueryGroupInfo failed - %s\n", nt_errstr(status));
4585 static bool test_SetGroupInfo(struct dcerpc_pipe *p,
4586 struct torture_context *tctx,
4587 struct policy_handle *handle)
4590 struct samr_QueryGroupInfo r;
4591 union samr_GroupInfo *info;
4592 struct samr_SetGroupInfo s;
4593 uint16_t levels[] = {1, 2, 3, 4};
4594 uint16_t set_ok[] = {0, 1, 1, 1};
4598 for (i=0;i<ARRAY_SIZE(levels);i++) {
4599 torture_comment(tctx, "Testing QueryGroupInfo level %u\n", levels[i]);
4601 r.in.group_handle = handle;
4602 r.in.level = levels[i];
4605 status = dcerpc_samr_QueryGroupInfo(p, tctx, &r);
4606 if (!NT_STATUS_IS_OK(status)) {
4607 torture_warning(tctx, "QueryGroupInfo level %u failed - %s\n",
4608 levels[i], nt_errstr(status));
4612 torture_comment(tctx, "Testing SetGroupInfo level %u\n", levels[i]);
4614 s.in.group_handle = handle;
4615 s.in.level = levels[i];
4616 s.in.info = *r.out.info;
4619 /* disabled this, as it changes the name only from the point of view of samr,
4620 but leaves the name from the point of view of w2k3 internals (and ldap). This means
4621 the name is still reserved, so creating the old name fails, but deleting by the old name
4623 if (s.in.level == 2) {
4624 init_lsa_String(&s.in.info->string, "NewName");
4628 if (s.in.level == 4) {
4629 init_lsa_String(&s.in.info->description, "test description");
4632 status = dcerpc_samr_SetGroupInfo(p, tctx, &s);
4634 if (!NT_STATUS_IS_OK(status)) {
4635 torture_warning(tctx, "SetGroupInfo level %u failed - %s\n",
4636 r.in.level, nt_errstr(status));
4641 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
4642 torture_warning(tctx, "SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
4643 r.in.level, nt_errstr(status));
4653 static bool test_QueryUserInfo(struct dcerpc_pipe *p,
4654 struct torture_context *tctx,
4655 struct policy_handle *handle)
4658 struct samr_QueryUserInfo r;
4659 union samr_UserInfo *info;
4660 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
4661 11, 12, 13, 14, 16, 17, 20, 21};
4665 for (i=0;i<ARRAY_SIZE(levels);i++) {
4666 torture_comment(tctx, "Testing QueryUserInfo level %u\n", levels[i]);
4668 r.in.user_handle = handle;
4669 r.in.level = levels[i];
4672 status = dcerpc_samr_QueryUserInfo(p, tctx, &r);
4673 if (!NT_STATUS_IS_OK(status)) {
4674 torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
4675 levels[i], nt_errstr(status));
4683 static bool test_QueryUserInfo2(struct dcerpc_pipe *p,
4684 struct torture_context *tctx,
4685 struct policy_handle *handle)
4688 struct samr_QueryUserInfo2 r;
4689 union samr_UserInfo *info;
4690 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
4691 11, 12, 13, 14, 16, 17, 20, 21};
4695 for (i=0;i<ARRAY_SIZE(levels);i++) {
4696 torture_comment(tctx, "Testing QueryUserInfo2 level %u\n", levels[i]);
4698 r.in.user_handle = handle;
4699 r.in.level = levels[i];
4702 status = dcerpc_samr_QueryUserInfo2(p, tctx, &r);
4703 if (!NT_STATUS_IS_OK(status)) {
4704 torture_warning(tctx, "QueryUserInfo2 level %u failed - %s\n",
4705 levels[i], nt_errstr(status));
4713 static bool test_OpenUser(struct dcerpc_pipe *p,
4714 struct torture_context *tctx,
4715 struct policy_handle *handle, uint32_t rid)
4718 struct samr_OpenUser r;
4719 struct policy_handle user_handle;
4722 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
4724 r.in.domain_handle = handle;
4725 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4727 r.out.user_handle = &user_handle;
4729 status = dcerpc_samr_OpenUser(p, tctx, &r);
4730 if (!NT_STATUS_IS_OK(status)) {
4731 torture_warning(tctx, "OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
4735 if (!test_QuerySecurity(p, tctx, &user_handle)) {
4739 if (!test_QueryUserInfo(p, tctx, &user_handle)) {
4743 if (!test_QueryUserInfo2(p, tctx, &user_handle)) {
4747 if (!test_GetUserPwInfo(p, tctx, &user_handle)) {
4751 if (!test_GetGroupsForUser(p,tctx, &user_handle)) {
4755 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
4762 static bool test_OpenGroup(struct dcerpc_pipe *p,
4763 struct torture_context *tctx,
4764 struct policy_handle *handle, uint32_t rid)
4767 struct samr_OpenGroup r;
4768 struct policy_handle group_handle;
4771 torture_comment(tctx, "Testing OpenGroup(%u)\n", rid);
4773 r.in.domain_handle = handle;
4774 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4776 r.out.group_handle = &group_handle;
4778 status = dcerpc_samr_OpenGroup(p, tctx, &r);
4779 if (!NT_STATUS_IS_OK(status)) {
4780 torture_warning(tctx, "OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
4784 if (!torture_setting_bool(tctx, "samba3", false)) {
4785 if (!test_QuerySecurity(p, tctx, &group_handle)) {
4790 if (!test_QueryGroupInfo(p, tctx, &group_handle)) {
4794 if (!test_QueryGroupMember(p, tctx, &group_handle)) {
4798 if (!test_samr_handle_Close(p, tctx, &group_handle)) {
4805 static bool test_OpenAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
4806 struct policy_handle *handle, uint32_t rid)
4809 struct samr_OpenAlias r;
4810 struct policy_handle alias_handle;
4813 torture_comment(tctx, "Testing OpenAlias(%u)\n", rid);
4815 r.in.domain_handle = handle;
4816 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4818 r.out.alias_handle = &alias_handle;
4820 status = dcerpc_samr_OpenAlias(p, tctx, &r);
4821 if (!NT_STATUS_IS_OK(status)) {
4822 torture_warning(tctx, "OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
4826 if (!torture_setting_bool(tctx, "samba3", false)) {
4827 if (!test_QuerySecurity(p, tctx, &alias_handle)) {
4832 if (!test_QueryAliasInfo(p, tctx, &alias_handle)) {
4836 if (!test_GetMembersInAlias(p, tctx, &alias_handle)) {
4840 if (!test_samr_handle_Close(p, tctx, &alias_handle)) {
4847 static bool check_mask(struct dcerpc_pipe *p, struct torture_context *tctx,
4848 struct policy_handle *handle, uint32_t rid,
4849 uint32_t acct_flag_mask)
4852 struct samr_OpenUser r;
4853 struct samr_QueryUserInfo q;
4854 union samr_UserInfo *info;
4855 struct policy_handle user_handle;
4858 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
4860 r.in.domain_handle = handle;
4861 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4863 r.out.user_handle = &user_handle;
4865 status = dcerpc_samr_OpenUser(p, tctx, &r);
4866 if (!NT_STATUS_IS_OK(status)) {
4867 torture_warning(tctx, "OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
4871 q.in.user_handle = &user_handle;
4875 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
4876 if (!NT_STATUS_IS_OK(status)) {
4877 torture_warning(tctx, "QueryUserInfo level 16 failed - %s\n",
4881 if ((acct_flag_mask & info->info16.acct_flags) == 0) {
4882 torture_warning(tctx, "Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
4883 acct_flag_mask, info->info16.acct_flags, rid);
4888 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
4895 static bool test_EnumDomainUsers_all(struct dcerpc_pipe *p,
4896 struct torture_context *tctx,
4897 struct policy_handle *handle)
4899 NTSTATUS status = STATUS_MORE_ENTRIES;
4900 struct samr_EnumDomainUsers r;
4901 uint32_t mask, resume_handle=0;
4904 struct samr_LookupNames n;
4905 struct samr_LookupRids lr ;
4906 struct lsa_Strings names;
4907 struct samr_Ids rids, types;
4908 struct samr_SamArray *sam = NULL;
4909 uint32_t num_entries = 0;
4911 uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
4912 ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
4913 ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
4916 torture_comment(tctx, "Testing EnumDomainUsers\n");
4918 for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
4919 r.in.domain_handle = handle;
4920 r.in.resume_handle = &resume_handle;
4921 r.in.acct_flags = mask = masks[mask_idx];
4922 r.in.max_size = (uint32_t)-1;
4923 r.out.resume_handle = &resume_handle;
4924 r.out.num_entries = &num_entries;
4927 status = dcerpc_samr_EnumDomainUsers(p, tctx, &r);
4928 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
4929 !NT_STATUS_IS_OK(status)) {
4930 torture_warning(tctx, "EnumDomainUsers failed - %s\n", nt_errstr(status));
4934 torture_assert(tctx, sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
4936 if (sam->count == 0) {
4940 for (i=0;i<sam->count;i++) {
4942 if (!check_mask(p, tctx, handle, sam->entries[i].idx, mask)) {
4945 } else if (!test_OpenUser(p, tctx, handle, sam->entries[i].idx)) {
4951 torture_comment(tctx, "Testing LookupNames\n");
4952 n.in.domain_handle = handle;
4953 n.in.num_names = sam->count;
4954 n.in.names = talloc_array(tctx, struct lsa_String, sam->count);
4956 n.out.types = &types;
4957 for (i=0;i<sam->count;i++) {
4958 n.in.names[i].string = sam->entries[i].name.string;
4960 status = dcerpc_samr_LookupNames(p, tctx, &n);
4961 if (!NT_STATUS_IS_OK(status)) {
4962 torture_warning(tctx, "LookupNames failed - %s\n", nt_errstr(status));
4967 torture_comment(tctx, "Testing LookupRids\n");
4968 lr.in.domain_handle = handle;
4969 lr.in.num_rids = sam->count;
4970 lr.in.rids = talloc_array(tctx, uint32_t, sam->count);
4971 lr.out.names = &names;
4972 lr.out.types = &types;
4973 for (i=0;i<sam->count;i++) {
4974 lr.in.rids[i] = sam->entries[i].idx;
4976 status = dcerpc_samr_LookupRids(p, tctx, &lr);
4977 torture_assert_ntstatus_ok(tctx, status, "LookupRids");
4983 try blasting the server with a bunch of sync requests
4985 static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, struct torture_context *tctx,
4986 struct policy_handle *handle)
4989 struct samr_EnumDomainUsers r;
4990 uint32_t resume_handle=0;
4992 #define ASYNC_COUNT 100
4993 struct rpc_request *req[ASYNC_COUNT];
4995 if (!torture_setting_bool(tctx, "dangerous", false)) {
4996 torture_skip(tctx, "samr async test disabled - enable dangerous tests to use\n");
4999 torture_comment(tctx, "Testing EnumDomainUsers_async\n");
5001 r.in.domain_handle = handle;
5002 r.in.resume_handle = &resume_handle;
5003 r.in.acct_flags = 0;
5004 r.in.max_size = (uint32_t)-1;
5005 r.out.resume_handle = &resume_handle;
5007 for (i=0;i<ASYNC_COUNT;i++) {
5008 req[i] = dcerpc_samr_EnumDomainUsers_send(p, tctx, &r);
5011 for (i=0;i<ASYNC_COUNT;i++) {
5012 status = dcerpc_ndr_request_recv(req[i]);
5013 if (!NT_STATUS_IS_OK(status)) {
5014 torture_warning(tctx, "EnumDomainUsers[%d] failed - %s\n",
5015 i, nt_errstr(status));
5020 torture_comment(tctx, "%d async requests OK\n", i);
5025 static bool test_EnumDomainGroups_all(struct dcerpc_pipe *p,
5026 struct torture_context *tctx,
5027 struct policy_handle *handle)
5030 struct samr_EnumDomainGroups r;
5031 uint32_t resume_handle=0;
5032 struct samr_SamArray *sam = NULL;
5033 uint32_t num_entries = 0;
5037 torture_comment(tctx, "Testing EnumDomainGroups\n");
5039 r.in.domain_handle = handle;
5040 r.in.resume_handle = &resume_handle;
5041 r.in.max_size = (uint32_t)-1;
5042 r.out.resume_handle = &resume_handle;
5043 r.out.num_entries = &num_entries;
5046 status = dcerpc_samr_EnumDomainGroups(p, tctx, &r);
5047 if (!NT_STATUS_IS_OK(status)) {
5048 torture_warning(tctx, "EnumDomainGroups failed - %s\n", nt_errstr(status));
5056 for (i=0;i<sam->count;i++) {
5057 if (!test_OpenGroup(p, tctx, handle, sam->entries[i].idx)) {
5065 static bool test_EnumDomainAliases_all(struct dcerpc_pipe *p,
5066 struct torture_context *tctx,
5067 struct policy_handle *handle)
5070 struct samr_EnumDomainAliases r;
5071 uint32_t resume_handle=0;
5072 struct samr_SamArray *sam = NULL;
5073 uint32_t num_entries = 0;
5077 torture_comment(tctx, "Testing EnumDomainAliases\n");
5079 r.in.domain_handle = handle;
5080 r.in.resume_handle = &resume_handle;
5081 r.in.max_size = (uint32_t)-1;
5083 r.out.num_entries = &num_entries;
5084 r.out.resume_handle = &resume_handle;
5086 status = dcerpc_samr_EnumDomainAliases(p, tctx, &r);
5087 if (!NT_STATUS_IS_OK(status)) {
5088 torture_warning(tctx, "EnumDomainAliases failed - %s\n", nt_errstr(status));
5096 for (i=0;i<sam->count;i++) {
5097 if (!test_OpenAlias(p, tctx, handle, sam->entries[i].idx)) {
5105 static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p,
5106 struct torture_context *tctx,
5107 struct policy_handle *handle)
5110 struct samr_GetDisplayEnumerationIndex r;
5112 uint16_t levels[] = {1, 2, 3, 4, 5};
5113 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
5114 struct lsa_String name;
5118 for (i=0;i<ARRAY_SIZE(levels);i++) {
5119 torture_comment(tctx, "Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
5121 init_lsa_String(&name, TEST_ACCOUNT_NAME);
5123 r.in.domain_handle = handle;
5124 r.in.level = levels[i];
5128 status = dcerpc_samr_GetDisplayEnumerationIndex(p, tctx, &r);
5131 !NT_STATUS_IS_OK(status) &&
5132 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
5133 torture_warning(tctx, "GetDisplayEnumerationIndex level %u failed - %s\n",
5134 levels[i], nt_errstr(status));
5138 init_lsa_String(&name, "zzzzzzzz");
5140 status = dcerpc_samr_GetDisplayEnumerationIndex(p, tctx, &r);
5142 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
5143 torture_warning(tctx, "GetDisplayEnumerationIndex level %u failed - %s\n",
5144 levels[i], nt_errstr(status));
5152 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p,
5153 struct torture_context *tctx,
5154 struct policy_handle *handle)
5157 struct samr_GetDisplayEnumerationIndex2 r;
5159 uint16_t levels[] = {1, 2, 3, 4, 5};
5160 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
5161 struct lsa_String name;
5165 for (i=0;i<ARRAY_SIZE(levels);i++) {
5166 torture_comment(tctx, "Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
5168 init_lsa_String(&name, TEST_ACCOUNT_NAME);
5170 r.in.domain_handle = handle;
5171 r.in.level = levels[i];
5175 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, tctx, &r);
5177 !NT_STATUS_IS_OK(status) &&
5178 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
5179 torture_warning(tctx, "GetDisplayEnumerationIndex2 level %u failed - %s\n",
5180 levels[i], nt_errstr(status));
5184 init_lsa_String(&name, "zzzzzzzz");
5186 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, tctx, &r);
5187 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
5188 torture_warning(tctx, "GetDisplayEnumerationIndex2 level %u failed - %s\n",
5189 levels[i], nt_errstr(status));
5197 #define STRING_EQUAL_QUERY(s1, s2, user) \
5198 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
5199 /* odd, but valid */ \
5200 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
5201 torture_warning(tctx, "%s mismatch for %s: %s != %s (%s)\n", \
5202 #s1, user.string, s1.string, s2.string, __location__); \
5205 #define INT_EQUAL_QUERY(s1, s2, user) \
5207 torture_warning(tctx, "%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
5208 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
5212 static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p,
5213 struct torture_context *tctx,
5214 struct samr_QueryDisplayInfo *querydisplayinfo,
5215 bool *seen_testuser)
5217 struct samr_OpenUser r;
5218 struct samr_QueryUserInfo q;
5219 union samr_UserInfo *info;
5220 struct policy_handle user_handle;
5223 r.in.domain_handle = querydisplayinfo->in.domain_handle;
5224 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5225 for (i = 0; ; i++) {
5226 switch (querydisplayinfo->in.level) {
5228 if (i >= querydisplayinfo->out.info->info1.count) {
5231 r.in.rid = querydisplayinfo->out.info->info1.entries[i].rid;
5234 if (i >= querydisplayinfo->out.info->info2.count) {
5237 r.in.rid = querydisplayinfo->out.info->info2.entries[i].rid;
5243 /* Not interested in validating just the account name */
5247 r.out.user_handle = &user_handle;
5249 switch (querydisplayinfo->in.level) {
5252 status = dcerpc_samr_OpenUser(p, tctx, &r);
5253 if (!NT_STATUS_IS_OK(status)) {
5254 torture_warning(tctx, "OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(status));
5259 q.in.user_handle = &user_handle;
5262 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
5263 if (!NT_STATUS_IS_OK(status)) {
5264 torture_warning(tctx, "QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(status));
5268 switch (querydisplayinfo->in.level) {
5270 if (seen_testuser && strcmp(info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
5271 *seen_testuser = true;
5273 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].full_name,
5274 info->info21.full_name, info->info21.account_name);
5275 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].account_name,
5276 info->info21.account_name, info->info21.account_name);
5277 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].description,
5278 info->info21.description, info->info21.account_name);
5279 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].rid,
5280 info->info21.rid, info->info21.account_name);
5281 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].acct_flags,
5282 info->info21.acct_flags, info->info21.account_name);
5286 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].account_name,
5287 info->info21.account_name, info->info21.account_name);
5288 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].description,
5289 info->info21.description, info->info21.account_name);
5290 INT_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].rid,
5291 info->info21.rid, info->info21.account_name);
5292 INT_EQUAL_QUERY((querydisplayinfo->out.info->info2.entries[i].acct_flags & ~ACB_NORMAL),
5293 info->info21.acct_flags, info->info21.account_name);
5295 if (!(querydisplayinfo->out.info->info2.entries[i].acct_flags & ACB_NORMAL)) {
5296 torture_warning(tctx, "Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
5297 info->info21.account_name.string);
5300 if (!(info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
5301 torture_warning(tctx, "Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
5302 info->info21.account_name.string,
5303 querydisplayinfo->out.info->info2.entries[i].acct_flags,
5304 info->info21.acct_flags);
5311 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
5318 static bool test_QueryDisplayInfo(struct dcerpc_pipe *p,
5319 struct torture_context *tctx,
5320 struct policy_handle *handle)
5323 struct samr_QueryDisplayInfo r;
5324 struct samr_QueryDomainInfo dom_info;
5325 union samr_DomainInfo *info = NULL;
5327 uint16_t levels[] = {1, 2, 3, 4, 5};
5329 bool seen_testuser = false;
5330 uint32_t total_size;
5331 uint32_t returned_size;
5332 union samr_DispInfo disp_info;
5335 for (i=0;i<ARRAY_SIZE(levels);i++) {
5336 torture_comment(tctx, "Testing QueryDisplayInfo level %u\n", levels[i]);
5339 status = STATUS_MORE_ENTRIES;
5340 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
5341 r.in.domain_handle = handle;
5342 r.in.level = levels[i];
5343 r.in.max_entries = 2;
5344 r.in.buf_size = (uint32_t)-1;
5345 r.out.total_size = &total_size;
5346 r.out.returned_size = &returned_size;
5347 r.out.info = &disp_info;
5349 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &r);
5350 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(status)) {
5351 torture_warning(tctx, "QueryDisplayInfo level %u failed - %s\n",
5352 levels[i], nt_errstr(status));
5355 switch (r.in.level) {
5357 if (!test_each_DisplayInfo_user(p, tctx, &r, &seen_testuser)) {
5360 r.in.start_idx += r.out.info->info1.count;
5363 if (!test_each_DisplayInfo_user(p, tctx, &r, NULL)) {
5366 r.in.start_idx += r.out.info->info2.count;
5369 r.in.start_idx += r.out.info->info3.count;
5372 r.in.start_idx += r.out.info->info4.count;
5375 r.in.start_idx += r.out.info->info5.count;
5379 dom_info.in.domain_handle = handle;
5380 dom_info.in.level = 2;
5381 dom_info.out.info = &info;
5383 /* Check number of users returned is correct */
5384 status = dcerpc_samr_QueryDomainInfo(p, tctx, &dom_info);
5385 if (!NT_STATUS_IS_OK(status)) {
5386 torture_warning(tctx, "QueryDomainInfo level %u failed - %s\n",
5387 r.in.level, nt_errstr(status));
5391 switch (r.in.level) {
5394 if (info->general.num_users < r.in.start_idx) {
5395 torture_warning(tctx, "QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
5396 r.in.start_idx, info->general.num_groups,
5397 info->general.domain_name.string);
5400 if (!seen_testuser) {
5401 struct policy_handle user_handle;
5402 if (NT_STATUS_IS_OK(test_OpenUser_byname(p, tctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
5403 torture_warning(tctx, "Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
5404 info->general.domain_name.string);
5406 test_samr_handle_Close(p, tctx, &user_handle);
5412 if (info->general.num_groups != r.in.start_idx) {
5413 torture_warning(tctx, "QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
5414 r.in.start_idx, info->general.num_groups,
5415 info->general.domain_name.string);
5427 static bool test_QueryDisplayInfo2(struct dcerpc_pipe *p,
5428 struct torture_context *tctx,
5429 struct policy_handle *handle)
5432 struct samr_QueryDisplayInfo2 r;
5434 uint16_t levels[] = {1, 2, 3, 4, 5};
5436 uint32_t total_size;
5437 uint32_t returned_size;
5438 union samr_DispInfo info;
5440 for (i=0;i<ARRAY_SIZE(levels);i++) {
5441 torture_comment(tctx, "Testing QueryDisplayInfo2 level %u\n", levels[i]);
5443 r.in.domain_handle = handle;
5444 r.in.level = levels[i];
5446 r.in.max_entries = 1000;
5447 r.in.buf_size = (uint32_t)-1;
5448 r.out.total_size = &total_size;
5449 r.out.returned_size = &returned_size;
5452 status = dcerpc_samr_QueryDisplayInfo2(p, tctx, &r);
5453 if (!NT_STATUS_IS_OK(status)) {
5454 torture_warning(tctx, "QueryDisplayInfo2 level %u failed - %s\n",
5455 levels[i], nt_errstr(status));
5463 static bool test_QueryDisplayInfo3(struct dcerpc_pipe *p, struct torture_context *tctx,
5464 struct policy_handle *handle)
5467 struct samr_QueryDisplayInfo3 r;
5469 uint16_t levels[] = {1, 2, 3, 4, 5};
5471 uint32_t total_size;
5472 uint32_t returned_size;
5473 union samr_DispInfo info;
5475 for (i=0;i<ARRAY_SIZE(levels);i++) {
5476 torture_comment(tctx, "Testing QueryDisplayInfo3 level %u\n", levels[i]);
5478 r.in.domain_handle = handle;
5479 r.in.level = levels[i];
5481 r.in.max_entries = 1000;
5482 r.in.buf_size = (uint32_t)-1;
5483 r.out.total_size = &total_size;
5484 r.out.returned_size = &returned_size;
5487 status = dcerpc_samr_QueryDisplayInfo3(p, tctx, &r);
5488 if (!NT_STATUS_IS_OK(status)) {
5489 torture_warning(tctx, "QueryDisplayInfo3 level %u failed - %s\n",
5490 levels[i], nt_errstr(status));
5499 static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p,
5500 struct torture_context *tctx,
5501 struct policy_handle *handle)
5504 struct samr_QueryDisplayInfo r;
5506 uint32_t total_size;
5507 uint32_t returned_size;
5508 union samr_DispInfo info;
5510 torture_comment(tctx, "Testing QueryDisplayInfo continuation\n");
5512 r.in.domain_handle = handle;
5515 r.in.max_entries = 1;
5516 r.in.buf_size = (uint32_t)-1;
5517 r.out.total_size = &total_size;
5518 r.out.returned_size = &returned_size;
5522 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &r);
5523 if (NT_STATUS_IS_OK(status) && *r.out.returned_size != 0) {
5524 if (r.out.info->info1.entries[0].idx != r.in.start_idx + 1) {
5525 torture_warning(tctx, "expected idx %d but got %d\n",
5527 r.out.info->info1.entries[0].idx);
5531 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
5532 !NT_STATUS_IS_OK(status)) {
5533 torture_warning(tctx, "QueryDisplayInfo level %u failed - %s\n",
5534 r.in.level, nt_errstr(status));
5539 } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
5540 NT_STATUS_IS_OK(status)) &&
5541 *r.out.returned_size != 0);
5546 static bool test_QueryDomainInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
5547 struct policy_handle *handle)
5550 struct samr_QueryDomainInfo r;
5551 union samr_DomainInfo *info = NULL;
5552 struct samr_SetDomainInfo s;
5553 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
5554 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
5557 const char *domain_comment = talloc_asprintf(tctx,
5558 "Tortured by Samba4 RPC-SAMR: %s",
5559 timestring(tctx, time(NULL)));
5561 s.in.domain_handle = handle;
5563 s.in.info = talloc(tctx, union samr_DomainInfo);
5565 s.in.info->oem.oem_information.string = domain_comment;
5566 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
5567 if (!NT_STATUS_IS_OK(status)) {
5568 torture_warning(tctx, "SetDomainInfo level %u (set comment) failed - %s\n",
5569 s.in.level, nt_errstr(status));
5573 for (i=0;i<ARRAY_SIZE(levels);i++) {
5574 torture_comment(tctx, "Testing QueryDomainInfo level %u\n", levels[i]);
5576 r.in.domain_handle = handle;
5577 r.in.level = levels[i];
5580 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
5581 if (!NT_STATUS_IS_OK(status)) {
5582 torture_warning(tctx, "QueryDomainInfo level %u failed - %s\n",
5583 r.in.level, nt_errstr(status));
5588 switch (levels[i]) {
5590 if (strcmp(info->general.oem_information.string, domain_comment) != 0) {
5591 torture_warning(tctx, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
5592 levels[i], info->general.oem_information.string, domain_comment);
5593 if (!torture_setting_bool(tctx, "samba3", false)) {
5597 if (!info->general.primary.string) {
5598 torture_warning(tctx, "QueryDomainInfo level %u returned no PDC name\n",
5601 } else if (info->general.role == SAMR_ROLE_DOMAIN_PDC) {
5602 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), info->general.primary.string) != 0) {
5603 torture_warning(tctx, "QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
5604 levels[i], info->general.primary.string, dcerpc_server_name(p));
5609 if (strcmp(info->oem.oem_information.string, domain_comment) != 0) {
5610 torture_warning(tctx, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
5611 levels[i], info->oem.oem_information.string, domain_comment);
5612 if (!torture_setting_bool(tctx, "samba3", false)) {
5618 if (!info->info6.primary.string) {
5619 torture_warning(tctx, "QueryDomainInfo level %u returned no PDC name\n",
5625 if (strcmp(info->general2.general.oem_information.string, domain_comment) != 0) {
5626 torture_warning(tctx, "QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
5627 levels[i], info->general2.general.oem_information.string, domain_comment);
5628 if (!torture_setting_bool(tctx, "samba3", false)) {
5635 torture_comment(tctx, "Testing SetDomainInfo level %u\n", levels[i]);
5637 s.in.domain_handle = handle;
5638 s.in.level = levels[i];
5641 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
5643 if (!NT_STATUS_IS_OK(status)) {
5644 torture_warning(tctx, "SetDomainInfo level %u failed - %s\n",
5645 r.in.level, nt_errstr(status));
5650 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
5651 torture_warning(tctx, "SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
5652 r.in.level, nt_errstr(status));
5658 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
5659 if (!NT_STATUS_IS_OK(status)) {
5660 torture_warning(tctx, "QueryDomainInfo level %u failed - %s\n",
5661 r.in.level, nt_errstr(status));
5671 static bool test_QueryDomainInfo2(struct dcerpc_pipe *p, struct torture_context *tctx,
5672 struct policy_handle *handle)
5675 struct samr_QueryDomainInfo2 r;
5676 union samr_DomainInfo *info = NULL;
5677 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
5681 for (i=0;i<ARRAY_SIZE(levels);i++) {
5682 torture_comment(tctx, "Testing QueryDomainInfo2 level %u\n", levels[i]);
5684 r.in.domain_handle = handle;
5685 r.in.level = levels[i];
5688 status = dcerpc_samr_QueryDomainInfo2(p, tctx, &r);
5689 if (!NT_STATUS_IS_OK(status)) {
5690 torture_warning(tctx, "QueryDomainInfo2 level %u failed - %s\n",
5691 r.in.level, nt_errstr(status));
5700 /* Test whether querydispinfo level 5 and enumdomgroups return the same
5701 set of group names. */
5702 static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx,
5703 struct policy_handle *handle)
5705 struct samr_EnumDomainGroups q1;
5706 struct samr_QueryDisplayInfo q2;
5708 uint32_t resume_handle=0;
5709 struct samr_SamArray *sam = NULL;
5710 uint32_t num_entries = 0;
5713 uint32_t total_size;
5714 uint32_t returned_size;
5715 union samr_DispInfo info;
5718 const char **names = NULL;
5720 torture_comment(tctx, "Testing coherency of querydispinfo vs enumdomgroups\n");
5722 q1.in.domain_handle = handle;
5723 q1.in.resume_handle = &resume_handle;
5725 q1.out.resume_handle = &resume_handle;
5726 q1.out.num_entries = &num_entries;
5729 status = STATUS_MORE_ENTRIES;
5730 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
5731 status = dcerpc_samr_EnumDomainGroups(p, tctx, &q1);
5733 if (!NT_STATUS_IS_OK(status) &&
5734 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
5737 for (i=0; i<*q1.out.num_entries; i++) {
5738 add_string_to_array(tctx,
5739 sam->entries[i].name.string,
5740 &names, &num_names);
5744 torture_assert_ntstatus_ok(tctx, status, "EnumDomainGroups");
5746 torture_assert(tctx, sam, "EnumDomainGroups failed to return sam");
5748 q2.in.domain_handle = handle;
5750 q2.in.start_idx = 0;
5751 q2.in.max_entries = 5;
5752 q2.in.buf_size = (uint32_t)-1;
5753 q2.out.total_size = &total_size;
5754 q2.out.returned_size = &returned_size;
5755 q2.out.info = &info;
5757 status = STATUS_MORE_ENTRIES;
5758 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
5759 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &q2);
5761 if (!NT_STATUS_IS_OK(status) &&
5762 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
5765 for (i=0; i<q2.out.info->info5.count; i++) {
5767 const char *name = q2.out.info->info5.entries[i].account_name.string;
5769 for (j=0; j<num_names; j++) {
5770 if (names[j] == NULL)
5772 if (strequal(names[j], name)) {
5780 torture_warning(tctx, "QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
5785 q2.in.start_idx += q2.out.info->info5.count;
5788 if (!NT_STATUS_IS_OK(status)) {
5789 torture_warning(tctx, "QueryDisplayInfo level 5 failed - %s\n",
5794 for (i=0; i<num_names; i++) {
5795 if (names[i] != NULL) {
5796 torture_warning(tctx, "EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
5805 static bool test_DeleteDomainGroup(struct dcerpc_pipe *p, struct torture_context *tctx,
5806 struct policy_handle *group_handle)
5808 struct samr_DeleteDomainGroup d;
5811 torture_comment(tctx, "Testing DeleteDomainGroup\n");
5813 d.in.group_handle = group_handle;
5814 d.out.group_handle = group_handle;
5816 status = dcerpc_samr_DeleteDomainGroup(p, tctx, &d);
5817 torture_assert_ntstatus_ok(tctx, status, "DeleteDomainGroup");
5822 static bool test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
5823 struct policy_handle *domain_handle)
5825 struct samr_TestPrivateFunctionsDomain r;
5829 torture_comment(tctx, "Testing TestPrivateFunctionsDomain\n");
5831 r.in.domain_handle = domain_handle;
5833 status = dcerpc_samr_TestPrivateFunctionsDomain(p, tctx, &r);
5834 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsDomain");
5839 static bool test_RidToSid(struct dcerpc_pipe *p, struct torture_context *tctx,
5840 struct dom_sid *domain_sid,
5841 struct policy_handle *domain_handle)
5843 struct samr_RidToSid r;
5846 struct dom_sid *calc_sid, *out_sid;
5847 int rids[] = { 0, 42, 512, 10200 };
5850 for (i=0;i<ARRAY_SIZE(rids);i++) {
5851 torture_comment(tctx, "Testing RidToSid\n");
5853 calc_sid = dom_sid_dup(tctx, domain_sid);
5854 r.in.domain_handle = domain_handle;
5856 r.out.sid = &out_sid;
5858 status = dcerpc_samr_RidToSid(p, tctx, &r);
5859 if (!NT_STATUS_IS_OK(status)) {
5860 torture_warning(tctx, "RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
5863 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
5865 if (!dom_sid_equal(calc_sid, out_sid)) {
5866 torture_warning(tctx, "RidToSid for %d failed - got %s, expected %s\n", rids[i],
5867 dom_sid_string(tctx, out_sid),
5868 dom_sid_string(tctx, calc_sid));
5877 static bool test_GetBootKeyInformation(struct dcerpc_pipe *p, struct torture_context *tctx,
5878 struct policy_handle *domain_handle)
5880 struct samr_GetBootKeyInformation r;
5883 uint32_t unknown = 0;
5885 torture_comment(tctx, "Testing GetBootKeyInformation\n");
5887 r.in.domain_handle = domain_handle;
5888 r.out.unknown = &unknown;
5890 status = dcerpc_samr_GetBootKeyInformation(p, tctx, &r);
5891 if (!NT_STATUS_IS_OK(status)) {
5892 /* w2k3 seems to fail this sometimes and pass it sometimes */
5893 torture_comment(tctx, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
5899 static bool test_AddGroupMember(struct dcerpc_pipe *p, struct torture_context *tctx,
5900 struct policy_handle *domain_handle,
5901 struct policy_handle *group_handle)
5904 struct samr_AddGroupMember r;
5905 struct samr_DeleteGroupMember d;
5906 struct samr_QueryGroupMember q;
5907 struct samr_RidTypeArray *rids = NULL;
5908 struct samr_SetMemberAttributesOfGroup s;
5910 bool found_member = false;
5913 status = test_LookupName(p, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
5914 torture_assert_ntstatus_ok(tctx, status, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME);
5916 r.in.group_handle = group_handle;
5918 r.in.flags = 0; /* ??? */
5920 torture_comment(tctx, "Testing AddGroupMember, QueryGroupMember and DeleteGroupMember\n");
5922 d.in.group_handle = group_handle;
5925 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
5926 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_NOT_IN_GROUP, status, "DeleteGroupMember");
5928 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5929 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
5931 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5932 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_IN_GROUP, status, "AddGroupMember");
5934 if (torture_setting_bool(tctx, "samba4", false) ||
5935 torture_setting_bool(tctx, "samba3", false)) {
5936 torture_comment(tctx, "skipping SetMemberAttributesOfGroup test against Samba\n");
5938 /* this one is quite strange. I am using random inputs in the
5939 hope of triggering an error that might give us a clue */
5941 s.in.group_handle = group_handle;
5942 s.in.unknown1 = random();
5943 s.in.unknown2 = random();
5945 status = dcerpc_samr_SetMemberAttributesOfGroup(p, tctx, &s);
5946 torture_assert_ntstatus_ok(tctx, status, "SetMemberAttributesOfGroup");
5949 q.in.group_handle = group_handle;
5952 status = dcerpc_samr_QueryGroupMember(p, tctx, &q);
5953 torture_assert_ntstatus_ok(tctx, status, "QueryGroupMember");
5954 torture_assert(tctx, rids, "QueryGroupMember did not fill in rids structure");
5956 for (i=0; i < rids->count; i++) {
5957 if (rids->rids[i] == rid) {
5958 found_member = true;
5962 torture_assert(tctx, found_member, "QueryGroupMember did not list newly added member");
5964 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
5965 torture_assert_ntstatus_ok(tctx, status, "DeleteGroupMember");
5968 found_member = false;
5970 status = dcerpc_samr_QueryGroupMember(p, tctx, &q);
5971 torture_assert_ntstatus_ok(tctx, status, "QueryGroupMember");
5972 torture_assert(tctx, rids, "QueryGroupMember did not fill in rids structure");
5974 for (i=0; i < rids->count; i++) {
5975 if (rids->rids[i] == rid) {
5976 found_member = true;
5980 torture_assert(tctx, !found_member, "QueryGroupMember does still list removed member");
5982 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5983 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
5989 static bool test_CreateDomainGroup(struct dcerpc_pipe *p,
5990 struct torture_context *tctx,
5991 struct policy_handle *domain_handle,
5992 const char *group_name,
5993 struct policy_handle *group_handle,
5994 struct dom_sid *domain_sid,
5998 struct samr_CreateDomainGroup r;
6000 struct lsa_String name;
6003 init_lsa_String(&name, group_name);
6005 r.in.domain_handle = domain_handle;
6007 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6008 r.out.group_handle = group_handle;
6011 torture_comment(tctx, "Testing CreateDomainGroup(%s)\n", r.in.name->string);
6013 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
6015 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
6016 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
6017 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.name->string);
6020 torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.name->string,
6026 if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS)) {
6027 if (!test_DeleteGroup_byname(p, tctx, domain_handle, r.in.name->string)) {
6028 torture_warning(tctx, "CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
6032 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
6034 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
6035 if (!test_DeleteUser_byname(p, tctx, domain_handle, r.in.name->string)) {
6037 torture_warning(tctx, "CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
6041 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
6043 torture_assert_ntstatus_ok(tctx, status, "CreateDomainGroup");
6049 if (!test_AddGroupMember(p, tctx, domain_handle, group_handle)) {
6050 torture_warning(tctx, "CreateDomainGroup failed - %s\n", nt_errstr(status));
6054 if (!test_SetGroupInfo(p, tctx, group_handle)) {
6063 its not totally clear what this does. It seems to accept any sid you like.
6065 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p,
6066 struct torture_context *tctx,
6067 struct policy_handle *domain_handle)
6070 struct samr_RemoveMemberFromForeignDomain r;
6072 r.in.domain_handle = domain_handle;
6073 r.in.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-12-34-56-78");
6075 status = dcerpc_samr_RemoveMemberFromForeignDomain(p, tctx, &r);
6076 torture_assert_ntstatus_ok(tctx, status, "RemoveMemberFromForeignDomain");
6081 static bool test_EnumDomainUsers(struct dcerpc_pipe *p,
6082 struct torture_context *tctx,
6083 struct policy_handle *domain_handle,
6084 uint32_t *total_num_entries_p)
6087 struct samr_EnumDomainUsers r;
6088 uint32_t resume_handle = 0;
6089 uint32_t num_entries = 0;
6090 uint32_t total_num_entries = 0;
6091 struct samr_SamArray *sam;
6093 r.in.domain_handle = domain_handle;
6094 r.in.acct_flags = 0;
6095 r.in.max_size = (uint32_t)-1;
6096 r.in.resume_handle = &resume_handle;
6099 r.out.num_entries = &num_entries;
6100 r.out.resume_handle = &resume_handle;
6102 torture_comment(tctx, "Testing EnumDomainUsers\n");
6105 status = dcerpc_samr_EnumDomainUsers(p, tctx, &r);
6106 if (NT_STATUS_IS_ERR(status)) {
6107 torture_assert_ntstatus_ok(tctx, status,
6108 "failed to enumerate users");
6111 total_num_entries += num_entries;
6112 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
6114 if (total_num_entries_p) {
6115 *total_num_entries_p = total_num_entries;
6121 static bool test_EnumDomainGroups(struct dcerpc_pipe *p,
6122 struct torture_context *tctx,
6123 struct policy_handle *domain_handle,
6124 uint32_t *total_num_entries_p)
6127 struct samr_EnumDomainGroups r;
6128 uint32_t resume_handle = 0;
6129 uint32_t num_entries = 0;
6130 uint32_t total_num_entries = 0;
6131 struct samr_SamArray *sam;
6133 r.in.domain_handle = domain_handle;
6134 r.in.max_size = (uint32_t)-1;
6135 r.in.resume_handle = &resume_handle;
6138 r.out.num_entries = &num_entries;
6139 r.out.resume_handle = &resume_handle;
6141 torture_comment(tctx, "Testing EnumDomainGroups\n");
6144 status = dcerpc_samr_EnumDomainGroups(p, tctx, &r);
6145 if (NT_STATUS_IS_ERR(status)) {
6146 torture_assert_ntstatus_ok(tctx, status,
6147 "failed to enumerate groups");
6150 total_num_entries += num_entries;
6151 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
6153 if (total_num_entries_p) {
6154 *total_num_entries_p = total_num_entries;
6160 static bool test_EnumDomainAliases(struct dcerpc_pipe *p,
6161 struct torture_context *tctx,
6162 struct policy_handle *domain_handle,
6163 uint32_t *total_num_entries_p)
6166 struct samr_EnumDomainAliases r;
6167 uint32_t resume_handle = 0;
6168 uint32_t num_entries = 0;
6169 uint32_t total_num_entries = 0;
6170 struct samr_SamArray *sam;
6172 r.in.domain_handle = domain_handle;
6173 r.in.max_size = (uint32_t)-1;
6174 r.in.resume_handle = &resume_handle;
6177 r.out.num_entries = &num_entries;
6178 r.out.resume_handle = &resume_handle;
6180 torture_comment(tctx, "Testing EnumDomainAliases\n");
6183 status = dcerpc_samr_EnumDomainAliases(p, tctx, &r);
6184 if (NT_STATUS_IS_ERR(status)) {
6185 torture_assert_ntstatus_ok(tctx, status,
6186 "failed to enumerate aliases");
6189 total_num_entries += num_entries;
6190 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
6192 if (total_num_entries_p) {
6193 *total_num_entries_p = total_num_entries;
6199 static bool test_QueryDisplayInfo_level(struct dcerpc_pipe *p,
6200 struct torture_context *tctx,
6201 struct policy_handle *handle,
6203 uint32_t *total_num_entries_p)
6206 struct samr_QueryDisplayInfo r;
6207 uint32_t total_num_entries = 0;
6209 r.in.domain_handle = handle;
6212 r.in.max_entries = (uint32_t)-1;
6213 r.in.buf_size = (uint32_t)-1;
6215 torture_comment(tctx, "Testing QueryDisplayInfo\n");
6218 uint32_t total_size;
6219 uint32_t returned_size;
6220 union samr_DispInfo info;
6222 r.out.total_size = &total_size;
6223 r.out.returned_size = &returned_size;
6226 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &r);
6227 if (NT_STATUS_IS_ERR(status)) {
6228 torture_assert_ntstatus_ok(tctx, status,
6229 "failed to query displayinfo");
6232 if (*r.out.returned_size == 0) {
6236 switch (r.in.level) {
6238 total_num_entries += info.info1.count;
6239 r.in.start_idx += info.info1.entries[info.info1.count - 1].idx + 1;
6242 total_num_entries += info.info2.count;
6243 r.in.start_idx += info.info2.entries[info.info2.count - 1].idx + 1;
6246 total_num_entries += info.info3.count;
6247 r.in.start_idx += info.info3.entries[info.info3.count - 1].idx + 1;
6250 total_num_entries += info.info4.count;
6251 r.in.start_idx += info.info4.entries[info.info4.count - 1].idx + 1;
6254 total_num_entries += info.info5.count;
6255 r.in.start_idx += info.info5.entries[info.info5.count - 1].idx + 1;
6261 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
6263 if (total_num_entries_p) {
6264 *total_num_entries_p = total_num_entries;
6270 static bool test_ManyObjects(struct dcerpc_pipe *p,
6271 struct torture_context *tctx,
6272 struct policy_handle *domain_handle,
6273 struct dom_sid *domain_sid,
6274 enum torture_samr_choice which_ops)
6276 uint32_t num_total = 1500;
6277 uint32_t num_enum = 0;
6278 uint32_t num_disp = 0;
6279 uint32_t num_created = 0;
6280 uint32_t num_anounced = 0;
6285 struct policy_handle *handles = talloc_zero_array(tctx, struct policy_handle, num_total);
6290 struct samr_QueryDomainInfo2 r;
6291 union samr_DomainInfo *info;
6292 r.in.domain_handle = domain_handle;
6296 status = dcerpc_samr_QueryDomainInfo2(p, tctx, &r);
6297 torture_assert_ntstatus_ok(tctx, status,
6298 "failed to query domain info");
6300 switch (which_ops) {
6301 case TORTURE_SAMR_MANY_ACCOUNTS:
6302 num_anounced = info->general.num_users;
6304 case TORTURE_SAMR_MANY_GROUPS:
6305 num_anounced = info->general.num_groups;
6307 case TORTURE_SAMR_MANY_ALIASES:
6308 num_anounced = info->general.num_aliases;
6317 for (i=0; i < num_total; i++) {
6319 const char *name = NULL;
6321 switch (which_ops) {
6322 case TORTURE_SAMR_MANY_ACCOUNTS:
6323 name = talloc_asprintf(tctx, "%s%04d", TEST_ACCOUNT_NAME, i);
6324 ret &= test_CreateUser(p, tctx, domain_handle, name, &handles[i], domain_sid, 0, NULL, false);
6326 case TORTURE_SAMR_MANY_GROUPS:
6327 name = talloc_asprintf(tctx, "%s%04d", TEST_GROUPNAME, i);
6328 ret &= test_CreateDomainGroup(p, tctx, domain_handle, name, &handles[i], domain_sid, false);
6330 case TORTURE_SAMR_MANY_ALIASES:
6331 name = talloc_asprintf(tctx, "%s%04d", TEST_ALIASNAME, i);
6332 ret &= test_CreateAlias(p, tctx, domain_handle, name, &handles[i], domain_sid, false);
6337 if (!policy_handle_empty(&handles[i])) {
6344 switch (which_ops) {
6345 case TORTURE_SAMR_MANY_ACCOUNTS:
6346 ret &= test_EnumDomainUsers(p, tctx, domain_handle, &num_enum);
6348 case TORTURE_SAMR_MANY_GROUPS:
6349 ret &= test_EnumDomainGroups(p, tctx, domain_handle, &num_enum);
6351 case TORTURE_SAMR_MANY_ALIASES:
6352 ret &= test_EnumDomainAliases(p, tctx, domain_handle, &num_enum);
6360 switch (which_ops) {
6361 case TORTURE_SAMR_MANY_ACCOUNTS:
6362 ret &= test_QueryDisplayInfo_level(p, tctx, domain_handle, 1, &num_disp);
6364 case TORTURE_SAMR_MANY_GROUPS:
6365 ret &= test_QueryDisplayInfo_level(p, tctx, domain_handle, 3, &num_disp);
6367 case TORTURE_SAMR_MANY_ALIASES:
6368 /* no aliases in dispinfo */
6374 /* close or delete */
6376 for (i=0; i < num_total; i++) {
6378 if (policy_handle_empty(&handles[i])) {
6382 if (torture_setting_bool(tctx, "samba3", false)) {
6383 ret &= test_samr_handle_Close(p, tctx, &handles[i]);
6385 switch (which_ops) {
6386 case TORTURE_SAMR_MANY_ACCOUNTS:
6387 ret &= test_DeleteUser(p, tctx, &handles[i]);
6389 case TORTURE_SAMR_MANY_GROUPS:
6390 ret &= test_DeleteDomainGroup(p, tctx, &handles[i]);
6392 case TORTURE_SAMR_MANY_ALIASES:
6393 ret &= test_DeleteAlias(p, tctx, &handles[i]);
6401 talloc_free(handles);
6403 if (which_ops == TORTURE_SAMR_MANY_ACCOUNTS && num_enum != num_anounced + num_created) {
6404 torture_comment(tctx,
6405 "unexpected number of results (%u) returned in enum call, expected %u\n",
6406 num_enum, num_anounced + num_created);
6408 torture_comment(tctx,
6409 "unexpected number of results (%u) returned in dispinfo, call, expected %u\n",
6410 num_disp, num_anounced + num_created);
6415 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
6416 struct policy_handle *handle);
6418 static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
6419 struct policy_handle *handle, struct dom_sid *sid,
6420 enum torture_samr_choice which_ops,
6421 struct cli_credentials *machine_credentials)
6424 struct samr_OpenDomain r;
6425 struct policy_handle domain_handle;
6426 struct policy_handle alias_handle;
6427 struct policy_handle user_handle;
6428 struct policy_handle group_handle;
6431 ZERO_STRUCT(alias_handle);
6432 ZERO_STRUCT(user_handle);
6433 ZERO_STRUCT(group_handle);
6434 ZERO_STRUCT(domain_handle);
6436 torture_comment(tctx, "Testing OpenDomain of %s\n", dom_sid_string(tctx, sid));
6438 r.in.connect_handle = handle;
6439 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6441 r.out.domain_handle = &domain_handle;
6443 status = dcerpc_samr_OpenDomain(p, tctx, &r);
6444 torture_assert_ntstatus_ok(tctx, status, "OpenDomain");
6446 /* run the domain tests with the main handle closed - this tests
6447 the servers reference counting */
6448 torture_assert(tctx, test_samr_handle_Close(p, tctx, handle), "Failed to close SAMR handle");
6450 switch (which_ops) {
6451 case TORTURE_SAMR_PASSWORDS:
6452 case TORTURE_SAMR_USER_PRIVILEGES:
6453 if (!torture_setting_bool(tctx, "samba3", false)) {
6454 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops, NULL);
6456 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, which_ops, NULL, true);
6458 torture_warning(tctx, "Testing PASSWORDS or PRIVILAGES on domain %s failed!\n", dom_sid_string(tctx, sid));
6461 case TORTURE_SAMR_USER_ATTRIBUTES:
6462 if (!torture_setting_bool(tctx, "samba3", false)) {
6463 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops, NULL);
6465 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, which_ops, NULL, true);
6466 /* This test needs 'complex' users to validate */
6467 ret &= test_QueryDisplayInfo(p, tctx, &domain_handle);
6469 torture_warning(tctx, "Testing ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
6472 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
6473 if (!torture_setting_bool(tctx, "samba3", false)) {
6474 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops, machine_credentials);
6476 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, which_ops, machine_credentials, true);
6478 torture_warning(tctx, "Testing PASSWORDS PWDLASTSET on domain %s failed!\n", dom_sid_string(tctx, sid));
6481 case TORTURE_SAMR_MANY_ACCOUNTS:
6482 case TORTURE_SAMR_MANY_GROUPS:
6483 case TORTURE_SAMR_MANY_ALIASES:
6484 ret &= test_ManyObjects(p, tctx, &domain_handle, sid, which_ops);
6486 torture_warning(tctx, "Testing MANY-{ACCOUNTS,GROUPS,ALIASES} on domain %s failed!\n", dom_sid_string(tctx, sid));
6489 case TORTURE_SAMR_OTHER:
6490 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, which_ops, NULL, true);
6492 torture_warning(tctx, "Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid));
6494 if (!torture_setting_bool(tctx, "samba3", false)) {
6495 ret &= test_QuerySecurity(p, tctx, &domain_handle);
6497 ret &= test_RemoveMemberFromForeignDomain(p, tctx, &domain_handle);
6498 ret &= test_CreateAlias(p, tctx, &domain_handle, TEST_ALIASNAME, &alias_handle, sid, true);
6499 ret &= test_CreateDomainGroup(p, tctx, &domain_handle, TEST_GROUPNAME, &group_handle, sid, true);
6500 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
6501 ret &= test_QueryDomainInfo2(p, tctx, &domain_handle);
6502 ret &= test_EnumDomainUsers_all(p, tctx, &domain_handle);
6503 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
6504 ret &= test_EnumDomainGroups_all(p, tctx, &domain_handle);
6505 ret &= test_EnumDomainAliases_all(p, tctx, &domain_handle);
6506 ret &= test_QueryDisplayInfo2(p, tctx, &domain_handle);
6507 ret &= test_QueryDisplayInfo3(p, tctx, &domain_handle);
6508 ret &= test_QueryDisplayInfo_continue(p, tctx, &domain_handle);
6510 if (torture_setting_bool(tctx, "samba4", false)) {
6511 torture_comment(tctx, "skipping GetDisplayEnumerationIndex test against Samba4\n");
6513 ret &= test_GetDisplayEnumerationIndex(p, tctx, &domain_handle);
6514 ret &= test_GetDisplayEnumerationIndex2(p, tctx, &domain_handle);
6516 ret &= test_GroupList(p, tctx, &domain_handle);
6517 ret &= test_TestPrivateFunctionsDomain(p, tctx, &domain_handle);
6518 ret &= test_RidToSid(p, tctx, sid, &domain_handle);
6519 ret &= test_GetBootKeyInformation(p, tctx, &domain_handle);
6521 torture_comment(tctx, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx, sid));
6526 if (!policy_handle_empty(&user_handle) &&
6527 !test_DeleteUser(p, tctx, &user_handle)) {
6531 if (!policy_handle_empty(&alias_handle) &&
6532 !test_DeleteAlias(p, tctx, &alias_handle)) {
6536 if (!policy_handle_empty(&group_handle) &&
6537 !test_DeleteDomainGroup(p, tctx, &group_handle)) {
6541 torture_assert(tctx, test_samr_handle_Close(p, tctx, &domain_handle), "Failed to close SAMR domain handle");
6543 torture_assert(tctx, test_Connect(p, tctx, handle), "Faile to re-connect SAMR handle");
6544 /* reconnect the main handle */
6547 torture_warning(tctx, "Testing domain %s failed!\n", dom_sid_string(tctx, sid));
6553 static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
6554 struct policy_handle *handle, const char *domain,
6555 enum torture_samr_choice which_ops,
6556 struct cli_credentials *machine_credentials)
6559 struct samr_LookupDomain r;
6560 struct dom_sid2 *sid = NULL;
6561 struct lsa_String n1;
6562 struct lsa_String n2;
6565 torture_comment(tctx, "Testing LookupDomain(%s)\n", domain);
6567 /* check for correct error codes */
6568 r.in.connect_handle = handle;
6569 r.in.domain_name = &n2;
6573 status = dcerpc_samr_LookupDomain(p, tctx, &r);
6574 torture_assert_ntstatus_equal(tctx, NT_STATUS_INVALID_PARAMETER, status, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
6576 init_lsa_String(&n2, "xxNODOMAINxx");
6578 status = dcerpc_samr_LookupDomain(p, tctx, &r);
6579 torture_assert_ntstatus_equal(tctx, NT_STATUS_NO_SUCH_DOMAIN, status, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
6581 r.in.connect_handle = handle;
6583 init_lsa_String(&n1, domain);
6584 r.in.domain_name = &n1;
6586 status = dcerpc_samr_LookupDomain(p, tctx, &r);
6587 torture_assert_ntstatus_ok(tctx, status, "LookupDomain");
6589 if (!test_GetDomPwInfo(p, tctx, &n1)) {
6593 if (!test_OpenDomain(p, tctx, handle, *r.out.sid, which_ops,
6594 machine_credentials)) {
6602 static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
6603 struct policy_handle *handle, enum torture_samr_choice which_ops,
6604 struct cli_credentials *machine_credentials)
6607 struct samr_EnumDomains r;
6608 uint32_t resume_handle = 0;
6609 uint32_t num_entries = 0;
6610 struct samr_SamArray *sam = NULL;
6614 r.in.connect_handle = handle;
6615 r.in.resume_handle = &resume_handle;
6616 r.in.buf_size = (uint32_t)-1;
6617 r.out.resume_handle = &resume_handle;
6618 r.out.num_entries = &num_entries;
6621 status = dcerpc_samr_EnumDomains(p, tctx, &r);
6622 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
6628 for (i=0;i<sam->count;i++) {
6629 if (!test_LookupDomain(p, tctx, handle,
6630 sam->entries[i].name.string, which_ops,
6631 machine_credentials)) {
6636 status = dcerpc_samr_EnumDomains(p, tctx, &r);
6637 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
6643 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
6644 struct policy_handle *handle)
6647 struct samr_Connect r;
6648 struct samr_Connect2 r2;
6649 struct samr_Connect3 r3;
6650 struct samr_Connect4 r4;
6651 struct samr_Connect5 r5;
6652 union samr_ConnectInfo info;
6653 struct policy_handle h;
6654 uint32_t level_out = 0;
6655 bool ret = true, got_handle = false;
6657 torture_comment(tctx, "testing samr_Connect\n");
6659 r.in.system_name = 0;
6660 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6661 r.out.connect_handle = &h;
6663 status = dcerpc_samr_Connect(p, tctx, &r);
6664 if (!NT_STATUS_IS_OK(status)) {
6665 torture_comment(tctx, "Connect failed - %s\n", nt_errstr(status));
6672 torture_comment(tctx, "testing samr_Connect2\n");
6674 r2.in.system_name = NULL;
6675 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6676 r2.out.connect_handle = &h;
6678 status = dcerpc_samr_Connect2(p, tctx, &r2);
6679 if (!NT_STATUS_IS_OK(status)) {
6680 torture_comment(tctx, "Connect2 failed - %s\n", nt_errstr(status));
6684 test_samr_handle_Close(p, tctx, handle);
6690 torture_comment(tctx, "testing samr_Connect3\n");
6692 r3.in.system_name = NULL;
6694 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6695 r3.out.connect_handle = &h;
6697 status = dcerpc_samr_Connect3(p, tctx, &r3);
6698 if (!NT_STATUS_IS_OK(status)) {
6699 torture_warning(tctx, "Connect3 failed - %s\n", nt_errstr(status));
6703 test_samr_handle_Close(p, tctx, handle);
6709 torture_comment(tctx, "testing samr_Connect4\n");
6711 r4.in.system_name = "";
6712 r4.in.client_version = 0;
6713 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6714 r4.out.connect_handle = &h;
6716 status = dcerpc_samr_Connect4(p, tctx, &r4);
6717 if (!NT_STATUS_IS_OK(status)) {
6718 torture_warning(tctx, "Connect4 failed - %s\n", nt_errstr(status));
6722 test_samr_handle_Close(p, tctx, handle);
6728 torture_comment(tctx, "testing samr_Connect5\n");
6730 info.info1.client_version = 0;
6731 info.info1.unknown2 = 0;
6733 r5.in.system_name = "";
6734 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6736 r5.out.level_out = &level_out;
6737 r5.in.info_in = &info;
6738 r5.out.info_out = &info;
6739 r5.out.connect_handle = &h;
6741 status = dcerpc_samr_Connect5(p, tctx, &r5);
6742 if (!NT_STATUS_IS_OK(status)) {
6743 torture_warning(tctx, "Connect5 failed - %s\n", nt_errstr(status));
6747 test_samr_handle_Close(p, tctx, handle);
6757 static bool test_samr_ValidatePassword(struct dcerpc_pipe *p, struct torture_context *tctx)
6759 struct samr_ValidatePassword r;
6760 union samr_ValidatePasswordReq req;
6761 union samr_ValidatePasswordRep *repp = NULL;
6763 const char *passwords[] = { "penguin", "p@ssw0rd", "p@ssw0rd123$", NULL };
6767 r.in.level = NetValidatePasswordReset;
6772 req.req3.account.string = "non-existant-account-aklsdji";
6774 for (i=0; passwords[i]; i++) {
6775 req.req3.password.string = passwords[i];
6776 status = dcerpc_samr_ValidatePassword(p, tctx, &r);
6777 torture_assert_ntstatus_ok(tctx, status, "samr_ValidatePassword");
6778 torture_comment(tctx, "Server %s password '%s'\n",
6779 repp->ctr3.status==SAMR_VALIDATION_STATUS_SUCCESS?"allowed":"refused",
6780 req.req3.password.string);
6786 bool torture_rpc_samr(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_samr_ValidatePassword(p, torture);
6801 ret &= test_Connect(p, torture, &handle);
6803 if (!torture_setting_bool(torture, "samba3", false)) {
6804 ret &= test_QuerySecurity(p, torture, &handle);
6807 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_OTHER, NULL);
6809 ret &= test_SetDsrmPassword(p, torture, &handle);
6811 ret &= test_Shutdown(p, torture, &handle);
6813 ret &= test_samr_handle_Close(p, torture, &handle);
6819 bool torture_rpc_samr_users(struct torture_context *torture)
6822 struct dcerpc_pipe *p;
6824 struct policy_handle handle;
6826 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6827 if (!NT_STATUS_IS_OK(status)) {
6831 ret &= test_Connect(p, torture, &handle);
6833 if (!torture_setting_bool(torture, "samba3", false)) {
6834 ret &= test_QuerySecurity(p, torture, &handle);
6837 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_USER_ATTRIBUTES, NULL);
6839 ret &= test_SetDsrmPassword(p, torture, &handle);
6841 ret &= test_Shutdown(p, torture, &handle);
6843 ret &= test_samr_handle_Close(p, torture, &handle);
6849 bool torture_rpc_samr_passwords(struct torture_context *torture)
6852 struct dcerpc_pipe *p;
6854 struct policy_handle handle;
6856 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6857 if (!NT_STATUS_IS_OK(status)) {
6861 ret &= test_Connect(p, torture, &handle);
6863 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_PASSWORDS, NULL);
6865 ret &= test_samr_handle_Close(p, torture, &handle);
6870 static bool torture_rpc_samr_pwdlastset(struct torture_context *torture,
6871 struct dcerpc_pipe *p2,
6872 struct cli_credentials *machine_credentials)
6875 struct dcerpc_pipe *p;
6877 struct policy_handle handle;
6879 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6880 if (!NT_STATUS_IS_OK(status)) {
6884 ret &= test_Connect(p, torture, &handle);
6886 ret &= test_EnumDomains(p, torture, &handle,
6887 TORTURE_SAMR_PASSWORDS_PWDLASTSET,
6888 machine_credentials);
6890 ret &= test_samr_handle_Close(p, torture, &handle);
6895 struct torture_suite *torture_rpc_samr_passwords_pwdlastset(TALLOC_CTX *mem_ctx)
6897 struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-PASSWORDS-PWDLASTSET");
6898 struct torture_rpc_tcase *tcase;
6900 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
6902 TEST_ACCOUNT_NAME_PWD);
6904 torture_rpc_tcase_add_test_creds(tcase, "pwdLastSet",
6905 torture_rpc_samr_pwdlastset);
6910 static bool torture_rpc_samr_users_privileges_delete_user(struct torture_context *torture,
6911 struct dcerpc_pipe *p2,
6912 struct cli_credentials *machine_credentials)
6915 struct dcerpc_pipe *p;
6917 struct policy_handle handle;
6919 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6920 if (!NT_STATUS_IS_OK(status)) {
6924 ret &= test_Connect(p, torture, &handle);
6926 ret &= test_EnumDomains(p, torture, &handle,
6927 TORTURE_SAMR_USER_PRIVILEGES,
6928 machine_credentials);
6930 ret &= test_samr_handle_Close(p, torture, &handle);
6935 struct torture_suite *torture_rpc_samr_user_privileges(TALLOC_CTX *mem_ctx)
6937 struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-USERS-PRIVILEGES");
6938 struct torture_rpc_tcase *tcase;
6940 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
6942 TEST_ACCOUNT_NAME_PWD);
6944 torture_rpc_tcase_add_test_creds(tcase, "delete_privileged_user",
6945 torture_rpc_samr_users_privileges_delete_user);
6950 static bool torture_rpc_samr_many_accounts(struct torture_context *torture,
6951 struct dcerpc_pipe *p2,
6952 struct cli_credentials *machine_credentials)
6955 struct dcerpc_pipe *p;
6957 struct policy_handle handle;
6959 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6960 if (!NT_STATUS_IS_OK(status)) {
6964 ret &= test_Connect(p, torture, &handle);
6966 ret &= test_EnumDomains(p, torture, &handle,
6967 TORTURE_SAMR_MANY_ACCOUNTS,
6968 machine_credentials);
6970 ret &= test_samr_handle_Close(p, torture, &handle);
6975 static bool torture_rpc_samr_many_groups(struct torture_context *torture,
6976 struct dcerpc_pipe *p2,
6977 struct cli_credentials *machine_credentials)
6980 struct dcerpc_pipe *p;
6982 struct policy_handle handle;
6984 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6985 if (!NT_STATUS_IS_OK(status)) {
6989 ret &= test_Connect(p, torture, &handle);
6991 ret &= test_EnumDomains(p, torture, &handle,
6992 TORTURE_SAMR_MANY_GROUPS,
6993 machine_credentials);
6995 ret &= test_samr_handle_Close(p, torture, &handle);
7000 static bool torture_rpc_samr_many_aliases(struct torture_context *torture,
7001 struct dcerpc_pipe *p2,
7002 struct cli_credentials *machine_credentials)
7005 struct dcerpc_pipe *p;
7007 struct policy_handle handle;
7009 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
7010 if (!NT_STATUS_IS_OK(status)) {
7014 ret &= test_Connect(p, torture, &handle);
7016 ret &= test_EnumDomains(p, torture, &handle,
7017 TORTURE_SAMR_MANY_ALIASES,
7018 machine_credentials);
7020 ret &= test_samr_handle_Close(p, torture, &handle);
7025 struct torture_suite *torture_rpc_samr_large_dc(TALLOC_CTX *mem_ctx)
7027 struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-LARGE-DC");
7028 struct torture_rpc_tcase *tcase;
7030 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
7034 torture_rpc_tcase_add_test_creds(tcase, "many_aliases",
7035 torture_rpc_samr_many_aliases);
7036 torture_rpc_tcase_add_test_creds(tcase, "many_groups",
7037 torture_rpc_samr_many_groups);
7038 torture_rpc_tcase_add_test_creds(tcase, "many_accounts",
7039 torture_rpc_samr_many_accounts);