2 Unix SMB/CIFS implementation.
3 test suite for samr rpc operations
5 Copyright (C) Andrew Tridgell 2003
6 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "torture/torture.h"
24 #include "system/time.h"
25 #include "librpc/gen_ndr/lsa.h"
26 #include "librpc/gen_ndr/ndr_netlogon.h"
27 #include "librpc/gen_ndr/ndr_netlogon_c.h"
28 #include "librpc/gen_ndr/ndr_samr_c.h"
29 #include "../lib/crypto/crypto.h"
30 #include "libcli/auth/libcli_auth.h"
31 #include "libcli/security/security.h"
32 #include "torture/rpc/rpc.h"
33 #include "param/param.h"
37 #define TEST_ACCOUNT_NAME "samrtorturetest"
38 #define TEST_ACCOUNT_NAME_PWD "samrpwdlastset"
39 #define TEST_ALIASNAME "samrtorturetestalias"
40 #define TEST_GROUPNAME "samrtorturetestgroup"
41 #define TEST_MACHINENAME "samrtestmach$"
42 #define TEST_DOMAINNAME "samrtestdom$"
44 enum torture_samr_choice {
45 TORTURE_SAMR_PASSWORDS,
46 TORTURE_SAMR_PASSWORDS_PWDLASTSET,
47 TORTURE_SAMR_USER_ATTRIBUTES,
51 static bool test_QueryUserInfo(struct dcerpc_pipe *p,
52 struct torture_context *tctx,
53 struct policy_handle *handle);
55 static bool test_QueryUserInfo2(struct dcerpc_pipe *p,
56 struct torture_context *tctx,
57 struct policy_handle *handle);
59 static bool test_QueryAliasInfo(struct dcerpc_pipe *p,
60 struct torture_context *tctx,
61 struct policy_handle *handle);
63 static bool test_ChangePassword(struct dcerpc_pipe *p,
64 struct torture_context *tctx,
65 const char *acct_name,
66 struct policy_handle *domain_handle, char **password);
68 static void init_lsa_String(struct lsa_String *string, const char *s)
73 static void init_lsa_BinaryString(struct lsa_BinaryString *string, const char *s, uint32_t length)
75 string->length = length;
76 string->size = length;
77 string->array = (uint16_t *)discard_const(s);
80 bool test_samr_handle_Close(struct dcerpc_pipe *p, struct torture_context *tctx,
81 struct policy_handle *handle)
87 r.out.handle = handle;
89 status = dcerpc_samr_Close(p, tctx, &r);
90 torture_assert_ntstatus_ok(tctx, status, "Close");
95 static bool test_Shutdown(struct dcerpc_pipe *p, struct torture_context *tctx,
96 struct policy_handle *handle)
99 struct samr_Shutdown r;
101 if (!torture_setting_bool(tctx, "dangerous", false)) {
102 torture_skip(tctx, "samr_Shutdown disabled - enable dangerous tests to use\n");
106 r.in.connect_handle = handle;
108 torture_comment(tctx, "testing samr_Shutdown\n");
110 status = dcerpc_samr_Shutdown(p, tctx, &r);
111 torture_assert_ntstatus_ok(tctx, status, "samr_Shutdown");
116 static bool test_SetDsrmPassword(struct dcerpc_pipe *p, struct torture_context *tctx,
117 struct policy_handle *handle)
120 struct samr_SetDsrmPassword r;
121 struct lsa_String string;
122 struct samr_Password hash;
124 if (!torture_setting_bool(tctx, "dangerous", false)) {
125 torture_skip(tctx, "samr_SetDsrmPassword disabled - enable dangerous tests to use");
128 E_md4hash("TeSTDSRM123", hash.hash);
130 init_lsa_String(&string, "Administrator");
136 torture_comment(tctx, "testing samr_SetDsrmPassword\n");
138 status = dcerpc_samr_SetDsrmPassword(p, tctx, &r);
139 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_SUPPORTED, "samr_SetDsrmPassword");
145 static bool test_QuerySecurity(struct dcerpc_pipe *p,
146 struct torture_context *tctx,
147 struct policy_handle *handle)
150 struct samr_QuerySecurity r;
151 struct samr_SetSecurity s;
152 struct sec_desc_buf *sdbuf = NULL;
154 r.in.handle = handle;
156 r.out.sdbuf = &sdbuf;
158 status = dcerpc_samr_QuerySecurity(p, tctx, &r);
159 torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
161 torture_assert(tctx, sdbuf != NULL, "sdbuf is NULL");
163 s.in.handle = handle;
167 if (torture_setting_bool(tctx, "samba4", false)) {
168 torture_skip(tctx, "skipping SetSecurity test against Samba4\n");
171 status = dcerpc_samr_SetSecurity(p, tctx, &s);
172 torture_assert_ntstatus_ok(tctx, status, "SetSecurity");
174 status = dcerpc_samr_QuerySecurity(p, tctx, &r);
175 torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
181 static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
182 struct policy_handle *handle, uint32_t base_acct_flags,
183 const char *base_account_name)
186 struct samr_SetUserInfo s;
187 struct samr_SetUserInfo2 s2;
188 struct samr_QueryUserInfo q;
189 struct samr_QueryUserInfo q0;
190 union samr_UserInfo u;
191 union samr_UserInfo *info;
193 const char *test_account_name;
195 uint32_t user_extra_flags = 0;
197 if (!torture_setting_bool(tctx, "samba3", false)) {
198 if (base_acct_flags == ACB_NORMAL) {
199 /* When created, accounts are expired by default */
200 user_extra_flags = ACB_PW_EXPIRED;
204 s.in.user_handle = handle;
207 s2.in.user_handle = handle;
210 q.in.user_handle = handle;
214 #define TESTCALL(call, r) \
215 status = dcerpc_samr_ ##call(p, tctx, &r); \
216 if (!NT_STATUS_IS_OK(status)) { \
217 torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
218 r.in.level, nt_errstr(status), __location__); \
223 #define STRING_EQUAL(s1, s2, field) \
224 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
225 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
226 #field, s2, __location__); \
231 #define MEM_EQUAL(s1, s2, length, field) \
232 if ((s1 && !s2) || (s2 && !s1) || memcmp(s1, s2, length)) { \
233 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
234 #field, (const char *)s2, __location__); \
239 #define INT_EQUAL(i1, i2, field) \
241 torture_comment(tctx, "Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \
242 #field, (unsigned long long)i2, (unsigned long long)i1, __location__); \
247 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
248 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
250 TESTCALL(QueryUserInfo, q) \
252 s2.in.level = lvl1; \
255 ZERO_STRUCT(u.info21); \
256 u.info21.fields_present = fpval; \
258 init_lsa_String(&u.info ## lvl1.field1, value); \
259 TESTCALL(SetUserInfo, s) \
260 TESTCALL(SetUserInfo2, s2) \
261 init_lsa_String(&u.info ## lvl1.field1, ""); \
262 TESTCALL(QueryUserInfo, q); \
264 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
266 TESTCALL(QueryUserInfo, q) \
268 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
271 #define TEST_USERINFO_BINARYSTRING(lvl1, field1, lvl2, field2, value, fpval) do { \
272 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
274 TESTCALL(QueryUserInfo, q) \
276 s2.in.level = lvl1; \
279 ZERO_STRUCT(u.info21); \
280 u.info21.fields_present = fpval; \
282 init_lsa_BinaryString(&u.info ## lvl1.field1, value, strlen(value)); \
283 TESTCALL(SetUserInfo, s) \
284 TESTCALL(SetUserInfo2, s2) \
285 init_lsa_BinaryString(&u.info ## lvl1.field1, "", 1); \
286 TESTCALL(QueryUserInfo, q); \
288 MEM_EQUAL(u.info ## lvl1.field1.array, value, strlen(value), field1); \
290 TESTCALL(QueryUserInfo, q) \
292 MEM_EQUAL(u.info ## lvl2.field2.array, value, strlen(value), field2); \
295 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
296 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
298 TESTCALL(QueryUserInfo, q) \
300 s2.in.level = lvl1; \
303 uint8_t *bits = u.info21.logon_hours.bits; \
304 ZERO_STRUCT(u.info21); \
305 if (fpval == SAMR_FIELD_LOGON_HOURS) { \
306 u.info21.logon_hours.units_per_week = 168; \
307 u.info21.logon_hours.bits = bits; \
309 u.info21.fields_present = fpval; \
311 u.info ## lvl1.field1 = value; \
312 TESTCALL(SetUserInfo, s) \
313 TESTCALL(SetUserInfo2, s2) \
314 u.info ## lvl1.field1 = 0; \
315 TESTCALL(QueryUserInfo, q); \
317 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
319 TESTCALL(QueryUserInfo, q) \
321 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
324 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
325 TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
329 do { TESTCALL(QueryUserInfo, q0) } while (0);
331 /* Samba 3 cannot store comment fields atm. - gd */
332 if (!torture_setting_bool(tctx, "samba3", false)) {
333 TEST_USERINFO_STRING(2, comment, 1, comment, "xx2-1 comment", 0);
334 TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
335 TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment",
339 test_account_name = talloc_asprintf(tctx, "%sxx7-1", base_account_name);
340 TEST_USERINFO_STRING(7, account_name, 1, account_name, base_account_name, 0);
341 test_account_name = talloc_asprintf(tctx, "%sxx7-3", base_account_name);
342 TEST_USERINFO_STRING(7, account_name, 3, account_name, base_account_name, 0);
343 test_account_name = talloc_asprintf(tctx, "%sxx7-5", base_account_name);
344 TEST_USERINFO_STRING(7, account_name, 5, account_name, base_account_name, 0);
345 test_account_name = talloc_asprintf(tctx, "%sxx7-6", base_account_name);
346 TEST_USERINFO_STRING(7, account_name, 6, account_name, base_account_name, 0);
347 test_account_name = talloc_asprintf(tctx, "%sxx7-7", base_account_name);
348 TEST_USERINFO_STRING(7, account_name, 7, account_name, base_account_name, 0);
349 test_account_name = talloc_asprintf(tctx, "%sxx7-21", base_account_name);
350 TEST_USERINFO_STRING(7, account_name, 21, account_name, base_account_name, 0);
351 test_account_name = base_account_name;
352 TEST_USERINFO_STRING(21, account_name, 21, account_name, base_account_name,
353 SAMR_FIELD_ACCOUNT_NAME);
355 TEST_USERINFO_STRING(6, full_name, 1, full_name, "xx6-1 full_name", 0);
356 TEST_USERINFO_STRING(6, full_name, 3, full_name, "xx6-3 full_name", 0);
357 TEST_USERINFO_STRING(6, full_name, 5, full_name, "xx6-5 full_name", 0);
358 TEST_USERINFO_STRING(6, full_name, 6, full_name, "xx6-6 full_name", 0);
359 TEST_USERINFO_STRING(6, full_name, 8, full_name, "xx6-8 full_name", 0);
360 TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
361 TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
362 TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name",
363 SAMR_FIELD_FULL_NAME);
365 TEST_USERINFO_STRING(6, full_name, 1, full_name, "", 0);
366 TEST_USERINFO_STRING(6, full_name, 3, full_name, "", 0);
367 TEST_USERINFO_STRING(6, full_name, 5, full_name, "", 0);
368 TEST_USERINFO_STRING(6, full_name, 6, full_name, "", 0);
369 TEST_USERINFO_STRING(6, full_name, 8, full_name, "", 0);
370 TEST_USERINFO_STRING(6, full_name, 21, full_name, "", 0);
371 TEST_USERINFO_STRING(8, full_name, 21, full_name, "", 0);
372 TEST_USERINFO_STRING(21, full_name, 21, full_name, "",
373 SAMR_FIELD_FULL_NAME);
375 TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
376 TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
377 TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
378 TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script",
379 SAMR_FIELD_LOGON_SCRIPT);
381 TEST_USERINFO_STRING(12, profile_path, 3, profile_path, "xx12-3 profile_path", 0);
382 TEST_USERINFO_STRING(12, profile_path, 5, profile_path, "xx12-5 profile_path", 0);
383 TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
384 TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path",
385 SAMR_FIELD_PROFILE_PATH);
387 TEST_USERINFO_STRING(10, home_directory, 3, home_directory, "xx10-3 home_directory", 0);
388 TEST_USERINFO_STRING(10, home_directory, 5, home_directory, "xx10-5 home_directory", 0);
389 TEST_USERINFO_STRING(10, home_directory, 21, home_directory, "xx10-21 home_directory", 0);
390 TEST_USERINFO_STRING(21, home_directory, 21, home_directory, "xx21-21 home_directory",
391 SAMR_FIELD_HOME_DIRECTORY);
392 TEST_USERINFO_STRING(21, home_directory, 10, home_directory, "xx21-10 home_directory",
393 SAMR_FIELD_HOME_DIRECTORY);
395 TEST_USERINFO_STRING(10, home_drive, 3, home_drive, "xx10-3 home_drive", 0);
396 TEST_USERINFO_STRING(10, home_drive, 5, home_drive, "xx10-5 home_drive", 0);
397 TEST_USERINFO_STRING(10, home_drive, 21, home_drive, "xx10-21 home_drive", 0);
398 TEST_USERINFO_STRING(21, home_drive, 21, home_drive, "xx21-21 home_drive",
399 SAMR_FIELD_HOME_DRIVE);
400 TEST_USERINFO_STRING(21, home_drive, 10, home_drive, "xx21-10 home_drive",
401 SAMR_FIELD_HOME_DRIVE);
403 TEST_USERINFO_STRING(13, description, 1, description, "xx13-1 description", 0);
404 TEST_USERINFO_STRING(13, description, 5, description, "xx13-5 description", 0);
405 TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
406 TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description",
407 SAMR_FIELD_DESCRIPTION);
409 TEST_USERINFO_STRING(14, workstations, 3, workstations, "14workstation3", 0);
410 TEST_USERINFO_STRING(14, workstations, 5, workstations, "14workstation4", 0);
411 TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
412 TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21",
413 SAMR_FIELD_WORKSTATIONS);
414 TEST_USERINFO_STRING(21, workstations, 3, workstations, "21workstation3",
415 SAMR_FIELD_WORKSTATIONS);
416 TEST_USERINFO_STRING(21, workstations, 5, workstations, "21workstation5",
417 SAMR_FIELD_WORKSTATIONS);
418 TEST_USERINFO_STRING(21, workstations, 14, workstations, "21workstation14",
419 SAMR_FIELD_WORKSTATIONS);
421 TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
422 TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "xx21-21 parameters",
423 SAMR_FIELD_PARAMETERS);
424 TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "xx21-20 parameters",
425 SAMR_FIELD_PARAMETERS);
426 /* also empty user parameters are allowed */
427 TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "", 0);
428 TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "",
429 SAMR_FIELD_PARAMETERS);
430 TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "",
431 SAMR_FIELD_PARAMETERS);
433 /* Samba 3 cannot store country_code and copy_page atm. - gd */
434 if (!torture_setting_bool(tctx, "samba3", false)) {
435 TEST_USERINFO_INT(2, country_code, 2, country_code, __LINE__, 0);
436 TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
437 TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__,
438 SAMR_FIELD_COUNTRY_CODE);
439 TEST_USERINFO_INT(21, country_code, 2, country_code, __LINE__,
440 SAMR_FIELD_COUNTRY_CODE);
442 TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
443 TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__,
444 SAMR_FIELD_CODE_PAGE);
445 TEST_USERINFO_INT(21, code_page, 2, code_page, __LINE__,
446 SAMR_FIELD_CODE_PAGE);
449 if (!torture_setting_bool(tctx, "samba3", false)) {
450 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, __LINE__, 0);
451 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, __LINE__, 0);
452 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, __LINE__,
453 SAMR_FIELD_ACCT_EXPIRY);
454 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, __LINE__,
455 SAMR_FIELD_ACCT_EXPIRY);
456 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, __LINE__,
457 SAMR_FIELD_ACCT_EXPIRY);
459 /* Samba 3 can only store seconds / time_t in passdb - gd */
461 unix_to_nt_time(&nt, time(NULL) + __LINE__);
462 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, nt, 0);
463 unix_to_nt_time(&nt, time(NULL) + __LINE__);
464 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, nt, 0);
465 unix_to_nt_time(&nt, time(NULL) + __LINE__);
466 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
467 unix_to_nt_time(&nt, time(NULL) + __LINE__);
468 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
469 unix_to_nt_time(&nt, time(NULL) + __LINE__);
470 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
473 TEST_USERINFO_INT(4, logon_hours.bits[3], 3, logon_hours.bits[3], 1, 0);
474 TEST_USERINFO_INT(4, logon_hours.bits[3], 5, logon_hours.bits[3], 2, 0);
475 TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
476 TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4,
477 SAMR_FIELD_LOGON_HOURS);
479 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
480 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
481 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
483 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
484 (base_acct_flags | ACB_DISABLED),
485 (base_acct_flags | ACB_DISABLED | user_extra_flags),
488 /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
489 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
490 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
491 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
493 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
494 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
495 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
499 /* The 'autolock' flag doesn't stick - check this */
500 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
501 (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK),
502 (base_acct_flags | ACB_DISABLED | user_extra_flags),
505 /* Removing the 'disabled' flag doesn't stick - check this */
506 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
508 (base_acct_flags | ACB_DISABLED | user_extra_flags),
512 /* Samba3 cannot store these atm */
513 if (!torture_setting_bool(tctx, "samba3", false)) {
514 /* The 'store plaintext' flag does stick */
515 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
516 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED),
517 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags),
519 /* The 'use DES' flag does stick */
520 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
521 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY),
522 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags),
524 /* The 'don't require kerberos pre-authentication flag does stick */
525 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
526 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH),
527 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags),
529 /* The 'no kerberos PAC required' flag sticks */
530 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
531 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD),
532 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags),
535 TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags,
536 (base_acct_flags | ACB_DISABLED),
537 (base_acct_flags | ACB_DISABLED | user_extra_flags),
538 SAMR_FIELD_ACCT_FLAGS);
541 /* these fail with win2003 - it appears you can't set the primary gid?
542 the set succeeds, but the gid isn't changed. Very weird! */
543 TEST_USERINFO_INT(9, primary_gid, 1, primary_gid, 513);
544 TEST_USERINFO_INT(9, primary_gid, 3, primary_gid, 513);
545 TEST_USERINFO_INT(9, primary_gid, 5, primary_gid, 513);
546 TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
553 generate a random password for password change tests
555 static char *samr_rand_pass_silent(TALLOC_CTX *mem_ctx, int min_len)
557 size_t len = MAX(8, min_len) + (random() % 6);
558 char *s = generate_random_str(mem_ctx, len);
562 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
564 char *s = samr_rand_pass_silent(mem_ctx, min_len);
565 printf("Generated password '%s'\n", s);
571 generate a random password for password change tests
573 static DATA_BLOB samr_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
576 DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
577 generate_random_buffer(password.data, password.length);
579 for (i=0; i < len; i++) {
580 if (((uint16_t *)password.data)[i] == 0) {
581 ((uint16_t *)password.data)[i] = 1;
589 generate a random password for password change tests (fixed length)
591 static char *samr_rand_pass_fixed_len(TALLOC_CTX *mem_ctx, int len)
593 char *s = generate_random_str(mem_ctx, len);
594 printf("Generated password '%s'\n", s);
598 static bool test_SetUserPass(struct dcerpc_pipe *p, struct torture_context *tctx,
599 struct policy_handle *handle, char **password)
602 struct samr_SetUserInfo s;
603 union samr_UserInfo u;
605 DATA_BLOB session_key;
607 struct samr_GetUserPwInfo pwp;
608 struct samr_PwInfo info;
609 int policy_min_pw_len = 0;
610 pwp.in.user_handle = handle;
611 pwp.out.info = &info;
613 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
614 if (NT_STATUS_IS_OK(status)) {
615 policy_min_pw_len = pwp.out.info->min_password_length;
617 newpass = samr_rand_pass(tctx, policy_min_pw_len);
619 s.in.user_handle = handle;
623 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
624 u.info24.password_expired = 0;
626 status = dcerpc_fetch_session_key(p, &session_key);
627 if (!NT_STATUS_IS_OK(status)) {
628 printf("SetUserInfo level %u - no session key - %s\n",
629 s.in.level, nt_errstr(status));
633 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
635 torture_comment(tctx, "Testing SetUserInfo level 24 (set password)\n");
637 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
638 if (!NT_STATUS_IS_OK(status)) {
639 printf("SetUserInfo level %u failed - %s\n",
640 s.in.level, nt_errstr(status));
650 static bool test_SetUserPass_23(struct dcerpc_pipe *p, struct torture_context *tctx,
651 struct policy_handle *handle, uint32_t fields_present,
655 struct samr_SetUserInfo s;
656 union samr_UserInfo u;
658 DATA_BLOB session_key;
660 struct samr_GetUserPwInfo pwp;
661 struct samr_PwInfo info;
662 int policy_min_pw_len = 0;
663 pwp.in.user_handle = handle;
664 pwp.out.info = &info;
666 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
667 if (NT_STATUS_IS_OK(status)) {
668 policy_min_pw_len = pwp.out.info->min_password_length;
670 newpass = samr_rand_pass(tctx, policy_min_pw_len);
672 s.in.user_handle = handle;
678 u.info23.info.fields_present = fields_present;
680 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
682 status = dcerpc_fetch_session_key(p, &session_key);
683 if (!NT_STATUS_IS_OK(status)) {
684 printf("SetUserInfo level %u - no session key - %s\n",
685 s.in.level, nt_errstr(status));
689 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
691 torture_comment(tctx, "Testing SetUserInfo level 23 (set password)\n");
693 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
694 if (!NT_STATUS_IS_OK(status)) {
695 printf("SetUserInfo level %u failed - %s\n",
696 s.in.level, nt_errstr(status));
702 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
704 status = dcerpc_fetch_session_key(p, &session_key);
705 if (!NT_STATUS_IS_OK(status)) {
706 printf("SetUserInfo level %u - no session key - %s\n",
707 s.in.level, nt_errstr(status));
711 /* This should break the key nicely */
712 session_key.length--;
713 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
715 torture_comment(tctx, "Testing SetUserInfo level 23 (set password) with wrong password\n");
717 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
718 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
719 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
720 s.in.level, nt_errstr(status));
728 static bool test_SetUserPassEx(struct dcerpc_pipe *p, struct torture_context *tctx,
729 struct policy_handle *handle, bool makeshort,
733 struct samr_SetUserInfo s;
734 union samr_UserInfo u;
736 DATA_BLOB session_key;
737 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
738 uint8_t confounder[16];
740 struct MD5Context ctx;
741 struct samr_GetUserPwInfo pwp;
742 struct samr_PwInfo info;
743 int policy_min_pw_len = 0;
744 pwp.in.user_handle = handle;
745 pwp.out.info = &info;
747 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
748 if (NT_STATUS_IS_OK(status)) {
749 policy_min_pw_len = pwp.out.info->min_password_length;
751 if (makeshort && policy_min_pw_len) {
752 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len - 1);
754 newpass = samr_rand_pass(tctx, policy_min_pw_len);
757 s.in.user_handle = handle;
761 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
762 u.info26.password_expired = 0;
764 status = dcerpc_fetch_session_key(p, &session_key);
765 if (!NT_STATUS_IS_OK(status)) {
766 printf("SetUserInfo level %u - no session key - %s\n",
767 s.in.level, nt_errstr(status));
771 generate_random_buffer((uint8_t *)confounder, 16);
774 MD5Update(&ctx, confounder, 16);
775 MD5Update(&ctx, session_key.data, session_key.length);
776 MD5Final(confounded_session_key.data, &ctx);
778 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
779 memcpy(&u.info26.password.data[516], confounder, 16);
781 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex)\n");
783 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
784 if (!NT_STATUS_IS_OK(status)) {
785 printf("SetUserInfo level %u failed - %s\n",
786 s.in.level, nt_errstr(status));
792 /* This should break the key nicely */
793 confounded_session_key.data[0]++;
795 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
796 memcpy(&u.info26.password.data[516], confounder, 16);
798 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
800 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
801 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
802 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
803 s.in.level, nt_errstr(status));
812 static bool test_SetUserPass_25(struct dcerpc_pipe *p, struct torture_context *tctx,
813 struct policy_handle *handle, uint32_t fields_present,
817 struct samr_SetUserInfo s;
818 union samr_UserInfo u;
820 DATA_BLOB session_key;
821 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
822 struct MD5Context ctx;
823 uint8_t confounder[16];
825 struct samr_GetUserPwInfo pwp;
826 struct samr_PwInfo info;
827 int policy_min_pw_len = 0;
828 pwp.in.user_handle = handle;
829 pwp.out.info = &info;
831 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
832 if (NT_STATUS_IS_OK(status)) {
833 policy_min_pw_len = pwp.out.info->min_password_length;
835 newpass = samr_rand_pass(tctx, policy_min_pw_len);
837 s.in.user_handle = handle;
843 u.info25.info.fields_present = fields_present;
845 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
847 status = dcerpc_fetch_session_key(p, &session_key);
848 if (!NT_STATUS_IS_OK(status)) {
849 printf("SetUserInfo level %u - no session key - %s\n",
850 s.in.level, nt_errstr(status));
854 generate_random_buffer((uint8_t *)confounder, 16);
857 MD5Update(&ctx, confounder, 16);
858 MD5Update(&ctx, session_key.data, session_key.length);
859 MD5Final(confounded_session_key.data, &ctx);
861 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
862 memcpy(&u.info25.password.data[516], confounder, 16);
864 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex)\n");
866 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
867 if (!NT_STATUS_IS_OK(status)) {
868 printf("SetUserInfo level %u failed - %s\n",
869 s.in.level, nt_errstr(status));
875 /* This should break the key nicely */
876 confounded_session_key.data[0]++;
878 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
879 memcpy(&u.info25.password.data[516], confounder, 16);
881 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
883 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
884 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
885 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
886 s.in.level, nt_errstr(status));
893 static bool test_SetUserPass_18(struct dcerpc_pipe *p, struct torture_context *tctx,
894 struct policy_handle *handle, char **password)
897 struct samr_SetUserInfo s;
898 union samr_UserInfo u;
900 DATA_BLOB session_key;
902 struct samr_GetUserPwInfo pwp;
903 struct samr_PwInfo info;
904 int policy_min_pw_len = 0;
905 uint8_t lm_hash[16], nt_hash[16];
907 pwp.in.user_handle = handle;
908 pwp.out.info = &info;
910 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
911 if (NT_STATUS_IS_OK(status)) {
912 policy_min_pw_len = pwp.out.info->min_password_length;
914 newpass = samr_rand_pass(tctx, policy_min_pw_len);
916 s.in.user_handle = handle;
922 u.info18.nt_pwd_active = true;
923 u.info18.lm_pwd_active = true;
925 E_md4hash(newpass, nt_hash);
926 E_deshash(newpass, lm_hash);
928 status = dcerpc_fetch_session_key(p, &session_key);
929 if (!NT_STATUS_IS_OK(status)) {
930 printf("SetUserInfo level %u - no session key - %s\n",
931 s.in.level, nt_errstr(status));
937 in = data_blob_const(nt_hash, 16);
938 out = data_blob_talloc_zero(tctx, 16);
939 sess_crypt_blob(&out, &in, &session_key, true);
940 memcpy(u.info18.nt_pwd.hash, out.data, out.length);
944 in = data_blob_const(lm_hash, 16);
945 out = data_blob_talloc_zero(tctx, 16);
946 sess_crypt_blob(&out, &in, &session_key, true);
947 memcpy(u.info18.lm_pwd.hash, out.data, out.length);
950 torture_comment(tctx, "Testing SetUserInfo level 18 (set password hash)\n");
952 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
953 if (!NT_STATUS_IS_OK(status)) {
954 printf("SetUserInfo level %u failed - %s\n",
955 s.in.level, nt_errstr(status));
964 static bool test_SetUserPass_21(struct dcerpc_pipe *p, struct torture_context *tctx,
965 struct policy_handle *handle, uint32_t fields_present,
969 struct samr_SetUserInfo s;
970 union samr_UserInfo u;
972 DATA_BLOB session_key;
974 struct samr_GetUserPwInfo pwp;
975 struct samr_PwInfo info;
976 int policy_min_pw_len = 0;
977 uint8_t lm_hash[16], nt_hash[16];
979 pwp.in.user_handle = handle;
980 pwp.out.info = &info;
982 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
983 if (NT_STATUS_IS_OK(status)) {
984 policy_min_pw_len = pwp.out.info->min_password_length;
986 newpass = samr_rand_pass(tctx, policy_min_pw_len);
988 s.in.user_handle = handle;
992 E_md4hash(newpass, nt_hash);
993 E_deshash(newpass, lm_hash);
997 u.info21.fields_present = fields_present;
999 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1000 u.info21.lm_owf_password.length = 16;
1001 u.info21.lm_owf_password.size = 16;
1002 u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
1003 u.info21.lm_password_set = true;
1006 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1007 u.info21.nt_owf_password.length = 16;
1008 u.info21.nt_owf_password.size = 16;
1009 u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
1010 u.info21.nt_password_set = true;
1013 status = dcerpc_fetch_session_key(p, &session_key);
1014 if (!NT_STATUS_IS_OK(status)) {
1015 printf("SetUserInfo level %u - no session key - %s\n",
1016 s.in.level, nt_errstr(status));
1020 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1022 in = data_blob_const(u.info21.lm_owf_password.array,
1023 u.info21.lm_owf_password.length);
1024 out = data_blob_talloc_zero(tctx, 16);
1025 sess_crypt_blob(&out, &in, &session_key, true);
1026 u.info21.lm_owf_password.array = (uint16_t *)out.data;
1029 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1031 in = data_blob_const(u.info21.nt_owf_password.array,
1032 u.info21.nt_owf_password.length);
1033 out = data_blob_talloc_zero(tctx, 16);
1034 sess_crypt_blob(&out, &in, &session_key, true);
1035 u.info21.nt_owf_password.array = (uint16_t *)out.data;
1038 torture_comment(tctx, "Testing SetUserInfo level 21 (set password hash)\n");
1040 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1041 if (!NT_STATUS_IS_OK(status)) {
1042 printf("SetUserInfo level %u failed - %s\n",
1043 s.in.level, nt_errstr(status));
1046 *password = newpass;
1049 /* try invalid length */
1050 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1052 u.info21.nt_owf_password.length++;
1054 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1056 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1057 printf("SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1058 s.in.level, nt_errstr(status));
1063 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1065 u.info21.lm_owf_password.length++;
1067 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1069 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1070 printf("SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1071 s.in.level, nt_errstr(status));
1079 static bool test_SetUserPass_level_ex(struct dcerpc_pipe *p,
1080 struct torture_context *tctx,
1081 struct policy_handle *handle,
1083 uint32_t fields_present,
1084 char **password, uint8_t password_expired,
1086 bool *matched_expected_error)
1089 NTSTATUS expected_error = NT_STATUS_OK;
1090 struct samr_SetUserInfo s;
1091 struct samr_SetUserInfo2 s2;
1092 union samr_UserInfo u;
1094 DATA_BLOB session_key;
1095 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
1096 struct MD5Context ctx;
1097 uint8_t confounder[16];
1099 struct samr_GetUserPwInfo pwp;
1100 struct samr_PwInfo info;
1101 int policy_min_pw_len = 0;
1102 const char *comment = NULL;
1103 uint8_t lm_hash[16], nt_hash[16];
1105 pwp.in.user_handle = handle;
1106 pwp.out.info = &info;
1108 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1109 if (NT_STATUS_IS_OK(status)) {
1110 policy_min_pw_len = pwp.out.info->min_password_length;
1112 newpass = samr_rand_pass_silent(tctx, policy_min_pw_len);
1115 s2.in.user_handle = handle;
1117 s2.in.level = level;
1119 s.in.user_handle = handle;
1124 if (fields_present & SAMR_FIELD_COMMENT) {
1125 comment = talloc_asprintf(tctx, "comment: %ld\n", time(NULL));
1132 E_md4hash(newpass, nt_hash);
1133 E_deshash(newpass, lm_hash);
1135 u.info18.nt_pwd_active = true;
1136 u.info18.lm_pwd_active = true;
1137 u.info18.password_expired = password_expired;
1139 memcpy(u.info18.lm_pwd.hash, lm_hash, 16);
1140 memcpy(u.info18.nt_pwd.hash, nt_hash, 16);
1144 E_md4hash(newpass, nt_hash);
1145 E_deshash(newpass, lm_hash);
1147 u.info21.fields_present = fields_present;
1148 u.info21.password_expired = password_expired;
1149 u.info21.comment.string = comment;
1151 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1152 u.info21.lm_owf_password.length = 16;
1153 u.info21.lm_owf_password.size = 16;
1154 u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
1155 u.info21.lm_password_set = true;
1158 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1159 u.info21.nt_owf_password.length = 16;
1160 u.info21.nt_owf_password.size = 16;
1161 u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
1162 u.info21.nt_password_set = true;
1167 u.info23.info.fields_present = fields_present;
1168 u.info23.info.password_expired = password_expired;
1169 u.info23.info.comment.string = comment;
1171 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
1175 u.info24.password_expired = password_expired;
1177 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
1181 u.info25.info.fields_present = fields_present;
1182 u.info25.info.password_expired = password_expired;
1183 u.info25.info.comment.string = comment;
1185 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
1189 u.info26.password_expired = password_expired;
1191 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
1196 status = dcerpc_fetch_session_key(p, &session_key);
1197 if (!NT_STATUS_IS_OK(status)) {
1198 printf("SetUserInfo level %u - no session key - %s\n",
1199 s.in.level, nt_errstr(status));
1203 generate_random_buffer((uint8_t *)confounder, 16);
1206 MD5Update(&ctx, confounder, 16);
1207 MD5Update(&ctx, session_key.data, session_key.length);
1208 MD5Final(confounded_session_key.data, &ctx);
1214 in = data_blob_const(u.info18.nt_pwd.hash, 16);
1215 out = data_blob_talloc_zero(tctx, 16);
1216 sess_crypt_blob(&out, &in, &session_key, true);
1217 memcpy(u.info18.nt_pwd.hash, out.data, out.length);
1221 in = data_blob_const(u.info18.lm_pwd.hash, 16);
1222 out = data_blob_talloc_zero(tctx, 16);
1223 sess_crypt_blob(&out, &in, &session_key, true);
1224 memcpy(u.info18.lm_pwd.hash, out.data, out.length);
1229 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1231 in = data_blob_const(u.info21.lm_owf_password.array,
1232 u.info21.lm_owf_password.length);
1233 out = data_blob_talloc_zero(tctx, 16);
1234 sess_crypt_blob(&out, &in, &session_key, true);
1235 u.info21.lm_owf_password.array = (uint16_t *)out.data;
1237 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1239 in = data_blob_const(u.info21.nt_owf_password.array,
1240 u.info21.nt_owf_password.length);
1241 out = data_blob_talloc_zero(tctx, 16);
1242 sess_crypt_blob(&out, &in, &session_key, true);
1243 u.info21.nt_owf_password.array = (uint16_t *)out.data;
1247 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
1250 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
1253 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
1254 memcpy(&u.info25.password.data[516], confounder, 16);
1257 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
1258 memcpy(&u.info26.password.data[516], confounder, 16);
1263 status = dcerpc_samr_SetUserInfo2(p, tctx, &s2);
1265 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1268 if (!NT_STATUS_IS_OK(status)) {
1269 if (fields_present == 0) {
1270 expected_error = NT_STATUS_INVALID_PARAMETER;
1272 if (fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
1273 expected_error = NT_STATUS_ACCESS_DENIED;
1277 if (!NT_STATUS_IS_OK(expected_error)) {
1279 torture_assert_ntstatus_equal(tctx,
1281 expected_error, "SetUserInfo2 failed");
1283 torture_assert_ntstatus_equal(tctx,
1285 expected_error, "SetUserInfo failed");
1287 *matched_expected_error = true;
1291 if (!NT_STATUS_IS_OK(status)) {
1292 printf("SetUserInfo%s level %u failed - %s\n",
1293 use_setinfo2 ? "2":"", level, nt_errstr(status));
1296 *password = newpass;
1302 static bool test_SetAliasInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1303 struct policy_handle *handle)
1306 struct samr_SetAliasInfo r;
1307 struct samr_QueryAliasInfo q;
1308 union samr_AliasInfo *info;
1309 uint16_t levels[] = {2, 3};
1313 /* Ignoring switch level 1, as that includes the number of members for the alias
1314 * and setting this to a wrong value might have negative consequences
1317 for (i=0;i<ARRAY_SIZE(levels);i++) {
1318 torture_comment(tctx, "Testing SetAliasInfo level %u\n", levels[i]);
1320 r.in.alias_handle = handle;
1321 r.in.level = levels[i];
1322 r.in.info = talloc(tctx, union samr_AliasInfo);
1323 switch (r.in.level) {
1324 case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
1325 case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
1326 "Test Description, should test I18N as well"); break;
1327 case ALIASINFOALL: printf("ALIASINFOALL ignored\n"); break;
1330 status = dcerpc_samr_SetAliasInfo(p, tctx, &r);
1331 if (!NT_STATUS_IS_OK(status)) {
1332 printf("SetAliasInfo level %u failed - %s\n",
1333 levels[i], nt_errstr(status));
1337 q.in.alias_handle = handle;
1338 q.in.level = levels[i];
1341 status = dcerpc_samr_QueryAliasInfo(p, tctx, &q);
1342 if (!NT_STATUS_IS_OK(status)) {
1343 printf("QueryAliasInfo level %u failed - %s\n",
1344 levels[i], nt_errstr(status));
1352 static bool test_GetGroupsForUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1353 struct policy_handle *user_handle)
1355 struct samr_GetGroupsForUser r;
1356 struct samr_RidWithAttributeArray *rids = NULL;
1359 torture_comment(tctx, "testing GetGroupsForUser\n");
1361 r.in.user_handle = user_handle;
1364 status = dcerpc_samr_GetGroupsForUser(p, tctx, &r);
1365 torture_assert_ntstatus_ok(tctx, status, "GetGroupsForUser");
1371 static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1372 struct lsa_String *domain_name)
1375 struct samr_GetDomPwInfo r;
1376 struct samr_PwInfo info;
1378 r.in.domain_name = domain_name;
1381 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1383 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1384 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1386 r.in.domain_name->string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1387 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1389 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1390 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1392 r.in.domain_name->string = "\\\\__NONAME__";
1393 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1395 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1396 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1398 r.in.domain_name->string = "\\\\Builtin";
1399 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1401 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1402 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1407 static bool test_GetUserPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1408 struct policy_handle *handle)
1411 struct samr_GetUserPwInfo r;
1412 struct samr_PwInfo info;
1414 torture_comment(tctx, "Testing GetUserPwInfo\n");
1416 r.in.user_handle = handle;
1419 status = dcerpc_samr_GetUserPwInfo(p, tctx, &r);
1420 torture_assert_ntstatus_ok(tctx, status, "GetUserPwInfo");
1425 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, struct torture_context *tctx,
1426 struct policy_handle *domain_handle, const char *name,
1430 struct samr_LookupNames n;
1431 struct lsa_String sname[2];
1432 struct samr_Ids rids, types;
1434 init_lsa_String(&sname[0], name);
1436 n.in.domain_handle = domain_handle;
1440 n.out.types = &types;
1441 status = dcerpc_samr_LookupNames(p, tctx, &n);
1442 if (NT_STATUS_IS_OK(status)) {
1443 *rid = n.out.rids->ids[0];
1448 init_lsa_String(&sname[1], "xxNONAMExx");
1450 status = dcerpc_samr_LookupNames(p, tctx, &n);
1451 if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
1452 printf("LookupNames[2] failed - %s\n", nt_errstr(status));
1453 if (NT_STATUS_IS_OK(status)) {
1454 return NT_STATUS_UNSUCCESSFUL;
1460 status = dcerpc_samr_LookupNames(p, tctx, &n);
1461 if (!NT_STATUS_IS_OK(status)) {
1462 printf("LookupNames[0] failed - %s\n", nt_errstr(status));
1466 init_lsa_String(&sname[0], "xxNONAMExx");
1468 status = dcerpc_samr_LookupNames(p, tctx, &n);
1469 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1470 printf("LookupNames[1 bad name] failed - %s\n", nt_errstr(status));
1471 if (NT_STATUS_IS_OK(status)) {
1472 return NT_STATUS_UNSUCCESSFUL;
1477 init_lsa_String(&sname[0], "xxNONAMExx");
1478 init_lsa_String(&sname[1], "xxNONAME2xx");
1480 status = dcerpc_samr_LookupNames(p, tctx, &n);
1481 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1482 printf("LookupNames[2 bad names] failed - %s\n", nt_errstr(status));
1483 if (NT_STATUS_IS_OK(status)) {
1484 return NT_STATUS_UNSUCCESSFUL;
1489 return NT_STATUS_OK;
1492 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p,
1493 struct torture_context *tctx,
1494 struct policy_handle *domain_handle,
1495 const char *name, struct policy_handle *user_handle)
1498 struct samr_OpenUser r;
1501 status = test_LookupName(p, tctx, domain_handle, name, &rid);
1502 if (!NT_STATUS_IS_OK(status)) {
1506 r.in.domain_handle = domain_handle;
1507 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1509 r.out.user_handle = user_handle;
1510 status = dcerpc_samr_OpenUser(p, tctx, &r);
1511 if (!NT_STATUS_IS_OK(status)) {
1512 printf("OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(status));
1519 static bool test_ChangePasswordNT3(struct dcerpc_pipe *p,
1520 struct torture_context *tctx,
1521 struct policy_handle *handle)
1524 struct samr_ChangePasswordUser r;
1526 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1527 struct policy_handle user_handle;
1528 char *oldpass = "test";
1529 char *newpass = "test2";
1530 uint8_t old_nt_hash[16], new_nt_hash[16];
1531 uint8_t old_lm_hash[16], new_lm_hash[16];
1533 status = test_OpenUser_byname(p, tctx, handle, "testuser", &user_handle);
1534 if (!NT_STATUS_IS_OK(status)) {
1538 printf("Testing ChangePasswordUser for user 'testuser'\n");
1540 printf("old password: %s\n", oldpass);
1541 printf("new password: %s\n", newpass);
1543 E_md4hash(oldpass, old_nt_hash);
1544 E_md4hash(newpass, new_nt_hash);
1545 E_deshash(oldpass, old_lm_hash);
1546 E_deshash(newpass, new_lm_hash);
1548 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1549 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1550 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1551 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1552 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1553 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1555 r.in.handle = &user_handle;
1556 r.in.lm_present = 1;
1557 r.in.old_lm_crypted = &hash1;
1558 r.in.new_lm_crypted = &hash2;
1559 r.in.nt_present = 1;
1560 r.in.old_nt_crypted = &hash3;
1561 r.in.new_nt_crypted = &hash4;
1562 r.in.cross1_present = 1;
1563 r.in.nt_cross = &hash5;
1564 r.in.cross2_present = 1;
1565 r.in.lm_cross = &hash6;
1567 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1568 if (!NT_STATUS_IS_OK(status)) {
1569 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1573 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
1581 static bool test_ChangePasswordUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1582 const char *acct_name,
1583 struct policy_handle *handle, char **password)
1586 struct samr_ChangePasswordUser r;
1588 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1589 struct policy_handle user_handle;
1591 uint8_t old_nt_hash[16], new_nt_hash[16];
1592 uint8_t old_lm_hash[16], new_lm_hash[16];
1593 bool changed = true;
1596 struct samr_GetUserPwInfo pwp;
1597 struct samr_PwInfo info;
1598 int policy_min_pw_len = 0;
1600 status = test_OpenUser_byname(p, tctx, handle, acct_name, &user_handle);
1601 if (!NT_STATUS_IS_OK(status)) {
1604 pwp.in.user_handle = &user_handle;
1605 pwp.out.info = &info;
1607 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1608 if (NT_STATUS_IS_OK(status)) {
1609 policy_min_pw_len = pwp.out.info->min_password_length;
1611 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1613 torture_comment(tctx, "Testing ChangePasswordUser\n");
1615 torture_assert(tctx, *password != NULL,
1616 "Failing ChangePasswordUser as old password was NULL. Previous test failed?");
1618 oldpass = *password;
1620 E_md4hash(oldpass, old_nt_hash);
1621 E_md4hash(newpass, new_nt_hash);
1622 E_deshash(oldpass, old_lm_hash);
1623 E_deshash(newpass, new_lm_hash);
1625 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1626 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1627 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1628 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1629 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1630 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1632 r.in.user_handle = &user_handle;
1633 r.in.lm_present = 1;
1634 /* Break the LM hash */
1636 r.in.old_lm_crypted = &hash1;
1637 r.in.new_lm_crypted = &hash2;
1638 r.in.nt_present = 1;
1639 r.in.old_nt_crypted = &hash3;
1640 r.in.new_nt_crypted = &hash4;
1641 r.in.cross1_present = 1;
1642 r.in.nt_cross = &hash5;
1643 r.in.cross2_present = 1;
1644 r.in.lm_cross = &hash6;
1646 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1647 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1648 "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash");
1650 /* Unbreak the LM hash */
1653 r.in.user_handle = &user_handle;
1654 r.in.lm_present = 1;
1655 r.in.old_lm_crypted = &hash1;
1656 r.in.new_lm_crypted = &hash2;
1657 /* Break the NT hash */
1659 r.in.nt_present = 1;
1660 r.in.old_nt_crypted = &hash3;
1661 r.in.new_nt_crypted = &hash4;
1662 r.in.cross1_present = 1;
1663 r.in.nt_cross = &hash5;
1664 r.in.cross2_present = 1;
1665 r.in.lm_cross = &hash6;
1667 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1668 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1669 "expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash");
1671 /* Unbreak the NT hash */
1674 r.in.user_handle = &user_handle;
1675 r.in.lm_present = 1;
1676 r.in.old_lm_crypted = &hash1;
1677 r.in.new_lm_crypted = &hash2;
1678 r.in.nt_present = 1;
1679 r.in.old_nt_crypted = &hash3;
1680 r.in.new_nt_crypted = &hash4;
1681 r.in.cross1_present = 1;
1682 r.in.nt_cross = &hash5;
1683 r.in.cross2_present = 1;
1684 /* Break the LM cross */
1686 r.in.lm_cross = &hash6;
1688 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1689 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1690 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status));
1694 /* Unbreak the LM cross */
1697 r.in.user_handle = &user_handle;
1698 r.in.lm_present = 1;
1699 r.in.old_lm_crypted = &hash1;
1700 r.in.new_lm_crypted = &hash2;
1701 r.in.nt_present = 1;
1702 r.in.old_nt_crypted = &hash3;
1703 r.in.new_nt_crypted = &hash4;
1704 r.in.cross1_present = 1;
1705 /* Break the NT cross */
1707 r.in.nt_cross = &hash5;
1708 r.in.cross2_present = 1;
1709 r.in.lm_cross = &hash6;
1711 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1712 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1713 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status));
1717 /* Unbreak the NT cross */
1721 /* Reset the hashes to not broken values */
1722 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1723 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1724 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1725 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1726 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1727 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1729 r.in.user_handle = &user_handle;
1730 r.in.lm_present = 1;
1731 r.in.old_lm_crypted = &hash1;
1732 r.in.new_lm_crypted = &hash2;
1733 r.in.nt_present = 1;
1734 r.in.old_nt_crypted = &hash3;
1735 r.in.new_nt_crypted = &hash4;
1736 r.in.cross1_present = 1;
1737 r.in.nt_cross = &hash5;
1738 r.in.cross2_present = 0;
1739 r.in.lm_cross = NULL;
1741 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1742 if (NT_STATUS_IS_OK(status)) {
1744 *password = newpass;
1745 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1746 printf("ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(status));
1751 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1753 E_md4hash(oldpass, old_nt_hash);
1754 E_md4hash(newpass, new_nt_hash);
1755 E_deshash(oldpass, old_lm_hash);
1756 E_deshash(newpass, new_lm_hash);
1759 /* Reset the hashes to not broken values */
1760 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1761 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1762 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1763 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1764 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1765 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1767 r.in.user_handle = &user_handle;
1768 r.in.lm_present = 1;
1769 r.in.old_lm_crypted = &hash1;
1770 r.in.new_lm_crypted = &hash2;
1771 r.in.nt_present = 1;
1772 r.in.old_nt_crypted = &hash3;
1773 r.in.new_nt_crypted = &hash4;
1774 r.in.cross1_present = 0;
1775 r.in.nt_cross = NULL;
1776 r.in.cross2_present = 1;
1777 r.in.lm_cross = &hash6;
1779 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1780 if (NT_STATUS_IS_OK(status)) {
1782 *password = newpass;
1783 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1784 printf("ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status));
1789 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1791 E_md4hash(oldpass, old_nt_hash);
1792 E_md4hash(newpass, new_nt_hash);
1793 E_deshash(oldpass, old_lm_hash);
1794 E_deshash(newpass, new_lm_hash);
1797 /* Reset the hashes to not broken values */
1798 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1799 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1800 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1801 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1802 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1803 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1805 r.in.user_handle = &user_handle;
1806 r.in.lm_present = 1;
1807 r.in.old_lm_crypted = &hash1;
1808 r.in.new_lm_crypted = &hash2;
1809 r.in.nt_present = 1;
1810 r.in.old_nt_crypted = &hash3;
1811 r.in.new_nt_crypted = &hash4;
1812 r.in.cross1_present = 1;
1813 r.in.nt_cross = &hash5;
1814 r.in.cross2_present = 1;
1815 r.in.lm_cross = &hash6;
1817 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1818 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1819 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1820 } else if (!NT_STATUS_IS_OK(status)) {
1821 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1825 *password = newpass;
1828 r.in.user_handle = &user_handle;
1829 r.in.lm_present = 1;
1830 r.in.old_lm_crypted = &hash1;
1831 r.in.new_lm_crypted = &hash2;
1832 r.in.nt_present = 1;
1833 r.in.old_nt_crypted = &hash3;
1834 r.in.new_nt_crypted = &hash4;
1835 r.in.cross1_present = 1;
1836 r.in.nt_cross = &hash5;
1837 r.in.cross2_present = 1;
1838 r.in.lm_cross = &hash6;
1841 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1842 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1843 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1844 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1845 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status));
1851 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
1859 static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
1860 const char *acct_name,
1861 struct policy_handle *handle, char **password)
1864 struct samr_OemChangePasswordUser2 r;
1866 struct samr_Password lm_verifier;
1867 struct samr_CryptPassword lm_pass;
1868 struct lsa_AsciiString server, account, account_bad;
1871 uint8_t old_lm_hash[16], new_lm_hash[16];
1873 struct samr_GetDomPwInfo dom_pw_info;
1874 struct samr_PwInfo info;
1875 int policy_min_pw_len = 0;
1877 struct lsa_String domain_name;
1879 domain_name.string = "";
1880 dom_pw_info.in.domain_name = &domain_name;
1881 dom_pw_info.out.info = &info;
1883 torture_comment(tctx, "Testing OemChangePasswordUser2\n");
1885 torture_assert(tctx, *password != NULL,
1886 "Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?");
1888 oldpass = *password;
1890 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
1891 if (NT_STATUS_IS_OK(status)) {
1892 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
1895 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1897 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1898 account.string = acct_name;
1900 E_deshash(oldpass, old_lm_hash);
1901 E_deshash(newpass, new_lm_hash);
1903 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1904 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1905 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1907 r.in.server = &server;
1908 r.in.account = &account;
1909 r.in.password = &lm_pass;
1910 r.in.hash = &lm_verifier;
1912 /* Break the verification */
1913 lm_verifier.hash[0]++;
1915 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1917 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1918 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1919 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1924 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1925 /* Break the old password */
1927 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1928 /* unbreak it for the next operation */
1930 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1932 r.in.server = &server;
1933 r.in.account = &account;
1934 r.in.password = &lm_pass;
1935 r.in.hash = &lm_verifier;
1937 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1939 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1940 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1941 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1946 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1947 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1949 r.in.server = &server;
1950 r.in.account = &account;
1951 r.in.password = &lm_pass;
1954 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1956 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1957 && !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1958 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
1963 /* This shouldn't be a valid name */
1964 account_bad.string = TEST_ACCOUNT_NAME "XX";
1965 r.in.account = &account_bad;
1967 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1969 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1970 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
1975 /* This shouldn't be a valid name */
1976 account_bad.string = TEST_ACCOUNT_NAME "XX";
1977 r.in.account = &account_bad;
1978 r.in.password = &lm_pass;
1979 r.in.hash = &lm_verifier;
1981 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1983 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1984 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1989 /* This shouldn't be a valid name */
1990 account_bad.string = TEST_ACCOUNT_NAME "XX";
1991 r.in.account = &account_bad;
1992 r.in.password = NULL;
1993 r.in.hash = &lm_verifier;
1995 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1997 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1998 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
2003 E_deshash(oldpass, old_lm_hash);
2004 E_deshash(newpass, new_lm_hash);
2006 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
2007 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2008 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
2010 r.in.server = &server;
2011 r.in.account = &account;
2012 r.in.password = &lm_pass;
2013 r.in.hash = &lm_verifier;
2015 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
2016 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2017 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
2018 } else if (!NT_STATUS_IS_OK(status)) {
2019 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
2022 *password = newpass;
2029 static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
2030 const char *acct_name,
2032 char *newpass, bool allow_password_restriction)
2035 struct samr_ChangePasswordUser2 r;
2037 struct lsa_String server, account;
2038 struct samr_CryptPassword nt_pass, lm_pass;
2039 struct samr_Password nt_verifier, lm_verifier;
2041 uint8_t old_nt_hash[16], new_nt_hash[16];
2042 uint8_t old_lm_hash[16], new_lm_hash[16];
2044 struct samr_GetDomPwInfo dom_pw_info;
2045 struct samr_PwInfo info;
2047 struct lsa_String domain_name;
2049 domain_name.string = "";
2050 dom_pw_info.in.domain_name = &domain_name;
2051 dom_pw_info.out.info = &info;
2053 torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name);
2055 torture_assert(tctx, *password != NULL,
2056 "Failing ChangePasswordUser2 as old password was NULL. Previous test failed?");
2057 oldpass = *password;
2060 int policy_min_pw_len = 0;
2061 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
2062 if (NT_STATUS_IS_OK(status)) {
2063 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
2066 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2069 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2070 init_lsa_String(&account, acct_name);
2072 E_md4hash(oldpass, old_nt_hash);
2073 E_md4hash(newpass, new_nt_hash);
2075 E_deshash(oldpass, old_lm_hash);
2076 E_deshash(newpass, new_lm_hash);
2078 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
2079 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2080 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2082 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2083 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2084 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2086 r.in.server = &server;
2087 r.in.account = &account;
2088 r.in.nt_password = &nt_pass;
2089 r.in.nt_verifier = &nt_verifier;
2091 r.in.lm_password = &lm_pass;
2092 r.in.lm_verifier = &lm_verifier;
2094 status = dcerpc_samr_ChangePasswordUser2(p, tctx, &r);
2095 if (allow_password_restriction && NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2096 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
2097 } else if (!NT_STATUS_IS_OK(status)) {
2098 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
2101 *password = newpass;
2108 bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tctx,
2109 const char *account_string,
2110 int policy_min_pw_len,
2112 const char *newpass,
2113 NTTIME last_password_change,
2114 bool handle_reject_reason)
2117 struct samr_ChangePasswordUser3 r;
2119 struct lsa_String server, account, account_bad;
2120 struct samr_CryptPassword nt_pass, lm_pass;
2121 struct samr_Password nt_verifier, lm_verifier;
2123 uint8_t old_nt_hash[16], new_nt_hash[16];
2124 uint8_t old_lm_hash[16], new_lm_hash[16];
2126 struct samr_DomInfo1 *dominfo = NULL;
2127 struct samr_ChangeReject *reject = NULL;
2129 torture_comment(tctx, "Testing ChangePasswordUser3\n");
2131 if (newpass == NULL) {
2133 if (policy_min_pw_len == 0) {
2134 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2136 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len);
2138 } while (check_password_quality(newpass) == false);
2140 torture_comment(tctx, "Using password '%s'\n", newpass);
2143 torture_assert(tctx, *password != NULL,
2144 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2146 oldpass = *password;
2147 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2148 init_lsa_String(&account, account_string);
2150 E_md4hash(oldpass, old_nt_hash);
2151 E_md4hash(newpass, new_nt_hash);
2153 E_deshash(oldpass, old_lm_hash);
2154 E_deshash(newpass, new_lm_hash);
2156 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2157 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2158 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2160 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2161 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2162 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2164 /* Break the verification */
2165 nt_verifier.hash[0]++;
2167 r.in.server = &server;
2168 r.in.account = &account;
2169 r.in.nt_password = &nt_pass;
2170 r.in.nt_verifier = &nt_verifier;
2172 r.in.lm_password = &lm_pass;
2173 r.in.lm_verifier = &lm_verifier;
2174 r.in.password3 = NULL;
2175 r.out.dominfo = &dominfo;
2176 r.out.reject = &reject;
2178 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2179 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
2180 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
2181 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
2186 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2187 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2188 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2190 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2191 /* Break the NT hash */
2193 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2194 /* Unbreak it again */
2196 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2198 r.in.server = &server;
2199 r.in.account = &account;
2200 r.in.nt_password = &nt_pass;
2201 r.in.nt_verifier = &nt_verifier;
2203 r.in.lm_password = &lm_pass;
2204 r.in.lm_verifier = &lm_verifier;
2205 r.in.password3 = NULL;
2206 r.out.dominfo = &dominfo;
2207 r.out.reject = &reject;
2209 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2210 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
2211 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
2212 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
2217 /* This shouldn't be a valid name */
2218 init_lsa_String(&account_bad, talloc_asprintf(tctx, "%sXX", account_string));
2220 r.in.account = &account_bad;
2221 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2222 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
2223 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
2228 E_md4hash(oldpass, old_nt_hash);
2229 E_md4hash(newpass, new_nt_hash);
2231 E_deshash(oldpass, old_lm_hash);
2232 E_deshash(newpass, new_lm_hash);
2234 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2235 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2236 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2238 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2239 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2240 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2242 r.in.server = &server;
2243 r.in.account = &account;
2244 r.in.nt_password = &nt_pass;
2245 r.in.nt_verifier = &nt_verifier;
2247 r.in.lm_password = &lm_pass;
2248 r.in.lm_verifier = &lm_verifier;
2249 r.in.password3 = NULL;
2250 r.out.dominfo = &dominfo;
2251 r.out.reject = &reject;
2253 unix_to_nt_time(&t, time(NULL));
2255 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2257 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
2260 && handle_reject_reason
2261 && (!null_nttime(last_password_change) || !dominfo->min_password_age)) {
2262 if (dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
2264 if (reject && (reject->reason != SAMR_REJECT_OTHER)) {
2265 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2266 SAMR_REJECT_OTHER, reject->reason);
2271 /* We tested the order of precendence which is as follows:
2280 if ((dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
2281 (last_password_change + dominfo->min_password_age > t)) {
2283 if (reject->reason != SAMR_REJECT_OTHER) {
2284 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2285 SAMR_REJECT_OTHER, reject->reason);
2289 } else if ((dominfo->min_password_length > 0) &&
2290 (strlen(newpass) < dominfo->min_password_length)) {
2292 if (reject->reason != SAMR_REJECT_TOO_SHORT) {
2293 printf("expected SAMR_REJECT_TOO_SHORT (%d), got %d\n",
2294 SAMR_REJECT_TOO_SHORT, reject->reason);
2298 } else if ((dominfo->password_history_length > 0) &&
2299 strequal(oldpass, newpass)) {
2301 if (reject->reason != SAMR_REJECT_IN_HISTORY) {
2302 printf("expected SAMR_REJECT_IN_HISTORY (%d), got %d\n",
2303 SAMR_REJECT_IN_HISTORY, reject->reason);
2306 } else if (dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
2308 if (reject->reason != SAMR_REJECT_COMPLEXITY) {
2309 printf("expected SAMR_REJECT_COMPLEXITY (%d), got %d\n",
2310 SAMR_REJECT_COMPLEXITY, reject->reason);
2316 if (reject->reason == SAMR_REJECT_TOO_SHORT) {
2317 /* retry with adjusted size */
2318 return test_ChangePasswordUser3(p, tctx, account_string,
2319 dominfo->min_password_length,
2320 password, NULL, 0, false);
2324 } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2325 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2326 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2327 SAMR_REJECT_OTHER, reject->reason);
2330 /* Perhaps the server has a 'min password age' set? */
2333 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3");
2334 *password = talloc_strdup(tctx, newpass);
2340 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_context *tctx,
2341 const char *account_string,
2342 struct policy_handle *handle,
2346 struct samr_ChangePasswordUser3 r;
2347 struct samr_SetUserInfo s;
2348 union samr_UserInfo u;
2349 DATA_BLOB session_key;
2350 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
2351 uint8_t confounder[16];
2352 struct MD5Context ctx;
2355 struct lsa_String server, account;
2356 struct samr_CryptPassword nt_pass;
2357 struct samr_Password nt_verifier;
2358 DATA_BLOB new_random_pass;
2361 uint8_t old_nt_hash[16], new_nt_hash[16];
2363 struct samr_DomInfo1 *dominfo = NULL;
2364 struct samr_ChangeReject *reject = NULL;
2366 new_random_pass = samr_very_rand_pass(tctx, 128);
2368 torture_assert(tctx, *password != NULL,
2369 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2371 oldpass = *password;
2372 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2373 init_lsa_String(&account, account_string);
2375 s.in.user_handle = handle;
2381 u.info25.info.fields_present = SAMR_FIELD_NT_PASSWORD_PRESENT;
2383 set_pw_in_buffer(u.info25.password.data, &new_random_pass);
2385 status = dcerpc_fetch_session_key(p, &session_key);
2386 if (!NT_STATUS_IS_OK(status)) {
2387 printf("SetUserInfo level %u - no session key - %s\n",
2388 s.in.level, nt_errstr(status));
2392 generate_random_buffer((uint8_t *)confounder, 16);
2395 MD5Update(&ctx, confounder, 16);
2396 MD5Update(&ctx, session_key.data, session_key.length);
2397 MD5Final(confounded_session_key.data, &ctx);
2399 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
2400 memcpy(&u.info25.password.data[516], confounder, 16);
2402 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
2404 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
2405 if (!NT_STATUS_IS_OK(status)) {
2406 printf("SetUserInfo level %u failed - %s\n",
2407 s.in.level, nt_errstr(status));
2411 torture_comment(tctx, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
2413 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2415 new_random_pass = samr_very_rand_pass(tctx, 128);
2417 mdfour(new_nt_hash, new_random_pass.data, new_random_pass.length);
2419 set_pw_in_buffer(nt_pass.data, &new_random_pass);
2420 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2421 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2423 r.in.server = &server;
2424 r.in.account = &account;
2425 r.in.nt_password = &nt_pass;
2426 r.in.nt_verifier = &nt_verifier;
2428 r.in.lm_password = NULL;
2429 r.in.lm_verifier = NULL;
2430 r.in.password3 = NULL;
2431 r.out.dominfo = &dominfo;
2432 r.out.reject = &reject;
2434 unix_to_nt_time(&t, time(NULL));
2436 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2438 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2439 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2440 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2441 SAMR_REJECT_OTHER, reject->reason);
2444 /* Perhaps the server has a 'min password age' set? */
2446 } else if (!NT_STATUS_IS_OK(status)) {
2447 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
2451 newpass = samr_rand_pass(tctx, 128);
2453 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2455 E_md4hash(newpass, new_nt_hash);
2457 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2458 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2459 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2461 r.in.server = &server;
2462 r.in.account = &account;
2463 r.in.nt_password = &nt_pass;
2464 r.in.nt_verifier = &nt_verifier;
2466 r.in.lm_password = NULL;
2467 r.in.lm_verifier = NULL;
2468 r.in.password3 = NULL;
2469 r.out.dominfo = &dominfo;
2470 r.out.reject = &reject;
2472 unix_to_nt_time(&t, time(NULL));
2474 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2476 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2477 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2478 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2479 SAMR_REJECT_OTHER, reject->reason);
2482 /* Perhaps the server has a 'min password age' set? */
2485 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3 (on second random password)");
2486 *password = talloc_strdup(tctx, newpass);
2493 static bool test_GetMembersInAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2494 struct policy_handle *alias_handle)
2496 struct samr_GetMembersInAlias r;
2497 struct lsa_SidArray sids;
2500 torture_comment(tctx, "Testing GetMembersInAlias\n");
2502 r.in.alias_handle = alias_handle;
2505 status = dcerpc_samr_GetMembersInAlias(p, tctx, &r);
2506 torture_assert_ntstatus_ok(tctx, status, "GetMembersInAlias");
2511 static bool test_AddMemberToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2512 struct policy_handle *alias_handle,
2513 const struct dom_sid *domain_sid)
2515 struct samr_AddAliasMember r;
2516 struct samr_DeleteAliasMember d;
2518 struct dom_sid *sid;
2520 sid = dom_sid_add_rid(tctx, domain_sid, 512);
2522 torture_comment(tctx, "testing AddAliasMember\n");
2523 r.in.alias_handle = alias_handle;
2526 status = dcerpc_samr_AddAliasMember(p, tctx, &r);
2527 torture_assert_ntstatus_ok(tctx, status, "AddAliasMember");
2529 d.in.alias_handle = alias_handle;
2532 status = dcerpc_samr_DeleteAliasMember(p, tctx, &d);
2533 torture_assert_ntstatus_ok(tctx, status, "DelAliasMember");
2538 static bool test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2539 struct policy_handle *alias_handle)
2541 struct samr_AddMultipleMembersToAlias a;
2542 struct samr_RemoveMultipleMembersFromAlias r;
2544 struct lsa_SidArray sids;
2546 torture_comment(tctx, "testing AddMultipleMembersToAlias\n");
2547 a.in.alias_handle = alias_handle;
2551 sids.sids = talloc_array(tctx, struct lsa_SidPtr, 3);
2553 sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2554 sids.sids[1].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-2");
2555 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-3");
2557 status = dcerpc_samr_AddMultipleMembersToAlias(p, tctx, &a);
2558 torture_assert_ntstatus_ok(tctx, status, "AddMultipleMembersToAlias");
2561 torture_comment(tctx, "testing RemoveMultipleMembersFromAlias\n");
2562 r.in.alias_handle = alias_handle;
2565 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2566 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2568 /* strange! removing twice doesn't give any error */
2569 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2570 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2572 /* but removing an alias that isn't there does */
2573 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-4");
2575 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2576 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, "RemoveMultipleMembersFromAlias");
2581 static bool test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2582 struct policy_handle *user_handle)
2584 struct samr_TestPrivateFunctionsUser r;
2587 torture_comment(tctx, "Testing TestPrivateFunctionsUser\n");
2589 r.in.user_handle = user_handle;
2591 status = dcerpc_samr_TestPrivateFunctionsUser(p, tctx, &r);
2592 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsUser");
2597 static bool test_QueryUserInfo_pwdlastset(struct dcerpc_pipe *p,
2598 struct torture_context *tctx,
2599 struct policy_handle *handle,
2604 uint16_t levels[] = { /* 3, */ 5, 21 };
2606 NTTIME pwdlastset3 = 0;
2607 NTTIME pwdlastset5 = 0;
2608 NTTIME pwdlastset21 = 0;
2610 torture_comment(tctx, "Testing QueryUserInfo%s level 5 and 21 call ",
2611 use_info2 ? "2":"");
2613 for (i=0; i<ARRAY_SIZE(levels); i++) {
2615 struct samr_QueryUserInfo r;
2616 struct samr_QueryUserInfo2 r2;
2617 union samr_UserInfo *info;
2620 r2.in.user_handle = handle;
2621 r2.in.level = levels[i];
2622 r2.out.info = &info;
2623 status = dcerpc_samr_QueryUserInfo2(p, tctx, &r2);
2626 r.in.user_handle = handle;
2627 r.in.level = levels[i];
2629 status = dcerpc_samr_QueryUserInfo(p, tctx, &r);
2632 if (!NT_STATUS_IS_OK(status) &&
2633 !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
2634 printf("QueryUserInfo%s level %u failed - %s\n",
2635 use_info2 ? "2":"", levels[i], nt_errstr(status));
2639 switch (levels[i]) {
2641 pwdlastset3 = info->info3.last_password_change;
2644 pwdlastset5 = info->info5.last_password_change;
2647 pwdlastset21 = info->info21.last_password_change;
2653 /* torture_assert_int_equal(tctx, pwdlastset3, pwdlastset5,
2654 "pwdlastset mixup"); */
2655 torture_assert_int_equal(tctx, pwdlastset5, pwdlastset21,
2656 "pwdlastset mixup");
2658 *pwdlastset = pwdlastset21;
2660 torture_comment(tctx, "(pwdlastset: %lld)\n", *pwdlastset);
2665 static bool test_SamLogon_Creds(struct dcerpc_pipe *p, struct torture_context *tctx,
2666 struct cli_credentials *machine_credentials,
2667 struct cli_credentials *test_credentials,
2668 struct netlogon_creds_CredentialState *creds,
2669 NTSTATUS expected_result)
2672 struct netr_LogonSamLogon r;
2673 struct netr_Authenticator auth, auth2;
2674 union netr_LogonLevel logon;
2675 union netr_Validation validation;
2676 uint8_t authoritative;
2677 struct netr_NetworkInfo ninfo;
2678 DATA_BLOB names_blob, chal, lm_resp, nt_resp;
2679 int flags = CLI_CRED_NTLM_AUTH;
2681 if (lp_client_lanman_auth(tctx->lp_ctx)) {
2682 flags |= CLI_CRED_LANMAN_AUTH;
2685 if (lp_client_ntlmv2_auth(tctx->lp_ctx)) {
2686 flags |= CLI_CRED_NTLMv2_AUTH;
2689 cli_credentials_get_ntlm_username_domain(test_credentials, tctx,
2690 &ninfo.identity_info.account_name.string,
2691 &ninfo.identity_info.domain_name.string);
2693 generate_random_buffer(ninfo.challenge,
2694 sizeof(ninfo.challenge));
2695 chal = data_blob_const(ninfo.challenge,
2696 sizeof(ninfo.challenge));
2698 names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(machine_credentials),
2699 cli_credentials_get_domain(machine_credentials));
2701 status = cli_credentials_get_ntlm_response(test_credentials, tctx,
2707 torture_assert_ntstatus_ok(tctx, status, "cli_credentials_get_ntlm_response failed");
2709 ninfo.lm.data = lm_resp.data;
2710 ninfo.lm.length = lm_resp.length;
2712 ninfo.nt.data = nt_resp.data;
2713 ninfo.nt.length = nt_resp.length;
2715 ninfo.identity_info.parameter_control =
2716 MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT |
2717 MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;
2718 ninfo.identity_info.logon_id_low = 0;
2719 ninfo.identity_info.logon_id_high = 0;
2720 ninfo.identity_info.workstation.string = cli_credentials_get_workstation(machine_credentials);
2722 logon.network = &ninfo;
2724 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2725 r.in.computer_name = cli_credentials_get_workstation(machine_credentials);
2726 r.in.credential = &auth;
2727 r.in.return_authenticator = &auth2;
2728 r.in.logon_level = 2;
2729 r.in.logon = &logon;
2730 r.out.validation = &validation;
2731 r.out.authoritative = &authoritative;
2733 d_printf("Testing LogonSamLogon with name %s\n", ninfo.identity_info.account_name.string);
2736 netlogon_creds_client_authenticator(creds, &auth);
2738 r.in.validation_level = 2;
2740 status = dcerpc_netr_LogonSamLogon(p, tctx, &r);
2741 if (!NT_STATUS_IS_OK(status)) {
2742 torture_assert_ntstatus_equal(tctx, status, expected_result, "LogonSamLogon failed");
2745 torture_assert_ntstatus_ok(tctx, status, "LogonSamLogon failed");
2748 torture_assert(tctx, netlogon_creds_client_check(creds, &r.out.return_authenticator->cred),
2749 "Credential chaining failed");
2754 static bool test_SamLogon(struct torture_context *tctx,
2755 struct dcerpc_pipe *p,
2756 struct cli_credentials *machine_credentials,
2757 struct cli_credentials *test_credentials,
2758 NTSTATUS expected_result)
2760 struct netlogon_creds_CredentialState *creds;
2762 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
2766 return test_SamLogon_Creds(p, tctx, machine_credentials, test_credentials,
2767 creds, expected_result);
2770 static bool test_SamLogon_with_creds(struct torture_context *tctx,
2771 struct dcerpc_pipe *p,
2772 struct cli_credentials *machine_creds,
2773 const char *acct_name,
2775 NTSTATUS expected_samlogon_result)
2778 struct cli_credentials *test_credentials;
2780 test_credentials = cli_credentials_init(tctx);
2782 cli_credentials_set_workstation(test_credentials,
2783 TEST_ACCOUNT_NAME_PWD, CRED_SPECIFIED);
2784 cli_credentials_set_domain(test_credentials,
2785 lp_workgroup(tctx->lp_ctx), CRED_SPECIFIED);
2786 cli_credentials_set_username(test_credentials,
2787 acct_name, CRED_SPECIFIED);
2788 cli_credentials_set_password(test_credentials,
2789 password, CRED_SPECIFIED);
2790 cli_credentials_set_secure_channel_type(test_credentials, SEC_CHAN_BDC);
2792 printf("testing samlogon as %s@%s password: %s\n",
2793 acct_name, TEST_ACCOUNT_NAME_PWD, password);
2795 if (!test_SamLogon(tctx, p, machine_creds, test_credentials,
2796 expected_samlogon_result)) {
2797 torture_warning(tctx, "new password did not work\n");
2804 static bool test_SetPassword_level(struct dcerpc_pipe *p,
2805 struct dcerpc_pipe *np,
2806 struct torture_context *tctx,
2807 struct policy_handle *handle,
2809 uint32_t fields_present,
2810 uint8_t password_expired,
2811 bool *matched_expected_error,
2813 const char *acct_name,
2815 struct cli_credentials *machine_creds,
2816 bool use_queryinfo2,
2818 NTSTATUS expected_samlogon_result)
2820 const char *fields = NULL;
2827 fields = talloc_asprintf(tctx, "(fields_present: 0x%08x)",
2834 torture_comment(tctx, "Testing SetUserInfo%s level %d call "
2835 "(password_expired: %d) %s\n",
2836 use_setinfo2 ? "2":"", level, password_expired,
2837 fields ? fields : "");
2839 if (!test_SetUserPass_level_ex(p, tctx, handle, level,
2844 matched_expected_error)) {
2848 if (!test_QueryUserInfo_pwdlastset(p, tctx, handle,
2854 if (*matched_expected_error == true) {
2858 if (!test_SamLogon_with_creds(tctx, np,
2862 expected_samlogon_result)) {
2869 static bool test_SetPassword_pwdlastset(struct dcerpc_pipe *p,
2870 struct torture_context *tctx,
2871 uint32_t acct_flags,
2872 const char *acct_name,
2873 struct policy_handle *handle,
2875 struct cli_credentials *machine_credentials)
2877 int s = 0, q = 0, f = 0, l = 0, z = 0;
2880 bool set_levels[] = { false, true };
2881 bool query_levels[] = { false, true };
2882 uint32_t levels[] = { 18, 21, 23, 24, 25, 26 };
2883 uint32_t nonzeros[] = { 1, 24 };
2884 uint32_t fields_present[] = {
2886 SAMR_FIELD_EXPIRED_FLAG,
2887 SAMR_FIELD_LAST_PWD_CHANGE,
2888 SAMR_FIELD_EXPIRED_FLAG | SAMR_FIELD_LAST_PWD_CHANGE,
2890 SAMR_FIELD_NT_PASSWORD_PRESENT,
2891 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
2892 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
2893 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
2894 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
2895 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
2896 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE | SAMR_FIELD_EXPIRED_FLAG
2899 struct dcerpc_pipe *np = NULL;
2901 if (torture_setting_bool(tctx, "samba3", false)) {
2903 printf("Samba3 has second granularity, setting delay to: %d\n",
2907 status = torture_rpc_connection(tctx, &np, &ndr_table_netlogon);
2908 if (!NT_STATUS_IS_OK(status)) {
2912 /* set to 1 to enable testing for all possible opcode
2913 (SetUserInfo, SetUserInfo2, QueryUserInfo, QueryUserInfo2)
2916 #define TEST_SET_LEVELS 1
2917 #define TEST_QUERY_LEVELS 1
2919 for (l=0; l<ARRAY_SIZE(levels); l++) {
2920 for (z=0; z<ARRAY_SIZE(nonzeros); z++) {
2921 for (f=0; f<ARRAY_SIZE(fields_present); f++) {
2922 #ifdef TEST_SET_LEVELS
2923 for (s=0; s<ARRAY_SIZE(set_levels); s++) {
2925 #ifdef TEST_QUERY_LEVELS
2926 for (q=0; q<ARRAY_SIZE(query_levels); q++) {
2928 NTTIME pwdlastset_old = 0;
2929 NTTIME pwdlastset_new = 0;
2930 bool matched_expected_error = false;
2931 NTSTATUS expected_samlogon_result = NT_STATUS_ACCOUNT_DISABLED;
2933 torture_comment(tctx, "------------------------------\n"
2934 "Testing pwdLastSet attribute for flags: 0x%08x "
2935 "(s: %d (l: %d), q: %d)\n",
2936 acct_flags, s, levels[l], q);
2938 switch (levels[l]) {
2942 if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
2943 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT))) {
2944 expected_samlogon_result = NT_STATUS_WRONG_PASSWORD;
2952 /* set a password and force password change (pwdlastset 0) by
2953 * setting the password expired flag to a non-0 value */
2955 if (!test_SetPassword_level(p, np, tctx, handle,
2959 &matched_expected_error,
2963 machine_credentials,
2966 expected_samlogon_result)) {
2970 if (matched_expected_error == true) {
2971 /* skipping on expected failure */
2975 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
2976 * set without the SAMR_FIELD_EXPIRED_FLAG */
2978 switch (levels[l]) {
2982 if ((pwdlastset_new != 0) &&
2983 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
2984 torture_comment(tctx, "not considering a non-0 "
2985 "pwdLastSet as a an error as the "
2986 "SAMR_FIELD_EXPIRED_FLAG has not "
2991 if (pwdlastset_new != 0) {
2992 torture_warning(tctx, "pwdLastSet test failed: "
2993 "expected pwdLastSet 0 but got %lld\n",
3000 switch (levels[l]) {
3004 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3005 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3006 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3007 (pwdlastset_old >= pwdlastset_new)) {
3008 torture_warning(tctx, "pwdlastset not increasing\n");
3013 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3014 (pwdlastset_old >= pwdlastset_new)) {
3015 torture_warning(tctx, "pwdlastset not increasing\n");
3025 /* set a password, pwdlastset needs to get updated (increased
3026 * value), password_expired value used here is 0 */
3028 if (!test_SetPassword_level(p, np, tctx, handle,
3032 &matched_expected_error,
3036 machine_credentials,
3039 expected_samlogon_result)) {
3043 /* when a password has been changed, pwdlastset must not be 0 afterwards
3044 * and must be larger then the old value */
3046 switch (levels[l]) {
3051 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3052 * password has been changed, old and new pwdlastset
3053 * need to be the same value */
3055 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3056 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3057 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3059 torture_assert_int_equal(tctx, pwdlastset_old,
3060 pwdlastset_new, "pwdlastset must be equal");
3064 if (pwdlastset_old >= pwdlastset_new) {
3065 torture_warning(tctx, "pwdLastSet test failed: "
3066 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
3067 pwdlastset_old, pwdlastset_new);
3070 if (pwdlastset_new == 0) {
3071 torture_warning(tctx, "pwdLastSet test failed: "
3072 "expected non-0 pwdlastset, got: %lld\n",
3078 switch (levels[l]) {
3082 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3083 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3084 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3085 (pwdlastset_old >= pwdlastset_new)) {
3086 torture_warning(tctx, "pwdlastset not increasing\n");
3091 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3092 (pwdlastset_old >= pwdlastset_new)) {
3093 torture_warning(tctx, "pwdlastset not increasing\n");
3099 pwdlastset_old = pwdlastset_new;
3105 /* set a password, pwdlastset needs to get updated (increased
3106 * value), password_expired value used here is 0 */
3108 if (!test_SetPassword_level(p, np, tctx, handle,
3112 &matched_expected_error,
3116 machine_credentials,
3119 expected_samlogon_result)) {
3123 /* when a password has been changed, pwdlastset must not be 0 afterwards
3124 * and must be larger then the old value */
3126 switch (levels[l]) {
3131 /* if no password has been changed, old and new pwdlastset
3132 * need to be the same value */
3134 if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3135 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3137 torture_assert_int_equal(tctx, pwdlastset_old,
3138 pwdlastset_new, "pwdlastset must be equal");
3142 if (pwdlastset_old >= pwdlastset_new) {
3143 torture_warning(tctx, "pwdLastSet test failed: "
3144 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
3145 pwdlastset_old, pwdlastset_new);
3148 if (pwdlastset_new == 0) {
3149 torture_warning(tctx, "pwdLastSet test failed: "
3150 "expected non-0 pwdlastset, got: %lld\n",
3158 /* set a password and force password change (pwdlastset 0) by
3159 * setting the password expired flag to a non-0 value */
3161 if (!test_SetPassword_level(p, np, tctx, handle,
3165 &matched_expected_error,
3169 machine_credentials,
3172 expected_samlogon_result)) {
3176 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3177 * set without the SAMR_FIELD_EXPIRED_FLAG */
3179 switch (levels[l]) {
3183 if ((pwdlastset_new != 0) &&
3184 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
3185 torture_comment(tctx, "not considering a non-0 "
3186 "pwdLastSet as a an error as the "
3187 "SAMR_FIELD_EXPIRED_FLAG has not "
3192 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3193 * password has been changed, old and new pwdlastset
3194 * need to be the same value */
3196 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3197 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3198 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3200 torture_assert_int_equal(tctx, pwdlastset_old,
3201 pwdlastset_new, "pwdlastset must be equal");
3206 if (pwdlastset_old == pwdlastset_new) {
3207 torture_warning(tctx, "pwdLastSet test failed: "
3208 "expected last pwdlastset (%lld) != new pwdlastset (%lld)\n",
3209 pwdlastset_old, pwdlastset_new);
3213 if (pwdlastset_new != 0) {
3214 torture_warning(tctx, "pwdLastSet test failed: "
3215 "expected pwdLastSet 0, got %lld\n",
3222 switch (levels[l]) {
3226 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3227 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3228 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3229 (pwdlastset_old >= pwdlastset_new)) {
3230 torture_warning(tctx, "pwdlastset not increasing\n");
3235 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3236 (pwdlastset_old >= pwdlastset_new)) {
3237 torture_warning(tctx, "pwdlastset not increasing\n");
3243 /* if the level we are testing does not have a fields_present
3244 * field, skip all fields present tests by setting f to to
3246 switch (levels[l]) {
3250 f = ARRAY_SIZE(fields_present);
3254 #ifdef TEST_QUERY_LEVELS
3257 #ifdef TEST_SET_LEVELS
3260 } /* fields present */
3264 #undef TEST_SET_LEVELS
3265 #undef TEST_QUERY_LEVELS
3270 static bool test_user_ops(struct dcerpc_pipe *p,
3271 struct torture_context *tctx,
3272 struct policy_handle *user_handle,
3273 struct policy_handle *domain_handle,
3274 uint32_t base_acct_flags,
3275 const char *base_acct_name, enum torture_samr_choice which_ops,
3276 struct cli_credentials *machine_credentials)
3278 char *password = NULL;
3279 struct samr_QueryUserInfo q;
3280 union samr_UserInfo *info;
3286 const uint32_t password_fields[] = {
3287 SAMR_FIELD_NT_PASSWORD_PRESENT,
3288 SAMR_FIELD_LM_PASSWORD_PRESENT,
3289 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
3293 status = test_LookupName(p, tctx, domain_handle, base_acct_name, &rid);
3294 if (!NT_STATUS_IS_OK(status)) {
3298 switch (which_ops) {
3299 case TORTURE_SAMR_USER_ATTRIBUTES:
3300 if (!test_QuerySecurity(p, tctx, user_handle)) {
3304 if (!test_QueryUserInfo(p, tctx, user_handle)) {
3308 if (!test_QueryUserInfo2(p, tctx, user_handle)) {
3312 if (!test_SetUserInfo(p, tctx, user_handle, base_acct_flags,
3317 if (!test_GetUserPwInfo(p, tctx, user_handle)) {
3321 if (!test_TestPrivateFunctionsUser(p, tctx, user_handle)) {
3325 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
3329 case TORTURE_SAMR_PASSWORDS:
3330 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
3331 char simple_pass[9];
3332 char *v = generate_random_str(tctx, 1);
3334 ZERO_STRUCT(simple_pass);
3335 memset(simple_pass, *v, sizeof(simple_pass) - 1);
3337 printf("Testing machine account password policy rules\n");
3339 /* Workstation trust accounts don't seem to need to honour password quality policy */
3340 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
3344 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
3348 /* reset again, to allow another 'user' password change */
3349 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
3353 /* Try a 'short' password */
3354 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
3358 /* Try a compleatly random password */
3359 if (!test_ChangePasswordRandomBytes(p, tctx, base_acct_name, user_handle, &password)) {
3364 for (i = 0; password_fields[i]; i++) {
3365 if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
3369 /* check it was set right */
3370 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3375 for (i = 0; password_fields[i]; i++) {
3376 if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
3380 /* check it was set right */
3381 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3386 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
3390 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
3394 if (torture_setting_bool(tctx, "samba4", false)) {
3395 printf("skipping Set Password level 18 and 21 against Samba4\n");
3398 if (!test_SetUserPass_18(p, tctx, user_handle, &password)) {
3402 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3406 for (i = 0; password_fields[i]; i++) {
3408 if (password_fields[i] == SAMR_FIELD_LM_PASSWORD_PRESENT) {
3409 /* we need to skip as that would break
3410 * the ChangePasswordUser3 verify */
3414 if (!test_SetUserPass_21(p, tctx, user_handle, password_fields[i], &password)) {
3418 /* check it was set right */
3419 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3425 q.in.user_handle = user_handle;
3429 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
3430 if (!NT_STATUS_IS_OK(status)) {
3431 printf("QueryUserInfo level %u failed - %s\n",
3432 q.in.level, nt_errstr(status));
3435 uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
3436 if ((info->info5.acct_flags) != expected_flags) {
3437 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
3438 info->info5.acct_flags,
3441 if (!torture_setting_bool(tctx, "samba3", false)) {
3445 if (info->info5.rid != rid) {
3446 printf("QuerUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
3447 info->info5.rid, rid);
3454 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
3456 /* test last password change timestamp behaviour */
3457 if (!test_SetPassword_pwdlastset(p, tctx, base_acct_flags,
3459 user_handle, &password,
3460 machine_credentials)) {
3465 torture_comment(tctx, "pwdLastSet test succeeded\n");
3467 torture_warning(tctx, "pwdLastSet test failed\n");
3472 case TORTURE_SAMR_OTHER:
3473 /* We just need the account to exist */
3479 static bool test_alias_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
3480 struct policy_handle *alias_handle,
3481 const struct dom_sid *domain_sid)
3485 if (!test_QuerySecurity(p, tctx, alias_handle)) {
3489 if (!test_QueryAliasInfo(p, tctx, alias_handle)) {
3493 if (!test_SetAliasInfo(p, tctx, alias_handle)) {
3497 if (!test_AddMemberToAlias(p, tctx, alias_handle, domain_sid)) {
3501 if (torture_setting_bool(tctx, "samba4", false)) {
3502 printf("skipping MultipleMembers Alias tests against Samba4\n");
3506 if (!test_AddMultipleMembersToAlias(p, tctx, alias_handle)) {
3514 static bool test_DeleteUser(struct dcerpc_pipe *p, struct torture_context *tctx,
3515 struct policy_handle *user_handle)
3517 struct samr_DeleteUser d;
3519 torture_comment(tctx, "Testing DeleteUser\n");
3521 d.in.user_handle = user_handle;
3522 d.out.user_handle = user_handle;
3524 status = dcerpc_samr_DeleteUser(p, tctx, &d);
3525 torture_assert_ntstatus_ok(tctx, status, "DeleteUser");
3530 bool test_DeleteUser_byname(struct dcerpc_pipe *p,
3531 struct torture_context *tctx,
3532 struct policy_handle *handle, const char *name)
3535 struct samr_DeleteUser d;
3536 struct policy_handle user_handle;
3539 status = test_LookupName(p, tctx, handle, name, &rid);
3540 if (!NT_STATUS_IS_OK(status)) {
3544 status = test_OpenUser_byname(p, tctx, handle, name, &user_handle);
3545 if (!NT_STATUS_IS_OK(status)) {
3549 d.in.user_handle = &user_handle;
3550 d.out.user_handle = &user_handle;
3551 status = dcerpc_samr_DeleteUser(p, tctx, &d);
3552 if (!NT_STATUS_IS_OK(status)) {
3559 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
3564 static bool test_DeleteGroup_byname(struct dcerpc_pipe *p,
3565 struct torture_context *tctx,
3566 struct policy_handle *handle, const char *name)
3569 struct samr_OpenGroup r;
3570 struct samr_DeleteDomainGroup d;
3571 struct policy_handle group_handle;
3574 status = test_LookupName(p, tctx, handle, name, &rid);
3575 if (!NT_STATUS_IS_OK(status)) {
3579 r.in.domain_handle = handle;
3580 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3582 r.out.group_handle = &group_handle;
3583 status = dcerpc_samr_OpenGroup(p, tctx, &r);
3584 if (!NT_STATUS_IS_OK(status)) {
3588 d.in.group_handle = &group_handle;
3589 d.out.group_handle = &group_handle;
3590 status = dcerpc_samr_DeleteDomainGroup(p, tctx, &d);
3591 if (!NT_STATUS_IS_OK(status)) {
3598 printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
3603 static bool test_DeleteAlias_byname(struct dcerpc_pipe *p,
3604 struct torture_context *tctx,
3605 struct policy_handle *domain_handle,
3609 struct samr_OpenAlias r;
3610 struct samr_DeleteDomAlias d;
3611 struct policy_handle alias_handle;
3614 printf("testing DeleteAlias_byname\n");
3616 status = test_LookupName(p, tctx, domain_handle, name, &rid);
3617 if (!NT_STATUS_IS_OK(status)) {
3621 r.in.domain_handle = domain_handle;
3622 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3624 r.out.alias_handle = &alias_handle;
3625 status = dcerpc_samr_OpenAlias(p, tctx, &r);
3626 if (!NT_STATUS_IS_OK(status)) {
3630 d.in.alias_handle = &alias_handle;
3631 d.out.alias_handle = &alias_handle;
3632 status = dcerpc_samr_DeleteDomAlias(p, tctx, &d);
3633 if (!NT_STATUS_IS_OK(status)) {
3640 printf("DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
3644 static bool test_DeleteAlias(struct dcerpc_pipe *p,
3645 struct torture_context *tctx,
3646 struct policy_handle *alias_handle)
3648 struct samr_DeleteDomAlias d;
3651 printf("Testing DeleteAlias\n");
3653 d.in.alias_handle = alias_handle;
3654 d.out.alias_handle = alias_handle;
3656 status = dcerpc_samr_DeleteDomAlias(p, tctx, &d);
3657 if (!NT_STATUS_IS_OK(status)) {
3658 printf("DeleteAlias failed - %s\n", nt_errstr(status));
3665 static bool test_CreateAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
3666 struct policy_handle *domain_handle,
3667 struct policy_handle *alias_handle,
3668 const struct dom_sid *domain_sid)
3671 struct samr_CreateDomAlias r;
3672 struct lsa_String name;
3676 init_lsa_String(&name, TEST_ALIASNAME);
3677 r.in.domain_handle = domain_handle;
3678 r.in.alias_name = &name;
3679 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3680 r.out.alias_handle = alias_handle;
3683 printf("Testing CreateAlias (%s)\n", r.in.alias_name->string);
3685 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
3687 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
3688 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
3689 printf("Server correctly refused create of '%s'\n", r.in.alias_name->string);
3692 printf("Server should have refused create of '%s', got %s instead\n", r.in.alias_name->string,
3698 if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
3699 if (!test_DeleteAlias_byname(p, tctx, domain_handle, r.in.alias_name->string)) {
3702 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
3705 if (!NT_STATUS_IS_OK(status)) {
3706 printf("CreateAlias failed - %s\n", nt_errstr(status));
3710 if (!test_alias_ops(p, tctx, alias_handle, domain_sid)) {
3717 static bool test_ChangePassword(struct dcerpc_pipe *p,
3718 struct torture_context *tctx,
3719 const char *acct_name,
3720 struct policy_handle *domain_handle, char **password)
3728 if (!test_ChangePasswordUser(p, tctx, acct_name, domain_handle, password)) {
3732 if (!test_ChangePasswordUser2(p, tctx, acct_name, password, 0, true)) {
3736 if (!test_OemChangePasswordUser2(p, tctx, acct_name, domain_handle, password)) {
3740 /* test what happens when setting the old password again */
3741 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, *password, 0, true)) {
3746 char simple_pass[9];
3747 char *v = generate_random_str(tctx, 1);
3749 ZERO_STRUCT(simple_pass);
3750 memset(simple_pass, *v, sizeof(simple_pass) - 1);
3752 /* test what happens when picking a simple password */
3753 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, simple_pass, 0, true)) {
3758 /* set samr_SetDomainInfo level 1 with min_length 5 */
3760 struct samr_QueryDomainInfo r;
3761 union samr_DomainInfo *info = NULL;
3762 struct samr_SetDomainInfo s;
3763 uint16_t len_old, len;
3764 uint32_t pwd_prop_old;
3765 int64_t min_pwd_age_old;
3770 r.in.domain_handle = domain_handle;
3774 printf("testing samr_QueryDomainInfo level 1\n");
3775 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
3776 if (!NT_STATUS_IS_OK(status)) {
3780 s.in.domain_handle = domain_handle;
3784 /* remember the old min length, so we can reset it */
3785 len_old = s.in.info->info1.min_password_length;
3786 s.in.info->info1.min_password_length = len;
3787 pwd_prop_old = s.in.info->info1.password_properties;
3788 /* turn off password complexity checks for this test */
3789 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
3791 min_pwd_age_old = s.in.info->info1.min_password_age;
3792 s.in.info->info1.min_password_age = 0;
3794 printf("testing samr_SetDomainInfo level 1\n");
3795 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
3796 if (!NT_STATUS_IS_OK(status)) {
3800 printf("calling test_ChangePasswordUser3 with too short password\n");
3802 if (!test_ChangePasswordUser3(p, tctx, acct_name, len - 1, password, NULL, 0, true)) {
3806 s.in.info->info1.min_password_length = len_old;
3807 s.in.info->info1.password_properties = pwd_prop_old;
3808 s.in.info->info1.min_password_age = min_pwd_age_old;
3810 printf("testing samr_SetDomainInfo level 1\n");
3811 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
3812 if (!NT_STATUS_IS_OK(status)) {
3820 struct samr_OpenUser r;
3821 struct samr_QueryUserInfo q;
3822 union samr_UserInfo *info;
3823 struct samr_LookupNames n;
3824 struct policy_handle user_handle;
3825 struct samr_Ids rids, types;
3827 n.in.domain_handle = domain_handle;
3829 n.in.names = talloc_array(tctx, struct lsa_String, 1);
3830 n.in.names[0].string = acct_name;
3832 n.out.types = &types;
3834 status = dcerpc_samr_LookupNames(p, tctx, &n);
3835 if (!NT_STATUS_IS_OK(status)) {
3836 printf("LookupNames failed - %s\n", nt_errstr(status));
3840 r.in.domain_handle = domain_handle;
3841 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3842 r.in.rid = n.out.rids->ids[0];
3843 r.out.user_handle = &user_handle;
3845 status = dcerpc_samr_OpenUser(p, tctx, &r);
3846 if (!NT_STATUS_IS_OK(status)) {
3847 printf("OpenUser(%u) failed - %s\n", n.out.rids->ids[0], nt_errstr(status));
3851 q.in.user_handle = &user_handle;
3855 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
3856 if (!NT_STATUS_IS_OK(status)) {
3857 printf("QueryUserInfo failed - %s\n", nt_errstr(status));
3861 printf("calling test_ChangePasswordUser3 with too early password change\n");
3863 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL,
3864 info->info5.last_password_change, true)) {
3869 /* we change passwords twice - this has the effect of verifying
3870 they were changed correctly for the final call */
3871 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
3875 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
3882 static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
3883 struct policy_handle *domain_handle,
3884 struct policy_handle *user_handle_out,
3885 struct dom_sid *domain_sid,
3886 enum torture_samr_choice which_ops,
3887 struct cli_credentials *machine_credentials)
3890 TALLOC_CTX *user_ctx;
3893 struct samr_CreateUser r;
3894 struct samr_QueryUserInfo q;
3895 union samr_UserInfo *info;
3896 struct samr_DeleteUser d;
3899 /* This call creates a 'normal' account - check that it really does */
3900 const uint32_t acct_flags = ACB_NORMAL;
3901 struct lsa_String name;
3904 struct policy_handle user_handle;
3905 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
3906 init_lsa_String(&name, TEST_ACCOUNT_NAME);
3908 r.in.domain_handle = domain_handle;
3909 r.in.account_name = &name;
3910 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3911 r.out.user_handle = &user_handle;
3914 printf("Testing CreateUser(%s)\n", r.in.account_name->string);
3916 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
3918 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
3919 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
3920 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
3923 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
3929 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
3930 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
3931 talloc_free(user_ctx);
3934 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
3936 if (!NT_STATUS_IS_OK(status)) {
3937 talloc_free(user_ctx);
3938 printf("CreateUser failed - %s\n", nt_errstr(status));
3941 q.in.user_handle = &user_handle;
3945 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
3946 if (!NT_STATUS_IS_OK(status)) {
3947 printf("QueryUserInfo level %u failed - %s\n",
3948 q.in.level, nt_errstr(status));
3951 if ((info->info16.acct_flags & acct_flags) != acct_flags) {
3952 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
3953 info->info16.acct_flags,
3959 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
3960 acct_flags, name.string, which_ops,
3961 machine_credentials)) {
3965 if (user_handle_out) {
3966 *user_handle_out = user_handle;
3968 printf("Testing DeleteUser (createuser test)\n");
3970 d.in.user_handle = &user_handle;
3971 d.out.user_handle = &user_handle;
3973 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
3974 if (!NT_STATUS_IS_OK(status)) {
3975 printf("DeleteUser failed - %s\n", nt_errstr(status));
3982 talloc_free(user_ctx);
3988 static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
3989 struct policy_handle *domain_handle,
3990 struct dom_sid *domain_sid,
3991 enum torture_samr_choice which_ops,
3992 struct cli_credentials *machine_credentials)
3995 struct samr_CreateUser2 r;
3996 struct samr_QueryUserInfo q;
3997 union samr_UserInfo *info;
3998 struct samr_DeleteUser d;
3999 struct policy_handle user_handle;
4001 struct lsa_String name;
4006 uint32_t acct_flags;
4007 const char *account_name;
4009 } account_types[] = {
4010 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
4011 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
4012 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
4013 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
4014 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
4015 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
4016 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
4017 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
4018 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
4019 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
4020 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
4021 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
4022 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
4023 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
4024 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
4027 for (i = 0; account_types[i].account_name; i++) {
4028 TALLOC_CTX *user_ctx;
4029 uint32_t acct_flags = account_types[i].acct_flags;
4030 uint32_t access_granted;
4031 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
4032 init_lsa_String(&name, account_types[i].account_name);
4034 r.in.domain_handle = domain_handle;
4035 r.in.account_name = &name;
4036 r.in.acct_flags = acct_flags;
4037 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4038 r.out.user_handle = &user_handle;
4039 r.out.access_granted = &access_granted;
4042 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
4044 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
4046 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
4047 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
4048 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
4051 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
4058 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
4059 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
4060 talloc_free(user_ctx);
4064 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
4067 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
4068 printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
4069 nt_errstr(status), nt_errstr(account_types[i].nt_status));
4073 if (NT_STATUS_IS_OK(status)) {
4074 q.in.user_handle = &user_handle;
4078 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
4079 if (!NT_STATUS_IS_OK(status)) {
4080 printf("QueryUserInfo level %u failed - %s\n",
4081 q.in.level, nt_errstr(status));
4084 uint32_t expected_flags = (acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
4085 if (acct_flags == ACB_NORMAL) {
4086 expected_flags |= ACB_PW_EXPIRED;
4088 if ((info->info5.acct_flags) != expected_flags) {
4089 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
4090 info->info5.acct_flags,
4094 switch (acct_flags) {
4096 if (info->info5.primary_gid != DOMAIN_RID_DCS) {
4097 printf("QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n",
4098 DOMAIN_RID_DCS, info->info5.primary_gid);
4103 if (info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
4104 printf("QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
4105 DOMAIN_RID_DOMAIN_MEMBERS, info->info5.primary_gid);
4110 if (info->info5.primary_gid != DOMAIN_RID_USERS) {
4111 printf("QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n",
4112 DOMAIN_RID_USERS, info->info5.primary_gid);
4119 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
4120 acct_flags, name.string, which_ops,
4121 machine_credentials)) {
4125 printf("Testing DeleteUser (createuser2 test)\n");
4127 d.in.user_handle = &user_handle;
4128 d.out.user_handle = &user_handle;
4130 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
4131 if (!NT_STATUS_IS_OK(status)) {
4132 printf("DeleteUser failed - %s\n", nt_errstr(status));
4136 talloc_free(user_ctx);
4142 static bool test_QueryAliasInfo(struct dcerpc_pipe *p,
4143 struct torture_context *tctx,
4144 struct policy_handle *handle)
4147 struct samr_QueryAliasInfo r;
4148 union samr_AliasInfo *info;
4149 uint16_t levels[] = {1, 2, 3};
4153 for (i=0;i<ARRAY_SIZE(levels);i++) {
4154 printf("Testing QueryAliasInfo level %u\n", levels[i]);
4156 r.in.alias_handle = handle;
4157 r.in.level = levels[i];
4160 status = dcerpc_samr_QueryAliasInfo(p, tctx, &r);
4161 if (!NT_STATUS_IS_OK(status)) {
4162 printf("QueryAliasInfo level %u failed - %s\n",
4163 levels[i], nt_errstr(status));
4171 static bool test_QueryGroupInfo(struct dcerpc_pipe *p,
4172 struct torture_context *tctx,
4173 struct policy_handle *handle)
4176 struct samr_QueryGroupInfo r;
4177 union samr_GroupInfo *info;
4178 uint16_t levels[] = {1, 2, 3, 4, 5};
4182 for (i=0;i<ARRAY_SIZE(levels);i++) {
4183 printf("Testing QueryGroupInfo level %u\n", levels[i]);
4185 r.in.group_handle = handle;
4186 r.in.level = levels[i];
4189 status = dcerpc_samr_QueryGroupInfo(p, tctx, &r);
4190 if (!NT_STATUS_IS_OK(status)) {
4191 printf("QueryGroupInfo level %u failed - %s\n",
4192 levels[i], nt_errstr(status));
4200 static bool test_QueryGroupMember(struct dcerpc_pipe *p,
4201 struct torture_context *tctx,
4202 struct policy_handle *handle)
4205 struct samr_QueryGroupMember r;
4206 struct samr_RidTypeArray *rids = NULL;
4209 printf("Testing QueryGroupMember\n");
4211 r.in.group_handle = handle;
4214 status = dcerpc_samr_QueryGroupMember(p, tctx, &r);
4215 if (!NT_STATUS_IS_OK(status)) {
4216 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
4224 static bool test_SetGroupInfo(struct dcerpc_pipe *p,
4225 struct torture_context *tctx,
4226 struct policy_handle *handle)
4229 struct samr_QueryGroupInfo r;
4230 union samr_GroupInfo *info;
4231 struct samr_SetGroupInfo s;
4232 uint16_t levels[] = {1, 2, 3, 4};
4233 uint16_t set_ok[] = {0, 1, 1, 1};
4237 for (i=0;i<ARRAY_SIZE(levels);i++) {
4238 printf("Testing QueryGroupInfo level %u\n", levels[i]);
4240 r.in.group_handle = handle;
4241 r.in.level = levels[i];
4244 status = dcerpc_samr_QueryGroupInfo(p, tctx, &r);
4245 if (!NT_STATUS_IS_OK(status)) {
4246 printf("QueryGroupInfo level %u failed - %s\n",
4247 levels[i], nt_errstr(status));
4251 printf("Testing SetGroupInfo level %u\n", levels[i]);
4253 s.in.group_handle = handle;
4254 s.in.level = levels[i];
4255 s.in.info = *r.out.info;
4258 /* disabled this, as it changes the name only from the point of view of samr,
4259 but leaves the name from the point of view of w2k3 internals (and ldap). This means
4260 the name is still reserved, so creating the old name fails, but deleting by the old name
4262 if (s.in.level == 2) {
4263 init_lsa_String(&s.in.info->string, "NewName");
4267 if (s.in.level == 4) {
4268 init_lsa_String(&s.in.info->description, "test description");
4271 status = dcerpc_samr_SetGroupInfo(p, tctx, &s);
4273 if (!NT_STATUS_IS_OK(status)) {
4274 printf("SetGroupInfo level %u failed - %s\n",
4275 r.in.level, nt_errstr(status));
4280 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
4281 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
4282 r.in.level, nt_errstr(status));
4292 static bool test_QueryUserInfo(struct dcerpc_pipe *p,
4293 struct torture_context *tctx,
4294 struct policy_handle *handle)
4297 struct samr_QueryUserInfo r;
4298 union samr_UserInfo *info;
4299 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
4300 11, 12, 13, 14, 16, 17, 20, 21};
4304 for (i=0;i<ARRAY_SIZE(levels);i++) {
4305 printf("Testing QueryUserInfo level %u\n", levels[i]);
4307 r.in.user_handle = handle;
4308 r.in.level = levels[i];
4311 status = dcerpc_samr_QueryUserInfo(p, tctx, &r);
4312 if (!NT_STATUS_IS_OK(status)) {
4313 printf("QueryUserInfo level %u failed - %s\n",
4314 levels[i], nt_errstr(status));
4322 static bool test_QueryUserInfo2(struct dcerpc_pipe *p,
4323 struct torture_context *tctx,
4324 struct policy_handle *handle)
4327 struct samr_QueryUserInfo2 r;
4328 union samr_UserInfo *info;
4329 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
4330 11, 12, 13, 14, 16, 17, 20, 21};
4334 for (i=0;i<ARRAY_SIZE(levels);i++) {
4335 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
4337 r.in.user_handle = handle;
4338 r.in.level = levels[i];
4341 status = dcerpc_samr_QueryUserInfo2(p, tctx, &r);
4342 if (!NT_STATUS_IS_OK(status)) {
4343 printf("QueryUserInfo2 level %u failed - %s\n",
4344 levels[i], nt_errstr(status));
4352 static bool test_OpenUser(struct dcerpc_pipe *p,
4353 struct torture_context *tctx,
4354 struct policy_handle *handle, uint32_t rid)
4357 struct samr_OpenUser r;
4358 struct policy_handle user_handle;
4361 printf("Testing OpenUser(%u)\n", rid);
4363 r.in.domain_handle = handle;
4364 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4366 r.out.user_handle = &user_handle;
4368 status = dcerpc_samr_OpenUser(p, tctx, &r);
4369 if (!NT_STATUS_IS_OK(status)) {
4370 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
4374 if (!test_QuerySecurity(p, tctx, &user_handle)) {
4378 if (!test_QueryUserInfo(p, tctx, &user_handle)) {
4382 if (!test_QueryUserInfo2(p, tctx, &user_handle)) {
4386 if (!test_GetUserPwInfo(p, tctx, &user_handle)) {
4390 if (!test_GetGroupsForUser(p,tctx, &user_handle)) {
4394 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
4401 static bool test_OpenGroup(struct dcerpc_pipe *p,
4402 struct torture_context *tctx,
4403 struct policy_handle *handle, uint32_t rid)
4406 struct samr_OpenGroup r;
4407 struct policy_handle group_handle;
4410 printf("Testing OpenGroup(%u)\n", rid);
4412 r.in.domain_handle = handle;
4413 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4415 r.out.group_handle = &group_handle;
4417 status = dcerpc_samr_OpenGroup(p, tctx, &r);
4418 if (!NT_STATUS_IS_OK(status)) {
4419 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
4423 if (!test_QuerySecurity(p, tctx, &group_handle)) {
4427 if (!test_QueryGroupInfo(p, tctx, &group_handle)) {
4431 if (!test_QueryGroupMember(p, tctx, &group_handle)) {
4435 if (!test_samr_handle_Close(p, tctx, &group_handle)) {
4442 static bool test_OpenAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
4443 struct policy_handle *handle, uint32_t rid)
4446 struct samr_OpenAlias r;
4447 struct policy_handle alias_handle;
4450 torture_comment(tctx, "Testing OpenAlias(%u)\n", rid);
4452 r.in.domain_handle = handle;
4453 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4455 r.out.alias_handle = &alias_handle;
4457 status = dcerpc_samr_OpenAlias(p, tctx, &r);
4458 if (!NT_STATUS_IS_OK(status)) {
4459 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
4463 if (!test_QuerySecurity(p, tctx, &alias_handle)) {
4467 if (!test_QueryAliasInfo(p, tctx, &alias_handle)) {
4471 if (!test_GetMembersInAlias(p, tctx, &alias_handle)) {
4475 if (!test_samr_handle_Close(p, tctx, &alias_handle)) {
4482 static bool check_mask(struct dcerpc_pipe *p, struct torture_context *tctx,
4483 struct policy_handle *handle, uint32_t rid,
4484 uint32_t acct_flag_mask)
4487 struct samr_OpenUser r;
4488 struct samr_QueryUserInfo q;
4489 union samr_UserInfo *info;
4490 struct policy_handle user_handle;
4493 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
4495 r.in.domain_handle = handle;
4496 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4498 r.out.user_handle = &user_handle;
4500 status = dcerpc_samr_OpenUser(p, tctx, &r);
4501 if (!NT_STATUS_IS_OK(status)) {
4502 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
4506 q.in.user_handle = &user_handle;
4510 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
4511 if (!NT_STATUS_IS_OK(status)) {
4512 printf("QueryUserInfo level 16 failed - %s\n",
4516 if ((acct_flag_mask & info->info16.acct_flags) == 0) {
4517 printf("Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
4518 acct_flag_mask, info->info16.acct_flags, rid);
4523 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
4530 static bool test_EnumDomainUsers(struct dcerpc_pipe *p, struct torture_context *tctx,
4531 struct policy_handle *handle)
4533 NTSTATUS status = STATUS_MORE_ENTRIES;
4534 struct samr_EnumDomainUsers r;
4535 uint32_t mask, resume_handle=0;
4538 struct samr_LookupNames n;
4539 struct samr_LookupRids lr ;
4540 struct lsa_Strings names;
4541 struct samr_Ids rids, types;
4542 struct samr_SamArray *sam = NULL;
4543 uint32_t num_entries = 0;
4545 uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
4546 ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
4547 ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
4550 printf("Testing EnumDomainUsers\n");
4552 for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
4553 r.in.domain_handle = handle;
4554 r.in.resume_handle = &resume_handle;
4555 r.in.acct_flags = mask = masks[mask_idx];
4556 r.in.max_size = (uint32_t)-1;
4557 r.out.resume_handle = &resume_handle;
4558 r.out.num_entries = &num_entries;
4561 status = dcerpc_samr_EnumDomainUsers(p, tctx, &r);
4562 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
4563 !NT_STATUS_IS_OK(status)) {
4564 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
4568 torture_assert(tctx, sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
4570 if (sam->count == 0) {
4574 for (i=0;i<sam->count;i++) {
4576 if (!check_mask(p, tctx, handle, sam->entries[i].idx, mask)) {
4579 } else if (!test_OpenUser(p, tctx, handle, sam->entries[i].idx)) {
4585 printf("Testing LookupNames\n");
4586 n.in.domain_handle = handle;
4587 n.in.num_names = sam->count;
4588 n.in.names = talloc_array(tctx, struct lsa_String, sam->count);
4590 n.out.types = &types;
4591 for (i=0;i<sam->count;i++) {
4592 n.in.names[i].string = sam->entries[i].name.string;
4594 status = dcerpc_samr_LookupNames(p, tctx, &n);
4595 if (!NT_STATUS_IS_OK(status)) {
4596 printf("LookupNames failed - %s\n", nt_errstr(status));
4601 printf("Testing LookupRids\n");
4602 lr.in.domain_handle = handle;
4603 lr.in.num_rids = sam->count;
4604 lr.in.rids = talloc_array(tctx, uint32_t, sam->count);
4605 lr.out.names = &names;
4606 lr.out.types = &types;
4607 for (i=0;i<sam->count;i++) {
4608 lr.in.rids[i] = sam->entries[i].idx;
4610 status = dcerpc_samr_LookupRids(p, tctx, &lr);
4611 torture_assert_ntstatus_ok(tctx, status, "LookupRids");
4617 try blasting the server with a bunch of sync requests
4619 static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, struct torture_context *tctx,
4620 struct policy_handle *handle)
4623 struct samr_EnumDomainUsers r;
4624 uint32_t resume_handle=0;
4626 #define ASYNC_COUNT 100
4627 struct rpc_request *req[ASYNC_COUNT];
4629 if (!torture_setting_bool(tctx, "dangerous", false)) {
4630 torture_skip(tctx, "samr async test disabled - enable dangerous tests to use\n");
4633 torture_comment(tctx, "Testing EnumDomainUsers_async\n");
4635 r.in.domain_handle = handle;
4636 r.in.resume_handle = &resume_handle;
4637 r.in.acct_flags = 0;
4638 r.in.max_size = (uint32_t)-1;
4639 r.out.resume_handle = &resume_handle;
4641 for (i=0;i<ASYNC_COUNT;i++) {
4642 req[i] = dcerpc_samr_EnumDomainUsers_send(p, tctx, &r);
4645 for (i=0;i<ASYNC_COUNT;i++) {
4646 status = dcerpc_ndr_request_recv(req[i]);
4647 if (!NT_STATUS_IS_OK(status)) {
4648 printf("EnumDomainUsers[%d] failed - %s\n",
4649 i, nt_errstr(status));
4654 torture_comment(tctx, "%d async requests OK\n", i);
4659 static bool test_EnumDomainGroups(struct dcerpc_pipe *p,
4660 struct torture_context *tctx,
4661 struct policy_handle *handle)
4664 struct samr_EnumDomainGroups r;
4665 uint32_t resume_handle=0;
4666 struct samr_SamArray *sam = NULL;
4667 uint32_t num_entries = 0;
4671 printf("Testing EnumDomainGroups\n");
4673 r.in.domain_handle = handle;
4674 r.in.resume_handle = &resume_handle;
4675 r.in.max_size = (uint32_t)-1;
4676 r.out.resume_handle = &resume_handle;
4677 r.out.num_entries = &num_entries;
4680 status = dcerpc_samr_EnumDomainGroups(p, tctx, &r);
4681 if (!NT_STATUS_IS_OK(status)) {
4682 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
4690 for (i=0;i<sam->count;i++) {
4691 if (!test_OpenGroup(p, tctx, handle, sam->entries[i].idx)) {
4699 static bool test_EnumDomainAliases(struct dcerpc_pipe *p,
4700 struct torture_context *tctx,
4701 struct policy_handle *handle)
4704 struct samr_EnumDomainAliases r;
4705 uint32_t resume_handle=0;
4706 struct samr_SamArray *sam = NULL;
4707 uint32_t num_entries = 0;
4711 printf("Testing EnumDomainAliases\n");
4713 r.in.domain_handle = handle;
4714 r.in.resume_handle = &resume_handle;
4715 r.in.max_size = (uint32_t)-1;
4717 r.out.num_entries = &num_entries;
4718 r.out.resume_handle = &resume_handle;
4720 status = dcerpc_samr_EnumDomainAliases(p, tctx, &r);
4721 if (!NT_STATUS_IS_OK(status)) {
4722 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
4730 for (i=0;i<sam->count;i++) {
4731 if (!test_OpenAlias(p, tctx, handle, sam->entries[i].idx)) {
4739 static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p,
4740 struct torture_context *tctx,
4741 struct policy_handle *handle)
4744 struct samr_GetDisplayEnumerationIndex r;
4746 uint16_t levels[] = {1, 2, 3, 4, 5};
4747 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
4748 struct lsa_String name;
4752 for (i=0;i<ARRAY_SIZE(levels);i++) {
4753 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
4755 init_lsa_String(&name, TEST_ACCOUNT_NAME);
4757 r.in.domain_handle = handle;
4758 r.in.level = levels[i];
4762 status = dcerpc_samr_GetDisplayEnumerationIndex(p, tctx, &r);
4765 !NT_STATUS_IS_OK(status) &&
4766 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
4767 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
4768 levels[i], nt_errstr(status));
4772 init_lsa_String(&name, "zzzzzzzz");
4774 status = dcerpc_samr_GetDisplayEnumerationIndex(p, tctx, &r);
4776 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
4777 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
4778 levels[i], nt_errstr(status));
4786 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p,
4787 struct torture_context *tctx,
4788 struct policy_handle *handle)
4791 struct samr_GetDisplayEnumerationIndex2 r;
4793 uint16_t levels[] = {1, 2, 3, 4, 5};
4794 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
4795 struct lsa_String name;
4799 for (i=0;i<ARRAY_SIZE(levels);i++) {
4800 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
4802 init_lsa_String(&name, TEST_ACCOUNT_NAME);
4804 r.in.domain_handle = handle;
4805 r.in.level = levels[i];
4809 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, tctx, &r);
4811 !NT_STATUS_IS_OK(status) &&
4812 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
4813 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
4814 levels[i], nt_errstr(status));
4818 init_lsa_String(&name, "zzzzzzzz");
4820 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, tctx, &r);
4821 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
4822 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
4823 levels[i], nt_errstr(status));
4831 #define STRING_EQUAL_QUERY(s1, s2, user) \
4832 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
4833 /* odd, but valid */ \
4834 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
4835 printf("%s mismatch for %s: %s != %s (%s)\n", \
4836 #s1, user.string, s1.string, s2.string, __location__); \
4839 #define INT_EQUAL_QUERY(s1, s2, user) \
4841 printf("%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
4842 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
4846 static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p,
4847 struct torture_context *tctx,
4848 struct samr_QueryDisplayInfo *querydisplayinfo,
4849 bool *seen_testuser)
4851 struct samr_OpenUser r;
4852 struct samr_QueryUserInfo q;
4853 union samr_UserInfo *info;
4854 struct policy_handle user_handle;
4857 r.in.domain_handle = querydisplayinfo->in.domain_handle;
4858 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4859 for (i = 0; ; i++) {
4860 switch (querydisplayinfo->in.level) {
4862 if (i >= querydisplayinfo->out.info->info1.count) {
4865 r.in.rid = querydisplayinfo->out.info->info1.entries[i].rid;
4868 if (i >= querydisplayinfo->out.info->info2.count) {
4871 r.in.rid = querydisplayinfo->out.info->info2.entries[i].rid;
4877 /* Not interested in validating just the account name */
4881 r.out.user_handle = &user_handle;
4883 switch (querydisplayinfo->in.level) {
4886 status = dcerpc_samr_OpenUser(p, tctx, &r);
4887 if (!NT_STATUS_IS_OK(status)) {
4888 printf("OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(status));
4893 q.in.user_handle = &user_handle;
4896 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
4897 if (!NT_STATUS_IS_OK(status)) {
4898 printf("QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(status));
4902 switch (querydisplayinfo->in.level) {
4904 if (seen_testuser && strcmp(info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
4905 *seen_testuser = true;
4907 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].full_name,
4908 info->info21.full_name, info->info21.account_name);
4909 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].account_name,
4910 info->info21.account_name, info->info21.account_name);
4911 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].description,
4912 info->info21.description, info->info21.account_name);
4913 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].rid,
4914 info->info21.rid, info->info21.account_name);
4915 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].acct_flags,
4916 info->info21.acct_flags, info->info21.account_name);
4920 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].account_name,
4921 info->info21.account_name, info->info21.account_name);
4922 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].description,
4923 info->info21.description, info->info21.account_name);
4924 INT_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].rid,
4925 info->info21.rid, info->info21.account_name);
4926 INT_EQUAL_QUERY((querydisplayinfo->out.info->info2.entries[i].acct_flags & ~ACB_NORMAL),
4927 info->info21.acct_flags, info->info21.account_name);
4929 if (!(querydisplayinfo->out.info->info2.entries[i].acct_flags & ACB_NORMAL)) {
4930 printf("Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
4931 info->info21.account_name.string);
4934 if (!(info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
4935 printf("Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
4936 info->info21.account_name.string,
4937 querydisplayinfo->out.info->info2.entries[i].acct_flags,
4938 info->info21.acct_flags);
4945 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
4952 static bool test_QueryDisplayInfo(struct dcerpc_pipe *p,
4953 struct torture_context *tctx,
4954 struct policy_handle *handle)
4957 struct samr_QueryDisplayInfo r;
4958 struct samr_QueryDomainInfo dom_info;
4959 union samr_DomainInfo *info = NULL;
4961 uint16_t levels[] = {1, 2, 3, 4, 5};
4963 bool seen_testuser = false;
4964 uint32_t total_size;
4965 uint32_t returned_size;
4966 union samr_DispInfo disp_info;
4969 for (i=0;i<ARRAY_SIZE(levels);i++) {
4970 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
4973 status = STATUS_MORE_ENTRIES;
4974 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
4975 r.in.domain_handle = handle;
4976 r.in.level = levels[i];
4977 r.in.max_entries = 2;
4978 r.in.buf_size = (uint32_t)-1;
4979 r.out.total_size = &total_size;
4980 r.out.returned_size = &returned_size;
4981 r.out.info = &disp_info;
4983 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &r);
4984 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(status)) {
4985 printf("QueryDisplayInfo level %u failed - %s\n",
4986 levels[i], nt_errstr(status));
4989 switch (r.in.level) {
4991 if (!test_each_DisplayInfo_user(p, tctx, &r, &seen_testuser)) {
4994 r.in.start_idx += r.out.info->info1.count;
4997 if (!test_each_DisplayInfo_user(p, tctx, &r, NULL)) {
5000 r.in.start_idx += r.out.info->info2.count;
5003 r.in.start_idx += r.out.info->info3.count;
5006 r.in.start_idx += r.out.info->info4.count;
5009 r.in.start_idx += r.out.info->info5.count;
5013 dom_info.in.domain_handle = handle;
5014 dom_info.in.level = 2;
5015 dom_info.out.info = &info;
5017 /* Check number of users returned is correct */
5018 status = dcerpc_samr_QueryDomainInfo(p, tctx, &dom_info);
5019 if (!NT_STATUS_IS_OK(status)) {
5020 printf("QueryDomainInfo level %u failed - %s\n",
5021 r.in.level, nt_errstr(status));
5025 switch (r.in.level) {
5028 if (info->general.num_users < r.in.start_idx) {
5029 printf("QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
5030 r.in.start_idx, info->general.num_groups,
5031 info->general.domain_name.string);
5034 if (!seen_testuser) {
5035 struct policy_handle user_handle;
5036 if (NT_STATUS_IS_OK(test_OpenUser_byname(p, tctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
5037 printf("Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
5038 info->general.domain_name.string);
5040 test_samr_handle_Close(p, tctx, &user_handle);
5046 if (info->general.num_groups != r.in.start_idx) {
5047 printf("QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
5048 r.in.start_idx, info->general.num_groups,
5049 info->general.domain_name.string);
5061 static bool test_QueryDisplayInfo2(struct dcerpc_pipe *p,
5062 struct torture_context *tctx,
5063 struct policy_handle *handle)
5066 struct samr_QueryDisplayInfo2 r;
5068 uint16_t levels[] = {1, 2, 3, 4, 5};
5070 uint32_t total_size;
5071 uint32_t returned_size;
5072 union samr_DispInfo info;
5074 for (i=0;i<ARRAY_SIZE(levels);i++) {
5075 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
5077 r.in.domain_handle = handle;
5078 r.in.level = levels[i];
5080 r.in.max_entries = 1000;
5081 r.in.buf_size = (uint32_t)-1;
5082 r.out.total_size = &total_size;
5083 r.out.returned_size = &returned_size;
5086 status = dcerpc_samr_QueryDisplayInfo2(p, tctx, &r);
5087 if (!NT_STATUS_IS_OK(status)) {
5088 printf("QueryDisplayInfo2 level %u failed - %s\n",
5089 levels[i], nt_errstr(status));
5097 static bool test_QueryDisplayInfo3(struct dcerpc_pipe *p, struct torture_context *tctx,
5098 struct policy_handle *handle)
5101 struct samr_QueryDisplayInfo3 r;
5103 uint16_t levels[] = {1, 2, 3, 4, 5};
5105 uint32_t total_size;
5106 uint32_t returned_size;
5107 union samr_DispInfo info;
5109 for (i=0;i<ARRAY_SIZE(levels);i++) {
5110 torture_comment(tctx, "Testing QueryDisplayInfo3 level %u\n", levels[i]);
5112 r.in.domain_handle = handle;
5113 r.in.level = levels[i];
5115 r.in.max_entries = 1000;
5116 r.in.buf_size = (uint32_t)-1;
5117 r.out.total_size = &total_size;
5118 r.out.returned_size = &returned_size;
5121 status = dcerpc_samr_QueryDisplayInfo3(p, tctx, &r);
5122 if (!NT_STATUS_IS_OK(status)) {
5123 printf("QueryDisplayInfo3 level %u failed - %s\n",
5124 levels[i], nt_errstr(status));
5133 static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p,
5134 struct torture_context *tctx,
5135 struct policy_handle *handle)
5138 struct samr_QueryDisplayInfo r;
5140 uint32_t total_size;
5141 uint32_t returned_size;
5142 union samr_DispInfo info;
5144 printf("Testing QueryDisplayInfo continuation\n");
5146 r.in.domain_handle = handle;
5149 r.in.max_entries = 1;
5150 r.in.buf_size = (uint32_t)-1;
5151 r.out.total_size = &total_size;
5152 r.out.returned_size = &returned_size;
5156 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &r);
5157 if (NT_STATUS_IS_OK(status) && *r.out.returned_size != 0) {
5158 if (r.out.info->info1.entries[0].idx != r.in.start_idx + 1) {
5159 printf("expected idx %d but got %d\n",
5161 r.out.info->info1.entries[0].idx);
5165 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
5166 !NT_STATUS_IS_OK(status)) {
5167 printf("QueryDisplayInfo level %u failed - %s\n",
5168 r.in.level, nt_errstr(status));
5173 } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
5174 NT_STATUS_IS_OK(status)) &&
5175 *r.out.returned_size != 0);
5180 static bool test_QueryDomainInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
5181 struct policy_handle *handle)
5184 struct samr_QueryDomainInfo r;
5185 union samr_DomainInfo *info = NULL;
5186 struct samr_SetDomainInfo s;
5187 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
5188 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
5191 const char *domain_comment = talloc_asprintf(tctx,
5192 "Tortured by Samba4 RPC-SAMR: %s",
5193 timestring(tctx, time(NULL)));
5195 s.in.domain_handle = handle;
5197 s.in.info = talloc(tctx, union samr_DomainInfo);
5199 s.in.info->oem.oem_information.string = domain_comment;
5200 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
5201 if (!NT_STATUS_IS_OK(status)) {
5202 printf("SetDomainInfo level %u (set comment) failed - %s\n",
5203 s.in.level, nt_errstr(status));
5207 for (i=0;i<ARRAY_SIZE(levels);i++) {
5208 torture_comment(tctx, "Testing QueryDomainInfo level %u\n", levels[i]);
5210 r.in.domain_handle = handle;
5211 r.in.level = levels[i];
5214 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
5215 if (!NT_STATUS_IS_OK(status)) {
5216 printf("QueryDomainInfo level %u failed - %s\n",
5217 r.in.level, nt_errstr(status));
5222 switch (levels[i]) {
5224 if (strcmp(info->general.oem_information.string, domain_comment) != 0) {
5225 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
5226 levels[i], info->general.oem_information.string, domain_comment);
5229 if (!info->general.primary.string) {
5230 printf("QueryDomainInfo level %u returned no PDC name\n",
5233 } else if (info->general.role == SAMR_ROLE_DOMAIN_PDC) {
5234 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), info->general.primary.string) != 0) {
5235 printf("QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
5236 levels[i], info->general.primary.string, dcerpc_server_name(p));
5241 if (strcmp(info->oem.oem_information.string, domain_comment) != 0) {
5242 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
5243 levels[i], info->oem.oem_information.string, domain_comment);
5248 if (!info->info6.primary.string) {
5249 printf("QueryDomainInfo level %u returned no PDC name\n",
5255 if (strcmp(info->general2.general.oem_information.string, domain_comment) != 0) {
5256 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
5257 levels[i], info->general2.general.oem_information.string, domain_comment);
5263 torture_comment(tctx, "Testing SetDomainInfo level %u\n", levels[i]);
5265 s.in.domain_handle = handle;
5266 s.in.level = levels[i];
5269 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
5271 if (!NT_STATUS_IS_OK(status)) {
5272 printf("SetDomainInfo level %u failed - %s\n",
5273 r.in.level, nt_errstr(status));
5278 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
5279 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
5280 r.in.level, nt_errstr(status));
5286 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
5287 if (!NT_STATUS_IS_OK(status)) {
5288 printf("QueryDomainInfo level %u failed - %s\n",
5289 r.in.level, nt_errstr(status));
5299 static bool test_QueryDomainInfo2(struct dcerpc_pipe *p, struct torture_context *tctx,
5300 struct policy_handle *handle)
5303 struct samr_QueryDomainInfo2 r;
5304 union samr_DomainInfo *info = NULL;
5305 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
5309 for (i=0;i<ARRAY_SIZE(levels);i++) {
5310 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
5312 r.in.domain_handle = handle;
5313 r.in.level = levels[i];
5316 status = dcerpc_samr_QueryDomainInfo2(p, tctx, &r);
5317 if (!NT_STATUS_IS_OK(status)) {
5318 printf("QueryDomainInfo2 level %u failed - %s\n",
5319 r.in.level, nt_errstr(status));
5328 /* Test whether querydispinfo level 5 and enumdomgroups return the same
5329 set of group names. */
5330 static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx,
5331 struct policy_handle *handle)
5333 struct samr_EnumDomainGroups q1;
5334 struct samr_QueryDisplayInfo q2;
5336 uint32_t resume_handle=0;
5337 struct samr_SamArray *sam = NULL;
5338 uint32_t num_entries = 0;
5341 uint32_t total_size;
5342 uint32_t returned_size;
5343 union samr_DispInfo info;
5346 const char **names = NULL;
5348 torture_comment(tctx, "Testing coherency of querydispinfo vs enumdomgroups\n");
5350 q1.in.domain_handle = handle;
5351 q1.in.resume_handle = &resume_handle;
5353 q1.out.resume_handle = &resume_handle;
5354 q1.out.num_entries = &num_entries;
5357 status = STATUS_MORE_ENTRIES;
5358 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
5359 status = dcerpc_samr_EnumDomainGroups(p, tctx, &q1);
5361 if (!NT_STATUS_IS_OK(status) &&
5362 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
5365 for (i=0; i<*q1.out.num_entries; i++) {
5366 add_string_to_array(tctx,
5367 sam->entries[i].name.string,
5368 &names, &num_names);
5372 torture_assert_ntstatus_ok(tctx, status, "EnumDomainGroups");
5374 torture_assert(tctx, sam, "EnumDomainGroups failed to return sam");
5376 q2.in.domain_handle = handle;
5378 q2.in.start_idx = 0;
5379 q2.in.max_entries = 5;
5380 q2.in.buf_size = (uint32_t)-1;
5381 q2.out.total_size = &total_size;
5382 q2.out.returned_size = &returned_size;
5383 q2.out.info = &info;
5385 status = STATUS_MORE_ENTRIES;
5386 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
5387 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &q2);
5389 if (!NT_STATUS_IS_OK(status) &&
5390 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
5393 for (i=0; i<q2.out.info->info5.count; i++) {
5395 const char *name = q2.out.info->info5.entries[i].account_name.string;
5397 for (j=0; j<num_names; j++) {
5398 if (names[j] == NULL)
5400 if (strequal(names[j], name)) {
5408 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
5413 q2.in.start_idx += q2.out.info->info5.count;
5416 if (!NT_STATUS_IS_OK(status)) {
5417 printf("QueryDisplayInfo level 5 failed - %s\n",
5422 for (i=0; i<num_names; i++) {
5423 if (names[i] != NULL) {
5424 printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
5433 static bool test_DeleteDomainGroup(struct dcerpc_pipe *p, struct torture_context *tctx,
5434 struct policy_handle *group_handle)
5436 struct samr_DeleteDomainGroup d;
5439 torture_comment(tctx, "Testing DeleteDomainGroup\n");
5441 d.in.group_handle = group_handle;
5442 d.out.group_handle = group_handle;
5444 status = dcerpc_samr_DeleteDomainGroup(p, tctx, &d);
5445 torture_assert_ntstatus_ok(tctx, status, "DeleteDomainGroup");
5450 static bool test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
5451 struct policy_handle *domain_handle)
5453 struct samr_TestPrivateFunctionsDomain r;
5457 torture_comment(tctx, "Testing TestPrivateFunctionsDomain\n");
5459 r.in.domain_handle = domain_handle;
5461 status = dcerpc_samr_TestPrivateFunctionsDomain(p, tctx, &r);
5462 torture_assert_ntstatus_equal(tctx, NT_STATUS_NOT_IMPLEMENTED, status, "TestPrivateFunctionsDomain");
5467 static bool test_RidToSid(struct dcerpc_pipe *p, struct torture_context *tctx,
5468 struct dom_sid *domain_sid,
5469 struct policy_handle *domain_handle)
5471 struct samr_RidToSid r;
5474 struct dom_sid *calc_sid, *out_sid;
5475 int rids[] = { 0, 42, 512, 10200 };
5478 for (i=0;i<ARRAY_SIZE(rids);i++) {
5479 torture_comment(tctx, "Testing RidToSid\n");
5481 calc_sid = dom_sid_dup(tctx, domain_sid);
5482 r.in.domain_handle = domain_handle;
5484 r.out.sid = &out_sid;
5486 status = dcerpc_samr_RidToSid(p, tctx, &r);
5487 if (!NT_STATUS_IS_OK(status)) {
5488 printf("RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
5491 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
5493 if (!dom_sid_equal(calc_sid, out_sid)) {
5494 printf("RidToSid for %d failed - got %s, expected %s\n", rids[i],
5495 dom_sid_string(tctx, out_sid),
5496 dom_sid_string(tctx, calc_sid));
5505 static bool test_GetBootKeyInformation(struct dcerpc_pipe *p, struct torture_context *tctx,
5506 struct policy_handle *domain_handle)
5508 struct samr_GetBootKeyInformation r;
5511 uint32_t unknown = 0;
5513 torture_comment(tctx, "Testing GetBootKeyInformation\n");
5515 r.in.domain_handle = domain_handle;
5516 r.out.unknown = &unknown;
5518 status = dcerpc_samr_GetBootKeyInformation(p, tctx, &r);
5519 if (!NT_STATUS_IS_OK(status)) {
5520 /* w2k3 seems to fail this sometimes and pass it sometimes */
5521 torture_comment(tctx, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
5527 static bool test_AddGroupMember(struct dcerpc_pipe *p, struct torture_context *tctx,
5528 struct policy_handle *domain_handle,
5529 struct policy_handle *group_handle)
5532 struct samr_AddGroupMember r;
5533 struct samr_DeleteGroupMember d;
5534 struct samr_QueryGroupMember q;
5535 struct samr_RidTypeArray *rids = NULL;
5536 struct samr_SetMemberAttributesOfGroup s;
5539 status = test_LookupName(p, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
5540 torture_assert_ntstatus_ok(tctx, status, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME);
5542 r.in.group_handle = group_handle;
5544 r.in.flags = 0; /* ??? */
5546 torture_comment(tctx, "Testing AddGroupMember and DeleteGroupMember\n");
5548 d.in.group_handle = group_handle;
5551 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
5552 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_NOT_IN_GROUP, status, "DeleteGroupMember");
5554 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5555 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
5557 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5558 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_IN_GROUP, status, "AddGroupMember");
5560 if (torture_setting_bool(tctx, "samba4", false)) {
5561 torture_comment(tctx, "skipping SetMemberAttributesOfGroup test against Samba4\n");
5563 /* this one is quite strange. I am using random inputs in the
5564 hope of triggering an error that might give us a clue */
5566 s.in.group_handle = group_handle;
5567 s.in.unknown1 = random();
5568 s.in.unknown2 = random();
5570 status = dcerpc_samr_SetMemberAttributesOfGroup(p, tctx, &s);
5571 torture_assert_ntstatus_ok(tctx, status, "SetMemberAttributesOfGroup");
5574 q.in.group_handle = group_handle;
5577 status = dcerpc_samr_QueryGroupMember(p, tctx, &q);
5578 torture_assert_ntstatus_ok(tctx, status, "QueryGroupMember");
5580 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
5581 torture_assert_ntstatus_ok(tctx, status, "DeleteGroupMember");
5583 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5584 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
5590 static bool test_CreateDomainGroup(struct dcerpc_pipe *p,
5591 struct torture_context *tctx,
5592 struct policy_handle *domain_handle,
5593 struct policy_handle *group_handle,
5594 struct dom_sid *domain_sid)
5597 struct samr_CreateDomainGroup r;
5599 struct lsa_String name;
5602 init_lsa_String(&name, TEST_GROUPNAME);
5604 r.in.domain_handle = domain_handle;
5606 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5607 r.out.group_handle = group_handle;
5610 printf("Testing CreateDomainGroup(%s)\n", r.in.name->string);
5612 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
5614 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5615 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5616 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.name->string);
5619 printf("Server should have refused create of '%s', got %s instead\n", r.in.name->string,
5625 if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS)) {
5626 if (!test_DeleteGroup_byname(p, tctx, domain_handle, r.in.name->string)) {
5627 printf("CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
5631 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
5633 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
5634 if (!test_DeleteUser_byname(p, tctx, domain_handle, r.in.name->string)) {
5636 printf("CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
5640 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
5642 torture_assert_ntstatus_ok(tctx, status, "CreateDomainGroup");
5644 if (!test_AddGroupMember(p, tctx, domain_handle, group_handle)) {
5645 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
5649 if (!test_SetGroupInfo(p, tctx, group_handle)) {
5658 its not totally clear what this does. It seems to accept any sid you like.
5660 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p,
5661 struct torture_context *tctx,
5662 struct policy_handle *domain_handle)
5665 struct samr_RemoveMemberFromForeignDomain r;
5667 r.in.domain_handle = domain_handle;
5668 r.in.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-12-34-56-78");
5670 status = dcerpc_samr_RemoveMemberFromForeignDomain(p, tctx, &r);
5671 torture_assert_ntstatus_ok(tctx, status, "RemoveMemberFromForeignDomain");
5678 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
5679 struct policy_handle *handle);
5681 static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
5682 struct policy_handle *handle, struct dom_sid *sid,
5683 enum torture_samr_choice which_ops,
5684 struct cli_credentials *machine_credentials)
5687 struct samr_OpenDomain r;
5688 struct policy_handle domain_handle;
5689 struct policy_handle alias_handle;
5690 struct policy_handle user_handle;
5691 struct policy_handle group_handle;
5694 ZERO_STRUCT(alias_handle);
5695 ZERO_STRUCT(user_handle);
5696 ZERO_STRUCT(group_handle);
5697 ZERO_STRUCT(domain_handle);
5699 torture_comment(tctx, "Testing OpenDomain of %s\n", dom_sid_string(tctx, sid));
5701 r.in.connect_handle = handle;
5702 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5704 r.out.domain_handle = &domain_handle;
5706 status = dcerpc_samr_OpenDomain(p, tctx, &r);
5707 torture_assert_ntstatus_ok(tctx, status, "OpenDomain");
5709 /* run the domain tests with the main handle closed - this tests
5710 the servers reference counting */
5711 ret &= test_samr_handle_Close(p, tctx, handle);
5713 switch (which_ops) {
5714 case TORTURE_SAMR_USER_ATTRIBUTES:
5715 case TORTURE_SAMR_PASSWORDS:
5716 if (!torture_setting_bool(tctx, "samba3", false)) {
5717 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops, NULL);
5719 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops, NULL);
5720 /* This test needs 'complex' users to validate */
5721 ret &= test_QueryDisplayInfo(p, tctx, &domain_handle);
5723 printf("Testing PASSWORDS or ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
5726 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
5727 if (!torture_setting_bool(tctx, "samba3", false)) {
5728 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops, machine_credentials);
5730 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops, machine_credentials);
5732 printf("Testing PASSWORDS PWDLASTSET on domain %s failed!\n", dom_sid_string(tctx, sid));
5735 case TORTURE_SAMR_OTHER:
5736 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops, NULL);
5738 printf("Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid));
5740 ret &= test_QuerySecurity(p, tctx, &domain_handle);
5741 ret &= test_RemoveMemberFromForeignDomain(p, tctx, &domain_handle);
5742 ret &= test_CreateAlias(p, tctx, &domain_handle, &alias_handle, sid);
5743 ret &= test_CreateDomainGroup(p, tctx, &domain_handle, &group_handle, sid);
5744 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
5745 ret &= test_QueryDomainInfo2(p, tctx, &domain_handle);
5746 ret &= test_EnumDomainUsers(p, tctx, &domain_handle);
5747 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
5748 ret &= test_EnumDomainGroups(p, tctx, &domain_handle);
5749 ret &= test_EnumDomainAliases(p, tctx, &domain_handle);
5750 ret &= test_QueryDisplayInfo2(p, tctx, &domain_handle);
5751 ret &= test_QueryDisplayInfo3(p, tctx, &domain_handle);
5752 ret &= test_QueryDisplayInfo_continue(p, tctx, &domain_handle);
5754 if (torture_setting_bool(tctx, "samba4", false)) {
5755 torture_comment(tctx, "skipping GetDisplayEnumerationIndex test against Samba4\n");
5757 ret &= test_GetDisplayEnumerationIndex(p, tctx, &domain_handle);
5758 ret &= test_GetDisplayEnumerationIndex2(p, tctx, &domain_handle);
5760 ret &= test_GroupList(p, tctx, &domain_handle);
5761 ret &= test_TestPrivateFunctionsDomain(p, tctx, &domain_handle);
5762 ret &= test_RidToSid(p, tctx, sid, &domain_handle);
5763 ret &= test_GetBootKeyInformation(p, tctx, &domain_handle);
5765 torture_comment(tctx, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx, sid));
5770 if (!policy_handle_empty(&user_handle) &&
5771 !test_DeleteUser(p, tctx, &user_handle)) {
5775 if (!policy_handle_empty(&alias_handle) &&
5776 !test_DeleteAlias(p, tctx, &alias_handle)) {
5780 if (!policy_handle_empty(&group_handle) &&
5781 !test_DeleteDomainGroup(p, tctx, &group_handle)) {
5785 ret &= test_samr_handle_Close(p, tctx, &domain_handle);
5787 /* reconnect the main handle */
5788 ret &= test_Connect(p, tctx, handle);
5791 printf("Testing domain %s failed!\n", dom_sid_string(tctx, sid));
5797 static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
5798 struct policy_handle *handle, const char *domain,
5799 enum torture_samr_choice which_ops,
5800 struct cli_credentials *machine_credentials)
5803 struct samr_LookupDomain r;
5804 struct dom_sid2 *sid = NULL;
5805 struct lsa_String n1;
5806 struct lsa_String n2;
5809 torture_comment(tctx, "Testing LookupDomain(%s)\n", domain);
5811 /* check for correct error codes */
5812 r.in.connect_handle = handle;
5813 r.in.domain_name = &n2;
5817 status = dcerpc_samr_LookupDomain(p, tctx, &r);
5818 torture_assert_ntstatus_equal(tctx, NT_STATUS_INVALID_PARAMETER, status, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
5820 init_lsa_String(&n2, "xxNODOMAINxx");
5822 status = dcerpc_samr_LookupDomain(p, tctx, &r);
5823 torture_assert_ntstatus_equal(tctx, NT_STATUS_NO_SUCH_DOMAIN, status, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
5825 r.in.connect_handle = handle;
5827 init_lsa_String(&n1, domain);
5828 r.in.domain_name = &n1;
5830 status = dcerpc_samr_LookupDomain(p, tctx, &r);
5831 torture_assert_ntstatus_ok(tctx, status, "LookupDomain");
5833 if (!test_GetDomPwInfo(p, tctx, &n1)) {
5837 if (!test_OpenDomain(p, tctx, handle, *r.out.sid, which_ops,
5838 machine_credentials)) {
5846 static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
5847 struct policy_handle *handle, enum torture_samr_choice which_ops,
5848 struct cli_credentials *machine_credentials)
5851 struct samr_EnumDomains r;
5852 uint32_t resume_handle = 0;
5853 uint32_t num_entries = 0;
5854 struct samr_SamArray *sam = NULL;
5858 r.in.connect_handle = handle;
5859 r.in.resume_handle = &resume_handle;
5860 r.in.buf_size = (uint32_t)-1;
5861 r.out.resume_handle = &resume_handle;
5862 r.out.num_entries = &num_entries;
5865 status = dcerpc_samr_EnumDomains(p, tctx, &r);
5866 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
5872 for (i=0;i<sam->count;i++) {
5873 if (!test_LookupDomain(p, tctx, handle,
5874 sam->entries[i].name.string, which_ops,
5875 machine_credentials)) {
5880 status = dcerpc_samr_EnumDomains(p, tctx, &r);
5881 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
5887 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
5888 struct policy_handle *handle)
5891 struct samr_Connect r;
5892 struct samr_Connect2 r2;
5893 struct samr_Connect3 r3;
5894 struct samr_Connect4 r4;
5895 struct samr_Connect5 r5;
5896 union samr_ConnectInfo info;
5897 struct policy_handle h;
5898 uint32_t level_out = 0;
5899 bool ret = true, got_handle = false;
5901 torture_comment(tctx, "testing samr_Connect\n");
5903 r.in.system_name = 0;
5904 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5905 r.out.connect_handle = &h;
5907 status = dcerpc_samr_Connect(p, tctx, &r);
5908 if (!NT_STATUS_IS_OK(status)) {
5909 torture_comment(tctx, "Connect failed - %s\n", nt_errstr(status));
5916 torture_comment(tctx, "testing samr_Connect2\n");
5918 r2.in.system_name = NULL;
5919 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5920 r2.out.connect_handle = &h;
5922 status = dcerpc_samr_Connect2(p, tctx, &r2);
5923 if (!NT_STATUS_IS_OK(status)) {
5924 torture_comment(tctx, "Connect2 failed - %s\n", nt_errstr(status));
5928 test_samr_handle_Close(p, tctx, handle);
5934 torture_comment(tctx, "testing samr_Connect3\n");
5936 r3.in.system_name = NULL;
5938 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5939 r3.out.connect_handle = &h;
5941 status = dcerpc_samr_Connect3(p, tctx, &r3);
5942 if (!NT_STATUS_IS_OK(status)) {
5943 printf("Connect3 failed - %s\n", nt_errstr(status));
5947 test_samr_handle_Close(p, tctx, handle);
5953 torture_comment(tctx, "testing samr_Connect4\n");
5955 r4.in.system_name = "";
5956 r4.in.client_version = 0;
5957 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5958 r4.out.connect_handle = &h;
5960 status = dcerpc_samr_Connect4(p, tctx, &r4);
5961 if (!NT_STATUS_IS_OK(status)) {
5962 printf("Connect4 failed - %s\n", nt_errstr(status));
5966 test_samr_handle_Close(p, tctx, handle);
5972 torture_comment(tctx, "testing samr_Connect5\n");
5974 info.info1.client_version = 0;
5975 info.info1.unknown2 = 0;
5977 r5.in.system_name = "";
5978 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5980 r5.out.level_out = &level_out;
5981 r5.in.info_in = &info;
5982 r5.out.info_out = &info;
5983 r5.out.connect_handle = &h;
5985 status = dcerpc_samr_Connect5(p, tctx, &r5);
5986 if (!NT_STATUS_IS_OK(status)) {
5987 printf("Connect5 failed - %s\n", nt_errstr(status));
5991 test_samr_handle_Close(p, tctx, handle);
6001 bool torture_rpc_samr(struct torture_context *torture)
6004 struct dcerpc_pipe *p;
6006 struct policy_handle handle;
6008 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6009 if (!NT_STATUS_IS_OK(status)) {
6013 ret &= test_Connect(p, torture, &handle);
6015 ret &= test_QuerySecurity(p, torture, &handle);
6017 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_OTHER, NULL);
6019 ret &= test_SetDsrmPassword(p, torture, &handle);
6021 ret &= test_Shutdown(p, torture, &handle);
6023 ret &= test_samr_handle_Close(p, torture, &handle);
6029 bool torture_rpc_samr_users(struct torture_context *torture)
6032 struct dcerpc_pipe *p;
6034 struct policy_handle handle;
6036 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6037 if (!NT_STATUS_IS_OK(status)) {
6041 ret &= test_Connect(p, torture, &handle);
6043 if (!torture_setting_bool(torture, "samba3", false)) {
6044 ret &= test_QuerySecurity(p, torture, &handle);
6047 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_USER_ATTRIBUTES, NULL);
6049 ret &= test_SetDsrmPassword(p, torture, &handle);
6051 ret &= test_Shutdown(p, torture, &handle);
6053 ret &= test_samr_handle_Close(p, torture, &handle);
6059 bool torture_rpc_samr_passwords(struct torture_context *torture)
6062 struct dcerpc_pipe *p;
6064 struct policy_handle handle;
6066 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6067 if (!NT_STATUS_IS_OK(status)) {
6071 ret &= test_Connect(p, torture, &handle);
6073 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_PASSWORDS, NULL);
6075 ret &= test_samr_handle_Close(p, torture, &handle);
6080 static bool torture_rpc_samr_pwdlastset(struct torture_context *torture,
6081 struct dcerpc_pipe *p2,
6082 struct cli_credentials *machine_credentials)
6085 struct dcerpc_pipe *p;
6087 struct policy_handle handle;
6089 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6090 if (!NT_STATUS_IS_OK(status)) {
6094 ret &= test_Connect(p, torture, &handle);
6096 ret &= test_EnumDomains(p, torture, &handle,
6097 TORTURE_SAMR_PASSWORDS_PWDLASTSET,
6098 machine_credentials);
6100 ret &= test_samr_handle_Close(p, torture, &handle);
6105 struct torture_suite *torture_rpc_samr_passwords_pwdlastset(struct torture_context *tctx)
6107 struct torture_suite *suite = torture_suite_create(tctx, "SAMR-PASSWORDS-PWDLASTSET");
6108 struct torture_rpc_tcase *tcase;
6110 tcase = torture_suite_add_machine_rpc_iface_tcase(suite, "samr",
6112 TEST_ACCOUNT_NAME_PWD);
6114 torture_rpc_tcase_add_test_creds(tcase, "pwdLastSet",
6115 torture_rpc_samr_pwdlastset);