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 (!torture_setting_bool(tctx, "samba3", false)) {
3486 if (!test_QuerySecurity(p, tctx, alias_handle)) {
3491 if (!test_QueryAliasInfo(p, tctx, alias_handle)) {
3495 if (!test_SetAliasInfo(p, tctx, alias_handle)) {
3499 if (!test_AddMemberToAlias(p, tctx, alias_handle, domain_sid)) {
3503 if (torture_setting_bool(tctx, "samba4", false)) {
3504 printf("skipping MultipleMembers Alias tests against Samba4\n");
3508 if (!test_AddMultipleMembersToAlias(p, tctx, alias_handle)) {
3516 static bool test_DeleteUser(struct dcerpc_pipe *p, struct torture_context *tctx,
3517 struct policy_handle *user_handle)
3519 struct samr_DeleteUser d;
3521 torture_comment(tctx, "Testing DeleteUser\n");
3523 d.in.user_handle = user_handle;
3524 d.out.user_handle = user_handle;
3526 status = dcerpc_samr_DeleteUser(p, tctx, &d);
3527 torture_assert_ntstatus_ok(tctx, status, "DeleteUser");
3532 bool test_DeleteUser_byname(struct dcerpc_pipe *p,
3533 struct torture_context *tctx,
3534 struct policy_handle *handle, const char *name)
3537 struct samr_DeleteUser d;
3538 struct policy_handle user_handle;
3541 status = test_LookupName(p, tctx, handle, name, &rid);
3542 if (!NT_STATUS_IS_OK(status)) {
3546 status = test_OpenUser_byname(p, tctx, handle, name, &user_handle);
3547 if (!NT_STATUS_IS_OK(status)) {
3551 d.in.user_handle = &user_handle;
3552 d.out.user_handle = &user_handle;
3553 status = dcerpc_samr_DeleteUser(p, tctx, &d);
3554 if (!NT_STATUS_IS_OK(status)) {
3561 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
3566 static bool test_DeleteGroup_byname(struct dcerpc_pipe *p,
3567 struct torture_context *tctx,
3568 struct policy_handle *handle, const char *name)
3571 struct samr_OpenGroup r;
3572 struct samr_DeleteDomainGroup d;
3573 struct policy_handle group_handle;
3576 status = test_LookupName(p, tctx, handle, name, &rid);
3577 if (!NT_STATUS_IS_OK(status)) {
3581 r.in.domain_handle = handle;
3582 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3584 r.out.group_handle = &group_handle;
3585 status = dcerpc_samr_OpenGroup(p, tctx, &r);
3586 if (!NT_STATUS_IS_OK(status)) {
3590 d.in.group_handle = &group_handle;
3591 d.out.group_handle = &group_handle;
3592 status = dcerpc_samr_DeleteDomainGroup(p, tctx, &d);
3593 if (!NT_STATUS_IS_OK(status)) {
3600 printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
3605 static bool test_DeleteAlias_byname(struct dcerpc_pipe *p,
3606 struct torture_context *tctx,
3607 struct policy_handle *domain_handle,
3611 struct samr_OpenAlias r;
3612 struct samr_DeleteDomAlias d;
3613 struct policy_handle alias_handle;
3616 printf("testing DeleteAlias_byname\n");
3618 status = test_LookupName(p, tctx, domain_handle, name, &rid);
3619 if (!NT_STATUS_IS_OK(status)) {
3623 r.in.domain_handle = domain_handle;
3624 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3626 r.out.alias_handle = &alias_handle;
3627 status = dcerpc_samr_OpenAlias(p, tctx, &r);
3628 if (!NT_STATUS_IS_OK(status)) {
3632 d.in.alias_handle = &alias_handle;
3633 d.out.alias_handle = &alias_handle;
3634 status = dcerpc_samr_DeleteDomAlias(p, tctx, &d);
3635 if (!NT_STATUS_IS_OK(status)) {
3642 printf("DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
3646 static bool test_DeleteAlias(struct dcerpc_pipe *p,
3647 struct torture_context *tctx,
3648 struct policy_handle *alias_handle)
3650 struct samr_DeleteDomAlias d;
3653 printf("Testing DeleteAlias\n");
3655 d.in.alias_handle = alias_handle;
3656 d.out.alias_handle = alias_handle;
3658 status = dcerpc_samr_DeleteDomAlias(p, tctx, &d);
3659 if (!NT_STATUS_IS_OK(status)) {
3660 printf("DeleteAlias failed - %s\n", nt_errstr(status));
3667 static bool test_CreateAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
3668 struct policy_handle *domain_handle,
3669 struct policy_handle *alias_handle,
3670 const struct dom_sid *domain_sid)
3673 struct samr_CreateDomAlias r;
3674 struct lsa_String name;
3678 init_lsa_String(&name, TEST_ALIASNAME);
3679 r.in.domain_handle = domain_handle;
3680 r.in.alias_name = &name;
3681 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3682 r.out.alias_handle = alias_handle;
3685 printf("Testing CreateAlias (%s)\n", r.in.alias_name->string);
3687 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
3689 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
3690 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
3691 printf("Server correctly refused create of '%s'\n", r.in.alias_name->string);
3694 printf("Server should have refused create of '%s', got %s instead\n", r.in.alias_name->string,
3700 if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
3701 if (!test_DeleteAlias_byname(p, tctx, domain_handle, r.in.alias_name->string)) {
3704 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
3707 if (!NT_STATUS_IS_OK(status)) {
3708 printf("CreateAlias failed - %s\n", nt_errstr(status));
3712 if (!test_alias_ops(p, tctx, alias_handle, domain_sid)) {
3719 static bool test_ChangePassword(struct dcerpc_pipe *p,
3720 struct torture_context *tctx,
3721 const char *acct_name,
3722 struct policy_handle *domain_handle, char **password)
3730 if (!test_ChangePasswordUser(p, tctx, acct_name, domain_handle, password)) {
3734 if (!test_ChangePasswordUser2(p, tctx, acct_name, password, 0, true)) {
3738 if (!test_OemChangePasswordUser2(p, tctx, acct_name, domain_handle, password)) {
3742 /* test what happens when setting the old password again */
3743 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, *password, 0, true)) {
3748 char simple_pass[9];
3749 char *v = generate_random_str(tctx, 1);
3751 ZERO_STRUCT(simple_pass);
3752 memset(simple_pass, *v, sizeof(simple_pass) - 1);
3754 /* test what happens when picking a simple password */
3755 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, simple_pass, 0, true)) {
3760 /* set samr_SetDomainInfo level 1 with min_length 5 */
3762 struct samr_QueryDomainInfo r;
3763 union samr_DomainInfo *info = NULL;
3764 struct samr_SetDomainInfo s;
3765 uint16_t len_old, len;
3766 uint32_t pwd_prop_old;
3767 int64_t min_pwd_age_old;
3772 r.in.domain_handle = domain_handle;
3776 printf("testing samr_QueryDomainInfo level 1\n");
3777 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
3778 if (!NT_STATUS_IS_OK(status)) {
3782 s.in.domain_handle = domain_handle;
3786 /* remember the old min length, so we can reset it */
3787 len_old = s.in.info->info1.min_password_length;
3788 s.in.info->info1.min_password_length = len;
3789 pwd_prop_old = s.in.info->info1.password_properties;
3790 /* turn off password complexity checks for this test */
3791 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
3793 min_pwd_age_old = s.in.info->info1.min_password_age;
3794 s.in.info->info1.min_password_age = 0;
3796 printf("testing samr_SetDomainInfo level 1\n");
3797 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
3798 if (!NT_STATUS_IS_OK(status)) {
3802 printf("calling test_ChangePasswordUser3 with too short password\n");
3804 if (!test_ChangePasswordUser3(p, tctx, acct_name, len - 1, password, NULL, 0, true)) {
3808 s.in.info->info1.min_password_length = len_old;
3809 s.in.info->info1.password_properties = pwd_prop_old;
3810 s.in.info->info1.min_password_age = min_pwd_age_old;
3812 printf("testing samr_SetDomainInfo level 1\n");
3813 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
3814 if (!NT_STATUS_IS_OK(status)) {
3822 struct samr_OpenUser r;
3823 struct samr_QueryUserInfo q;
3824 union samr_UserInfo *info;
3825 struct samr_LookupNames n;
3826 struct policy_handle user_handle;
3827 struct samr_Ids rids, types;
3829 n.in.domain_handle = domain_handle;
3831 n.in.names = talloc_array(tctx, struct lsa_String, 1);
3832 n.in.names[0].string = acct_name;
3834 n.out.types = &types;
3836 status = dcerpc_samr_LookupNames(p, tctx, &n);
3837 if (!NT_STATUS_IS_OK(status)) {
3838 printf("LookupNames failed - %s\n", nt_errstr(status));
3842 r.in.domain_handle = domain_handle;
3843 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3844 r.in.rid = n.out.rids->ids[0];
3845 r.out.user_handle = &user_handle;
3847 status = dcerpc_samr_OpenUser(p, tctx, &r);
3848 if (!NT_STATUS_IS_OK(status)) {
3849 printf("OpenUser(%u) failed - %s\n", n.out.rids->ids[0], nt_errstr(status));
3853 q.in.user_handle = &user_handle;
3857 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
3858 if (!NT_STATUS_IS_OK(status)) {
3859 printf("QueryUserInfo failed - %s\n", nt_errstr(status));
3863 printf("calling test_ChangePasswordUser3 with too early password change\n");
3865 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL,
3866 info->info5.last_password_change, true)) {
3871 /* we change passwords twice - this has the effect of verifying
3872 they were changed correctly for the final call */
3873 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
3877 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
3884 static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
3885 struct policy_handle *domain_handle,
3886 struct policy_handle *user_handle_out,
3887 struct dom_sid *domain_sid,
3888 enum torture_samr_choice which_ops,
3889 struct cli_credentials *machine_credentials)
3892 TALLOC_CTX *user_ctx;
3895 struct samr_CreateUser r;
3896 struct samr_QueryUserInfo q;
3897 union samr_UserInfo *info;
3898 struct samr_DeleteUser d;
3901 /* This call creates a 'normal' account - check that it really does */
3902 const uint32_t acct_flags = ACB_NORMAL;
3903 struct lsa_String name;
3906 struct policy_handle user_handle;
3907 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
3908 init_lsa_String(&name, TEST_ACCOUNT_NAME);
3910 r.in.domain_handle = domain_handle;
3911 r.in.account_name = &name;
3912 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3913 r.out.user_handle = &user_handle;
3916 printf("Testing CreateUser(%s)\n", r.in.account_name->string);
3918 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
3920 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
3921 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
3922 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
3925 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
3931 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
3932 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
3933 talloc_free(user_ctx);
3936 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
3938 if (!NT_STATUS_IS_OK(status)) {
3939 talloc_free(user_ctx);
3940 printf("CreateUser failed - %s\n", nt_errstr(status));
3943 q.in.user_handle = &user_handle;
3947 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
3948 if (!NT_STATUS_IS_OK(status)) {
3949 printf("QueryUserInfo level %u failed - %s\n",
3950 q.in.level, nt_errstr(status));
3953 if ((info->info16.acct_flags & acct_flags) != acct_flags) {
3954 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
3955 info->info16.acct_flags,
3961 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
3962 acct_flags, name.string, which_ops,
3963 machine_credentials)) {
3967 if (user_handle_out) {
3968 *user_handle_out = user_handle;
3970 printf("Testing DeleteUser (createuser test)\n");
3972 d.in.user_handle = &user_handle;
3973 d.out.user_handle = &user_handle;
3975 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
3976 if (!NT_STATUS_IS_OK(status)) {
3977 printf("DeleteUser failed - %s\n", nt_errstr(status));
3984 talloc_free(user_ctx);
3990 static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
3991 struct policy_handle *domain_handle,
3992 struct dom_sid *domain_sid,
3993 enum torture_samr_choice which_ops,
3994 struct cli_credentials *machine_credentials)
3997 struct samr_CreateUser2 r;
3998 struct samr_QueryUserInfo q;
3999 union samr_UserInfo *info;
4000 struct samr_DeleteUser d;
4001 struct policy_handle user_handle;
4003 struct lsa_String name;
4008 uint32_t acct_flags;
4009 const char *account_name;
4011 } account_types[] = {
4012 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
4013 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
4014 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
4015 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
4016 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
4017 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
4018 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
4019 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
4020 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
4021 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
4022 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
4023 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
4024 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
4025 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
4026 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
4029 for (i = 0; account_types[i].account_name; i++) {
4030 TALLOC_CTX *user_ctx;
4031 uint32_t acct_flags = account_types[i].acct_flags;
4032 uint32_t access_granted;
4033 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
4034 init_lsa_String(&name, account_types[i].account_name);
4036 r.in.domain_handle = domain_handle;
4037 r.in.account_name = &name;
4038 r.in.acct_flags = acct_flags;
4039 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4040 r.out.user_handle = &user_handle;
4041 r.out.access_granted = &access_granted;
4044 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
4046 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
4048 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
4049 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
4050 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
4053 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
4060 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
4061 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
4062 talloc_free(user_ctx);
4066 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
4069 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
4070 printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
4071 nt_errstr(status), nt_errstr(account_types[i].nt_status));
4075 if (NT_STATUS_IS_OK(status)) {
4076 q.in.user_handle = &user_handle;
4080 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
4081 if (!NT_STATUS_IS_OK(status)) {
4082 printf("QueryUserInfo level %u failed - %s\n",
4083 q.in.level, nt_errstr(status));
4086 uint32_t expected_flags = (acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
4087 if (acct_flags == ACB_NORMAL) {
4088 expected_flags |= ACB_PW_EXPIRED;
4090 if ((info->info5.acct_flags) != expected_flags) {
4091 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
4092 info->info5.acct_flags,
4096 switch (acct_flags) {
4098 if (info->info5.primary_gid != DOMAIN_RID_DCS) {
4099 printf("QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n",
4100 DOMAIN_RID_DCS, info->info5.primary_gid);
4105 if (info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
4106 printf("QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
4107 DOMAIN_RID_DOMAIN_MEMBERS, info->info5.primary_gid);
4112 if (info->info5.primary_gid != DOMAIN_RID_USERS) {
4113 printf("QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n",
4114 DOMAIN_RID_USERS, info->info5.primary_gid);
4121 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
4122 acct_flags, name.string, which_ops,
4123 machine_credentials)) {
4127 printf("Testing DeleteUser (createuser2 test)\n");
4129 d.in.user_handle = &user_handle;
4130 d.out.user_handle = &user_handle;
4132 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
4133 if (!NT_STATUS_IS_OK(status)) {
4134 printf("DeleteUser failed - %s\n", nt_errstr(status));
4138 talloc_free(user_ctx);
4144 static bool test_QueryAliasInfo(struct dcerpc_pipe *p,
4145 struct torture_context *tctx,
4146 struct policy_handle *handle)
4149 struct samr_QueryAliasInfo r;
4150 union samr_AliasInfo *info;
4151 uint16_t levels[] = {1, 2, 3};
4155 for (i=0;i<ARRAY_SIZE(levels);i++) {
4156 printf("Testing QueryAliasInfo level %u\n", levels[i]);
4158 r.in.alias_handle = handle;
4159 r.in.level = levels[i];
4162 status = dcerpc_samr_QueryAliasInfo(p, tctx, &r);
4163 if (!NT_STATUS_IS_OK(status)) {
4164 printf("QueryAliasInfo level %u failed - %s\n",
4165 levels[i], nt_errstr(status));
4173 static bool test_QueryGroupInfo(struct dcerpc_pipe *p,
4174 struct torture_context *tctx,
4175 struct policy_handle *handle)
4178 struct samr_QueryGroupInfo r;
4179 union samr_GroupInfo *info;
4180 uint16_t levels[] = {1, 2, 3, 4, 5};
4184 for (i=0;i<ARRAY_SIZE(levels);i++) {
4185 printf("Testing QueryGroupInfo level %u\n", levels[i]);
4187 r.in.group_handle = handle;
4188 r.in.level = levels[i];
4191 status = dcerpc_samr_QueryGroupInfo(p, tctx, &r);
4192 if (!NT_STATUS_IS_OK(status)) {
4193 printf("QueryGroupInfo level %u failed - %s\n",
4194 levels[i], nt_errstr(status));
4202 static bool test_QueryGroupMember(struct dcerpc_pipe *p,
4203 struct torture_context *tctx,
4204 struct policy_handle *handle)
4207 struct samr_QueryGroupMember r;
4208 struct samr_RidTypeArray *rids = NULL;
4211 printf("Testing QueryGroupMember\n");
4213 r.in.group_handle = handle;
4216 status = dcerpc_samr_QueryGroupMember(p, tctx, &r);
4217 if (!NT_STATUS_IS_OK(status)) {
4218 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
4226 static bool test_SetGroupInfo(struct dcerpc_pipe *p,
4227 struct torture_context *tctx,
4228 struct policy_handle *handle)
4231 struct samr_QueryGroupInfo r;
4232 union samr_GroupInfo *info;
4233 struct samr_SetGroupInfo s;
4234 uint16_t levels[] = {1, 2, 3, 4};
4235 uint16_t set_ok[] = {0, 1, 1, 1};
4239 for (i=0;i<ARRAY_SIZE(levels);i++) {
4240 printf("Testing QueryGroupInfo level %u\n", levels[i]);
4242 r.in.group_handle = handle;
4243 r.in.level = levels[i];
4246 status = dcerpc_samr_QueryGroupInfo(p, tctx, &r);
4247 if (!NT_STATUS_IS_OK(status)) {
4248 printf("QueryGroupInfo level %u failed - %s\n",
4249 levels[i], nt_errstr(status));
4253 printf("Testing SetGroupInfo level %u\n", levels[i]);
4255 s.in.group_handle = handle;
4256 s.in.level = levels[i];
4257 s.in.info = *r.out.info;
4260 /* disabled this, as it changes the name only from the point of view of samr,
4261 but leaves the name from the point of view of w2k3 internals (and ldap). This means
4262 the name is still reserved, so creating the old name fails, but deleting by the old name
4264 if (s.in.level == 2) {
4265 init_lsa_String(&s.in.info->string, "NewName");
4269 if (s.in.level == 4) {
4270 init_lsa_String(&s.in.info->description, "test description");
4273 status = dcerpc_samr_SetGroupInfo(p, tctx, &s);
4275 if (!NT_STATUS_IS_OK(status)) {
4276 printf("SetGroupInfo level %u failed - %s\n",
4277 r.in.level, nt_errstr(status));
4282 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
4283 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
4284 r.in.level, nt_errstr(status));
4294 static bool test_QueryUserInfo(struct dcerpc_pipe *p,
4295 struct torture_context *tctx,
4296 struct policy_handle *handle)
4299 struct samr_QueryUserInfo r;
4300 union samr_UserInfo *info;
4301 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
4302 11, 12, 13, 14, 16, 17, 20, 21};
4306 for (i=0;i<ARRAY_SIZE(levels);i++) {
4307 printf("Testing QueryUserInfo level %u\n", levels[i]);
4309 r.in.user_handle = handle;
4310 r.in.level = levels[i];
4313 status = dcerpc_samr_QueryUserInfo(p, tctx, &r);
4314 if (!NT_STATUS_IS_OK(status)) {
4315 printf("QueryUserInfo level %u failed - %s\n",
4316 levels[i], nt_errstr(status));
4324 static bool test_QueryUserInfo2(struct dcerpc_pipe *p,
4325 struct torture_context *tctx,
4326 struct policy_handle *handle)
4329 struct samr_QueryUserInfo2 r;
4330 union samr_UserInfo *info;
4331 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
4332 11, 12, 13, 14, 16, 17, 20, 21};
4336 for (i=0;i<ARRAY_SIZE(levels);i++) {
4337 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
4339 r.in.user_handle = handle;
4340 r.in.level = levels[i];
4343 status = dcerpc_samr_QueryUserInfo2(p, tctx, &r);
4344 if (!NT_STATUS_IS_OK(status)) {
4345 printf("QueryUserInfo2 level %u failed - %s\n",
4346 levels[i], nt_errstr(status));
4354 static bool test_OpenUser(struct dcerpc_pipe *p,
4355 struct torture_context *tctx,
4356 struct policy_handle *handle, uint32_t rid)
4359 struct samr_OpenUser r;
4360 struct policy_handle user_handle;
4363 printf("Testing OpenUser(%u)\n", rid);
4365 r.in.domain_handle = handle;
4366 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4368 r.out.user_handle = &user_handle;
4370 status = dcerpc_samr_OpenUser(p, tctx, &r);
4371 if (!NT_STATUS_IS_OK(status)) {
4372 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
4376 if (!test_QuerySecurity(p, tctx, &user_handle)) {
4380 if (!test_QueryUserInfo(p, tctx, &user_handle)) {
4384 if (!test_QueryUserInfo2(p, tctx, &user_handle)) {
4388 if (!test_GetUserPwInfo(p, tctx, &user_handle)) {
4392 if (!test_GetGroupsForUser(p,tctx, &user_handle)) {
4396 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
4403 static bool test_OpenGroup(struct dcerpc_pipe *p,
4404 struct torture_context *tctx,
4405 struct policy_handle *handle, uint32_t rid)
4408 struct samr_OpenGroup r;
4409 struct policy_handle group_handle;
4412 printf("Testing OpenGroup(%u)\n", rid);
4414 r.in.domain_handle = handle;
4415 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4417 r.out.group_handle = &group_handle;
4419 status = dcerpc_samr_OpenGroup(p, tctx, &r);
4420 if (!NT_STATUS_IS_OK(status)) {
4421 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
4425 if (!torture_setting_bool(tctx, "samba3", false)) {
4426 if (!test_QuerySecurity(p, tctx, &group_handle)) {
4431 if (!test_QueryGroupInfo(p, tctx, &group_handle)) {
4435 if (!test_QueryGroupMember(p, tctx, &group_handle)) {
4439 if (!test_samr_handle_Close(p, tctx, &group_handle)) {
4446 static bool test_OpenAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
4447 struct policy_handle *handle, uint32_t rid)
4450 struct samr_OpenAlias r;
4451 struct policy_handle alias_handle;
4454 torture_comment(tctx, "Testing OpenAlias(%u)\n", rid);
4456 r.in.domain_handle = handle;
4457 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4459 r.out.alias_handle = &alias_handle;
4461 status = dcerpc_samr_OpenAlias(p, tctx, &r);
4462 if (!NT_STATUS_IS_OK(status)) {
4463 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
4467 if (!torture_setting_bool(tctx, "samba3", false)) {
4468 if (!test_QuerySecurity(p, tctx, &alias_handle)) {
4473 if (!test_QueryAliasInfo(p, tctx, &alias_handle)) {
4477 if (!test_GetMembersInAlias(p, tctx, &alias_handle)) {
4481 if (!test_samr_handle_Close(p, tctx, &alias_handle)) {
4488 static bool check_mask(struct dcerpc_pipe *p, struct torture_context *tctx,
4489 struct policy_handle *handle, uint32_t rid,
4490 uint32_t acct_flag_mask)
4493 struct samr_OpenUser r;
4494 struct samr_QueryUserInfo q;
4495 union samr_UserInfo *info;
4496 struct policy_handle user_handle;
4499 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
4501 r.in.domain_handle = handle;
4502 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4504 r.out.user_handle = &user_handle;
4506 status = dcerpc_samr_OpenUser(p, tctx, &r);
4507 if (!NT_STATUS_IS_OK(status)) {
4508 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
4512 q.in.user_handle = &user_handle;
4516 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
4517 if (!NT_STATUS_IS_OK(status)) {
4518 printf("QueryUserInfo level 16 failed - %s\n",
4522 if ((acct_flag_mask & info->info16.acct_flags) == 0) {
4523 printf("Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
4524 acct_flag_mask, info->info16.acct_flags, rid);
4529 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
4536 static bool test_EnumDomainUsers(struct dcerpc_pipe *p, struct torture_context *tctx,
4537 struct policy_handle *handle)
4539 NTSTATUS status = STATUS_MORE_ENTRIES;
4540 struct samr_EnumDomainUsers r;
4541 uint32_t mask, resume_handle=0;
4544 struct samr_LookupNames n;
4545 struct samr_LookupRids lr ;
4546 struct lsa_Strings names;
4547 struct samr_Ids rids, types;
4548 struct samr_SamArray *sam = NULL;
4549 uint32_t num_entries = 0;
4551 uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
4552 ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
4553 ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
4556 printf("Testing EnumDomainUsers\n");
4558 for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
4559 r.in.domain_handle = handle;
4560 r.in.resume_handle = &resume_handle;
4561 r.in.acct_flags = mask = masks[mask_idx];
4562 r.in.max_size = (uint32_t)-1;
4563 r.out.resume_handle = &resume_handle;
4564 r.out.num_entries = &num_entries;
4567 status = dcerpc_samr_EnumDomainUsers(p, tctx, &r);
4568 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
4569 !NT_STATUS_IS_OK(status)) {
4570 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
4574 torture_assert(tctx, sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
4576 if (sam->count == 0) {
4580 for (i=0;i<sam->count;i++) {
4582 if (!check_mask(p, tctx, handle, sam->entries[i].idx, mask)) {
4585 } else if (!test_OpenUser(p, tctx, handle, sam->entries[i].idx)) {
4591 printf("Testing LookupNames\n");
4592 n.in.domain_handle = handle;
4593 n.in.num_names = sam->count;
4594 n.in.names = talloc_array(tctx, struct lsa_String, sam->count);
4596 n.out.types = &types;
4597 for (i=0;i<sam->count;i++) {
4598 n.in.names[i].string = sam->entries[i].name.string;
4600 status = dcerpc_samr_LookupNames(p, tctx, &n);
4601 if (!NT_STATUS_IS_OK(status)) {
4602 printf("LookupNames failed - %s\n", nt_errstr(status));
4607 printf("Testing LookupRids\n");
4608 lr.in.domain_handle = handle;
4609 lr.in.num_rids = sam->count;
4610 lr.in.rids = talloc_array(tctx, uint32_t, sam->count);
4611 lr.out.names = &names;
4612 lr.out.types = &types;
4613 for (i=0;i<sam->count;i++) {
4614 lr.in.rids[i] = sam->entries[i].idx;
4616 status = dcerpc_samr_LookupRids(p, tctx, &lr);
4617 torture_assert_ntstatus_ok(tctx, status, "LookupRids");
4623 try blasting the server with a bunch of sync requests
4625 static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, struct torture_context *tctx,
4626 struct policy_handle *handle)
4629 struct samr_EnumDomainUsers r;
4630 uint32_t resume_handle=0;
4632 #define ASYNC_COUNT 100
4633 struct rpc_request *req[ASYNC_COUNT];
4635 if (!torture_setting_bool(tctx, "dangerous", false)) {
4636 torture_skip(tctx, "samr async test disabled - enable dangerous tests to use\n");
4639 torture_comment(tctx, "Testing EnumDomainUsers_async\n");
4641 r.in.domain_handle = handle;
4642 r.in.resume_handle = &resume_handle;
4643 r.in.acct_flags = 0;
4644 r.in.max_size = (uint32_t)-1;
4645 r.out.resume_handle = &resume_handle;
4647 for (i=0;i<ASYNC_COUNT;i++) {
4648 req[i] = dcerpc_samr_EnumDomainUsers_send(p, tctx, &r);
4651 for (i=0;i<ASYNC_COUNT;i++) {
4652 status = dcerpc_ndr_request_recv(req[i]);
4653 if (!NT_STATUS_IS_OK(status)) {
4654 printf("EnumDomainUsers[%d] failed - %s\n",
4655 i, nt_errstr(status));
4660 torture_comment(tctx, "%d async requests OK\n", i);
4665 static bool test_EnumDomainGroups(struct dcerpc_pipe *p,
4666 struct torture_context *tctx,
4667 struct policy_handle *handle)
4670 struct samr_EnumDomainGroups r;
4671 uint32_t resume_handle=0;
4672 struct samr_SamArray *sam = NULL;
4673 uint32_t num_entries = 0;
4677 printf("Testing EnumDomainGroups\n");
4679 r.in.domain_handle = handle;
4680 r.in.resume_handle = &resume_handle;
4681 r.in.max_size = (uint32_t)-1;
4682 r.out.resume_handle = &resume_handle;
4683 r.out.num_entries = &num_entries;
4686 status = dcerpc_samr_EnumDomainGroups(p, tctx, &r);
4687 if (!NT_STATUS_IS_OK(status)) {
4688 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
4696 for (i=0;i<sam->count;i++) {
4697 if (!test_OpenGroup(p, tctx, handle, sam->entries[i].idx)) {
4705 static bool test_EnumDomainAliases(struct dcerpc_pipe *p,
4706 struct torture_context *tctx,
4707 struct policy_handle *handle)
4710 struct samr_EnumDomainAliases r;
4711 uint32_t resume_handle=0;
4712 struct samr_SamArray *sam = NULL;
4713 uint32_t num_entries = 0;
4717 printf("Testing EnumDomainAliases\n");
4719 r.in.domain_handle = handle;
4720 r.in.resume_handle = &resume_handle;
4721 r.in.max_size = (uint32_t)-1;
4723 r.out.num_entries = &num_entries;
4724 r.out.resume_handle = &resume_handle;
4726 status = dcerpc_samr_EnumDomainAliases(p, tctx, &r);
4727 if (!NT_STATUS_IS_OK(status)) {
4728 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
4736 for (i=0;i<sam->count;i++) {
4737 if (!test_OpenAlias(p, tctx, handle, sam->entries[i].idx)) {
4745 static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p,
4746 struct torture_context *tctx,
4747 struct policy_handle *handle)
4750 struct samr_GetDisplayEnumerationIndex r;
4752 uint16_t levels[] = {1, 2, 3, 4, 5};
4753 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
4754 struct lsa_String name;
4758 for (i=0;i<ARRAY_SIZE(levels);i++) {
4759 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
4761 init_lsa_String(&name, TEST_ACCOUNT_NAME);
4763 r.in.domain_handle = handle;
4764 r.in.level = levels[i];
4768 status = dcerpc_samr_GetDisplayEnumerationIndex(p, tctx, &r);
4771 !NT_STATUS_IS_OK(status) &&
4772 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
4773 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
4774 levels[i], nt_errstr(status));
4778 init_lsa_String(&name, "zzzzzzzz");
4780 status = dcerpc_samr_GetDisplayEnumerationIndex(p, tctx, &r);
4782 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
4783 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
4784 levels[i], nt_errstr(status));
4792 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p,
4793 struct torture_context *tctx,
4794 struct policy_handle *handle)
4797 struct samr_GetDisplayEnumerationIndex2 r;
4799 uint16_t levels[] = {1, 2, 3, 4, 5};
4800 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
4801 struct lsa_String name;
4805 for (i=0;i<ARRAY_SIZE(levels);i++) {
4806 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
4808 init_lsa_String(&name, TEST_ACCOUNT_NAME);
4810 r.in.domain_handle = handle;
4811 r.in.level = levels[i];
4815 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, tctx, &r);
4817 !NT_STATUS_IS_OK(status) &&
4818 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
4819 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
4820 levels[i], nt_errstr(status));
4824 init_lsa_String(&name, "zzzzzzzz");
4826 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, tctx, &r);
4827 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
4828 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
4829 levels[i], nt_errstr(status));
4837 #define STRING_EQUAL_QUERY(s1, s2, user) \
4838 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
4839 /* odd, but valid */ \
4840 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
4841 printf("%s mismatch for %s: %s != %s (%s)\n", \
4842 #s1, user.string, s1.string, s2.string, __location__); \
4845 #define INT_EQUAL_QUERY(s1, s2, user) \
4847 printf("%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
4848 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
4852 static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p,
4853 struct torture_context *tctx,
4854 struct samr_QueryDisplayInfo *querydisplayinfo,
4855 bool *seen_testuser)
4857 struct samr_OpenUser r;
4858 struct samr_QueryUserInfo q;
4859 union samr_UserInfo *info;
4860 struct policy_handle user_handle;
4863 r.in.domain_handle = querydisplayinfo->in.domain_handle;
4864 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4865 for (i = 0; ; i++) {
4866 switch (querydisplayinfo->in.level) {
4868 if (i >= querydisplayinfo->out.info->info1.count) {
4871 r.in.rid = querydisplayinfo->out.info->info1.entries[i].rid;
4874 if (i >= querydisplayinfo->out.info->info2.count) {
4877 r.in.rid = querydisplayinfo->out.info->info2.entries[i].rid;
4883 /* Not interested in validating just the account name */
4887 r.out.user_handle = &user_handle;
4889 switch (querydisplayinfo->in.level) {
4892 status = dcerpc_samr_OpenUser(p, tctx, &r);
4893 if (!NT_STATUS_IS_OK(status)) {
4894 printf("OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(status));
4899 q.in.user_handle = &user_handle;
4902 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
4903 if (!NT_STATUS_IS_OK(status)) {
4904 printf("QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(status));
4908 switch (querydisplayinfo->in.level) {
4910 if (seen_testuser && strcmp(info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
4911 *seen_testuser = true;
4913 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].full_name,
4914 info->info21.full_name, info->info21.account_name);
4915 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].account_name,
4916 info->info21.account_name, info->info21.account_name);
4917 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].description,
4918 info->info21.description, info->info21.account_name);
4919 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].rid,
4920 info->info21.rid, info->info21.account_name);
4921 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].acct_flags,
4922 info->info21.acct_flags, info->info21.account_name);
4926 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].account_name,
4927 info->info21.account_name, info->info21.account_name);
4928 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].description,
4929 info->info21.description, info->info21.account_name);
4930 INT_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].rid,
4931 info->info21.rid, info->info21.account_name);
4932 INT_EQUAL_QUERY((querydisplayinfo->out.info->info2.entries[i].acct_flags & ~ACB_NORMAL),
4933 info->info21.acct_flags, info->info21.account_name);
4935 if (!(querydisplayinfo->out.info->info2.entries[i].acct_flags & ACB_NORMAL)) {
4936 printf("Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
4937 info->info21.account_name.string);
4940 if (!(info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
4941 printf("Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
4942 info->info21.account_name.string,
4943 querydisplayinfo->out.info->info2.entries[i].acct_flags,
4944 info->info21.acct_flags);
4951 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
4958 static bool test_QueryDisplayInfo(struct dcerpc_pipe *p,
4959 struct torture_context *tctx,
4960 struct policy_handle *handle)
4963 struct samr_QueryDisplayInfo r;
4964 struct samr_QueryDomainInfo dom_info;
4965 union samr_DomainInfo *info = NULL;
4967 uint16_t levels[] = {1, 2, 3, 4, 5};
4969 bool seen_testuser = false;
4970 uint32_t total_size;
4971 uint32_t returned_size;
4972 union samr_DispInfo disp_info;
4975 for (i=0;i<ARRAY_SIZE(levels);i++) {
4976 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
4979 status = STATUS_MORE_ENTRIES;
4980 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
4981 r.in.domain_handle = handle;
4982 r.in.level = levels[i];
4983 r.in.max_entries = 2;
4984 r.in.buf_size = (uint32_t)-1;
4985 r.out.total_size = &total_size;
4986 r.out.returned_size = &returned_size;
4987 r.out.info = &disp_info;
4989 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &r);
4990 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(status)) {
4991 printf("QueryDisplayInfo level %u failed - %s\n",
4992 levels[i], nt_errstr(status));
4995 switch (r.in.level) {
4997 if (!test_each_DisplayInfo_user(p, tctx, &r, &seen_testuser)) {
5000 r.in.start_idx += r.out.info->info1.count;
5003 if (!test_each_DisplayInfo_user(p, tctx, &r, NULL)) {
5006 r.in.start_idx += r.out.info->info2.count;
5009 r.in.start_idx += r.out.info->info3.count;
5012 r.in.start_idx += r.out.info->info4.count;
5015 r.in.start_idx += r.out.info->info5.count;
5019 dom_info.in.domain_handle = handle;
5020 dom_info.in.level = 2;
5021 dom_info.out.info = &info;
5023 /* Check number of users returned is correct */
5024 status = dcerpc_samr_QueryDomainInfo(p, tctx, &dom_info);
5025 if (!NT_STATUS_IS_OK(status)) {
5026 printf("QueryDomainInfo level %u failed - %s\n",
5027 r.in.level, nt_errstr(status));
5031 switch (r.in.level) {
5034 if (info->general.num_users < r.in.start_idx) {
5035 printf("QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
5036 r.in.start_idx, info->general.num_groups,
5037 info->general.domain_name.string);
5040 if (!seen_testuser) {
5041 struct policy_handle user_handle;
5042 if (NT_STATUS_IS_OK(test_OpenUser_byname(p, tctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
5043 printf("Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
5044 info->general.domain_name.string);
5046 test_samr_handle_Close(p, tctx, &user_handle);
5052 if (info->general.num_groups != r.in.start_idx) {
5053 printf("QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
5054 r.in.start_idx, info->general.num_groups,
5055 info->general.domain_name.string);
5067 static bool test_QueryDisplayInfo2(struct dcerpc_pipe *p,
5068 struct torture_context *tctx,
5069 struct policy_handle *handle)
5072 struct samr_QueryDisplayInfo2 r;
5074 uint16_t levels[] = {1, 2, 3, 4, 5};
5076 uint32_t total_size;
5077 uint32_t returned_size;
5078 union samr_DispInfo info;
5080 for (i=0;i<ARRAY_SIZE(levels);i++) {
5081 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
5083 r.in.domain_handle = handle;
5084 r.in.level = levels[i];
5086 r.in.max_entries = 1000;
5087 r.in.buf_size = (uint32_t)-1;
5088 r.out.total_size = &total_size;
5089 r.out.returned_size = &returned_size;
5092 status = dcerpc_samr_QueryDisplayInfo2(p, tctx, &r);
5093 if (!NT_STATUS_IS_OK(status)) {
5094 printf("QueryDisplayInfo2 level %u failed - %s\n",
5095 levels[i], nt_errstr(status));
5103 static bool test_QueryDisplayInfo3(struct dcerpc_pipe *p, struct torture_context *tctx,
5104 struct policy_handle *handle)
5107 struct samr_QueryDisplayInfo3 r;
5109 uint16_t levels[] = {1, 2, 3, 4, 5};
5111 uint32_t total_size;
5112 uint32_t returned_size;
5113 union samr_DispInfo info;
5115 for (i=0;i<ARRAY_SIZE(levels);i++) {
5116 torture_comment(tctx, "Testing QueryDisplayInfo3 level %u\n", levels[i]);
5118 r.in.domain_handle = handle;
5119 r.in.level = levels[i];
5121 r.in.max_entries = 1000;
5122 r.in.buf_size = (uint32_t)-1;
5123 r.out.total_size = &total_size;
5124 r.out.returned_size = &returned_size;
5127 status = dcerpc_samr_QueryDisplayInfo3(p, tctx, &r);
5128 if (!NT_STATUS_IS_OK(status)) {
5129 printf("QueryDisplayInfo3 level %u failed - %s\n",
5130 levels[i], nt_errstr(status));
5139 static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p,
5140 struct torture_context *tctx,
5141 struct policy_handle *handle)
5144 struct samr_QueryDisplayInfo r;
5146 uint32_t total_size;
5147 uint32_t returned_size;
5148 union samr_DispInfo info;
5150 printf("Testing QueryDisplayInfo continuation\n");
5152 r.in.domain_handle = handle;
5155 r.in.max_entries = 1;
5156 r.in.buf_size = (uint32_t)-1;
5157 r.out.total_size = &total_size;
5158 r.out.returned_size = &returned_size;
5162 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &r);
5163 if (NT_STATUS_IS_OK(status) && *r.out.returned_size != 0) {
5164 if (r.out.info->info1.entries[0].idx != r.in.start_idx + 1) {
5165 printf("expected idx %d but got %d\n",
5167 r.out.info->info1.entries[0].idx);
5171 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
5172 !NT_STATUS_IS_OK(status)) {
5173 printf("QueryDisplayInfo level %u failed - %s\n",
5174 r.in.level, nt_errstr(status));
5179 } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
5180 NT_STATUS_IS_OK(status)) &&
5181 *r.out.returned_size != 0);
5186 static bool test_QueryDomainInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
5187 struct policy_handle *handle)
5190 struct samr_QueryDomainInfo r;
5191 union samr_DomainInfo *info = NULL;
5192 struct samr_SetDomainInfo s;
5193 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
5194 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
5197 const char *domain_comment = talloc_asprintf(tctx,
5198 "Tortured by Samba4 RPC-SAMR: %s",
5199 timestring(tctx, time(NULL)));
5201 s.in.domain_handle = handle;
5203 s.in.info = talloc(tctx, union samr_DomainInfo);
5205 s.in.info->oem.oem_information.string = domain_comment;
5206 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
5207 if (!NT_STATUS_IS_OK(status)) {
5208 printf("SetDomainInfo level %u (set comment) failed - %s\n",
5209 s.in.level, nt_errstr(status));
5213 for (i=0;i<ARRAY_SIZE(levels);i++) {
5214 torture_comment(tctx, "Testing QueryDomainInfo level %u\n", levels[i]);
5216 r.in.domain_handle = handle;
5217 r.in.level = levels[i];
5220 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
5221 if (!NT_STATUS_IS_OK(status)) {
5222 printf("QueryDomainInfo level %u failed - %s\n",
5223 r.in.level, nt_errstr(status));
5228 switch (levels[i]) {
5230 if (strcmp(info->general.oem_information.string, domain_comment) != 0) {
5231 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
5232 levels[i], info->general.oem_information.string, domain_comment);
5235 if (!info->general.primary.string) {
5236 printf("QueryDomainInfo level %u returned no PDC name\n",
5239 } else if (info->general.role == SAMR_ROLE_DOMAIN_PDC) {
5240 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), info->general.primary.string) != 0) {
5241 printf("QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
5242 levels[i], info->general.primary.string, dcerpc_server_name(p));
5247 if (strcmp(info->oem.oem_information.string, domain_comment) != 0) {
5248 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
5249 levels[i], info->oem.oem_information.string, domain_comment);
5254 if (!info->info6.primary.string) {
5255 printf("QueryDomainInfo level %u returned no PDC name\n",
5261 if (strcmp(info->general2.general.oem_information.string, domain_comment) != 0) {
5262 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
5263 levels[i], info->general2.general.oem_information.string, domain_comment);
5269 torture_comment(tctx, "Testing SetDomainInfo level %u\n", levels[i]);
5271 s.in.domain_handle = handle;
5272 s.in.level = levels[i];
5275 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
5277 if (!NT_STATUS_IS_OK(status)) {
5278 printf("SetDomainInfo level %u failed - %s\n",
5279 r.in.level, nt_errstr(status));
5284 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
5285 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
5286 r.in.level, nt_errstr(status));
5292 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
5293 if (!NT_STATUS_IS_OK(status)) {
5294 printf("QueryDomainInfo level %u failed - %s\n",
5295 r.in.level, nt_errstr(status));
5305 static bool test_QueryDomainInfo2(struct dcerpc_pipe *p, struct torture_context *tctx,
5306 struct policy_handle *handle)
5309 struct samr_QueryDomainInfo2 r;
5310 union samr_DomainInfo *info = NULL;
5311 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
5315 for (i=0;i<ARRAY_SIZE(levels);i++) {
5316 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
5318 r.in.domain_handle = handle;
5319 r.in.level = levels[i];
5322 status = dcerpc_samr_QueryDomainInfo2(p, tctx, &r);
5323 if (!NT_STATUS_IS_OK(status)) {
5324 printf("QueryDomainInfo2 level %u failed - %s\n",
5325 r.in.level, nt_errstr(status));
5334 /* Test whether querydispinfo level 5 and enumdomgroups return the same
5335 set of group names. */
5336 static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx,
5337 struct policy_handle *handle)
5339 struct samr_EnumDomainGroups q1;
5340 struct samr_QueryDisplayInfo q2;
5342 uint32_t resume_handle=0;
5343 struct samr_SamArray *sam = NULL;
5344 uint32_t num_entries = 0;
5347 uint32_t total_size;
5348 uint32_t returned_size;
5349 union samr_DispInfo info;
5352 const char **names = NULL;
5354 torture_comment(tctx, "Testing coherency of querydispinfo vs enumdomgroups\n");
5356 q1.in.domain_handle = handle;
5357 q1.in.resume_handle = &resume_handle;
5359 q1.out.resume_handle = &resume_handle;
5360 q1.out.num_entries = &num_entries;
5363 status = STATUS_MORE_ENTRIES;
5364 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
5365 status = dcerpc_samr_EnumDomainGroups(p, tctx, &q1);
5367 if (!NT_STATUS_IS_OK(status) &&
5368 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
5371 for (i=0; i<*q1.out.num_entries; i++) {
5372 add_string_to_array(tctx,
5373 sam->entries[i].name.string,
5374 &names, &num_names);
5378 torture_assert_ntstatus_ok(tctx, status, "EnumDomainGroups");
5380 torture_assert(tctx, sam, "EnumDomainGroups failed to return sam");
5382 q2.in.domain_handle = handle;
5384 q2.in.start_idx = 0;
5385 q2.in.max_entries = 5;
5386 q2.in.buf_size = (uint32_t)-1;
5387 q2.out.total_size = &total_size;
5388 q2.out.returned_size = &returned_size;
5389 q2.out.info = &info;
5391 status = STATUS_MORE_ENTRIES;
5392 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
5393 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &q2);
5395 if (!NT_STATUS_IS_OK(status) &&
5396 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
5399 for (i=0; i<q2.out.info->info5.count; i++) {
5401 const char *name = q2.out.info->info5.entries[i].account_name.string;
5403 for (j=0; j<num_names; j++) {
5404 if (names[j] == NULL)
5406 if (strequal(names[j], name)) {
5414 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
5419 q2.in.start_idx += q2.out.info->info5.count;
5422 if (!NT_STATUS_IS_OK(status)) {
5423 printf("QueryDisplayInfo level 5 failed - %s\n",
5428 for (i=0; i<num_names; i++) {
5429 if (names[i] != NULL) {
5430 printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
5439 static bool test_DeleteDomainGroup(struct dcerpc_pipe *p, struct torture_context *tctx,
5440 struct policy_handle *group_handle)
5442 struct samr_DeleteDomainGroup d;
5445 torture_comment(tctx, "Testing DeleteDomainGroup\n");
5447 d.in.group_handle = group_handle;
5448 d.out.group_handle = group_handle;
5450 status = dcerpc_samr_DeleteDomainGroup(p, tctx, &d);
5451 torture_assert_ntstatus_ok(tctx, status, "DeleteDomainGroup");
5456 static bool test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
5457 struct policy_handle *domain_handle)
5459 struct samr_TestPrivateFunctionsDomain r;
5463 torture_comment(tctx, "Testing TestPrivateFunctionsDomain\n");
5465 r.in.domain_handle = domain_handle;
5467 status = dcerpc_samr_TestPrivateFunctionsDomain(p, tctx, &r);
5468 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsDomain");
5473 static bool test_RidToSid(struct dcerpc_pipe *p, struct torture_context *tctx,
5474 struct dom_sid *domain_sid,
5475 struct policy_handle *domain_handle)
5477 struct samr_RidToSid r;
5480 struct dom_sid *calc_sid, *out_sid;
5481 int rids[] = { 0, 42, 512, 10200 };
5484 for (i=0;i<ARRAY_SIZE(rids);i++) {
5485 torture_comment(tctx, "Testing RidToSid\n");
5487 calc_sid = dom_sid_dup(tctx, domain_sid);
5488 r.in.domain_handle = domain_handle;
5490 r.out.sid = &out_sid;
5492 status = dcerpc_samr_RidToSid(p, tctx, &r);
5493 if (!NT_STATUS_IS_OK(status)) {
5494 printf("RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
5497 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
5499 if (!dom_sid_equal(calc_sid, out_sid)) {
5500 printf("RidToSid for %d failed - got %s, expected %s\n", rids[i],
5501 dom_sid_string(tctx, out_sid),
5502 dom_sid_string(tctx, calc_sid));
5511 static bool test_GetBootKeyInformation(struct dcerpc_pipe *p, struct torture_context *tctx,
5512 struct policy_handle *domain_handle)
5514 struct samr_GetBootKeyInformation r;
5517 uint32_t unknown = 0;
5519 torture_comment(tctx, "Testing GetBootKeyInformation\n");
5521 r.in.domain_handle = domain_handle;
5522 r.out.unknown = &unknown;
5524 status = dcerpc_samr_GetBootKeyInformation(p, tctx, &r);
5525 if (!NT_STATUS_IS_OK(status)) {
5526 /* w2k3 seems to fail this sometimes and pass it sometimes */
5527 torture_comment(tctx, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
5533 static bool test_AddGroupMember(struct dcerpc_pipe *p, struct torture_context *tctx,
5534 struct policy_handle *domain_handle,
5535 struct policy_handle *group_handle)
5538 struct samr_AddGroupMember r;
5539 struct samr_DeleteGroupMember d;
5540 struct samr_QueryGroupMember q;
5541 struct samr_RidTypeArray *rids = NULL;
5542 struct samr_SetMemberAttributesOfGroup s;
5545 status = test_LookupName(p, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
5546 torture_assert_ntstatus_ok(tctx, status, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME);
5548 r.in.group_handle = group_handle;
5550 r.in.flags = 0; /* ??? */
5552 torture_comment(tctx, "Testing AddGroupMember and DeleteGroupMember\n");
5554 d.in.group_handle = group_handle;
5557 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
5558 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_NOT_IN_GROUP, status, "DeleteGroupMember");
5560 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5561 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
5563 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5564 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_IN_GROUP, status, "AddGroupMember");
5566 if (torture_setting_bool(tctx, "samba4", false)) {
5567 torture_comment(tctx, "skipping SetMemberAttributesOfGroup test against Samba4\n");
5569 /* this one is quite strange. I am using random inputs in the
5570 hope of triggering an error that might give us a clue */
5572 s.in.group_handle = group_handle;
5573 s.in.unknown1 = random();
5574 s.in.unknown2 = random();
5576 status = dcerpc_samr_SetMemberAttributesOfGroup(p, tctx, &s);
5577 torture_assert_ntstatus_ok(tctx, status, "SetMemberAttributesOfGroup");
5580 q.in.group_handle = group_handle;
5583 status = dcerpc_samr_QueryGroupMember(p, tctx, &q);
5584 torture_assert_ntstatus_ok(tctx, status, "QueryGroupMember");
5586 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
5587 torture_assert_ntstatus_ok(tctx, status, "DeleteGroupMember");
5589 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5590 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
5596 static bool test_CreateDomainGroup(struct dcerpc_pipe *p,
5597 struct torture_context *tctx,
5598 struct policy_handle *domain_handle,
5599 struct policy_handle *group_handle,
5600 struct dom_sid *domain_sid)
5603 struct samr_CreateDomainGroup r;
5605 struct lsa_String name;
5608 init_lsa_String(&name, TEST_GROUPNAME);
5610 r.in.domain_handle = domain_handle;
5612 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5613 r.out.group_handle = group_handle;
5616 printf("Testing CreateDomainGroup(%s)\n", r.in.name->string);
5618 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
5620 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5621 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5622 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.name->string);
5625 printf("Server should have refused create of '%s', got %s instead\n", r.in.name->string,
5631 if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS)) {
5632 if (!test_DeleteGroup_byname(p, tctx, domain_handle, r.in.name->string)) {
5633 printf("CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
5637 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
5639 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
5640 if (!test_DeleteUser_byname(p, tctx, domain_handle, r.in.name->string)) {
5642 printf("CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
5646 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
5648 torture_assert_ntstatus_ok(tctx, status, "CreateDomainGroup");
5650 if (!test_AddGroupMember(p, tctx, domain_handle, group_handle)) {
5651 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
5655 if (!test_SetGroupInfo(p, tctx, group_handle)) {
5664 its not totally clear what this does. It seems to accept any sid you like.
5666 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p,
5667 struct torture_context *tctx,
5668 struct policy_handle *domain_handle)
5671 struct samr_RemoveMemberFromForeignDomain r;
5673 r.in.domain_handle = domain_handle;
5674 r.in.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-12-34-56-78");
5676 status = dcerpc_samr_RemoveMemberFromForeignDomain(p, tctx, &r);
5677 torture_assert_ntstatus_ok(tctx, status, "RemoveMemberFromForeignDomain");
5684 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
5685 struct policy_handle *handle);
5687 static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
5688 struct policy_handle *handle, struct dom_sid *sid,
5689 enum torture_samr_choice which_ops,
5690 struct cli_credentials *machine_credentials)
5693 struct samr_OpenDomain r;
5694 struct policy_handle domain_handle;
5695 struct policy_handle alias_handle;
5696 struct policy_handle user_handle;
5697 struct policy_handle group_handle;
5700 ZERO_STRUCT(alias_handle);
5701 ZERO_STRUCT(user_handle);
5702 ZERO_STRUCT(group_handle);
5703 ZERO_STRUCT(domain_handle);
5705 torture_comment(tctx, "Testing OpenDomain of %s\n", dom_sid_string(tctx, sid));
5707 r.in.connect_handle = handle;
5708 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5710 r.out.domain_handle = &domain_handle;
5712 status = dcerpc_samr_OpenDomain(p, tctx, &r);
5713 torture_assert_ntstatus_ok(tctx, status, "OpenDomain");
5715 /* run the domain tests with the main handle closed - this tests
5716 the servers reference counting */
5717 ret &= test_samr_handle_Close(p, tctx, handle);
5719 switch (which_ops) {
5720 case TORTURE_SAMR_USER_ATTRIBUTES:
5721 case TORTURE_SAMR_PASSWORDS:
5722 if (!torture_setting_bool(tctx, "samba3", false)) {
5723 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops, NULL);
5725 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops, NULL);
5726 /* This test needs 'complex' users to validate */
5727 ret &= test_QueryDisplayInfo(p, tctx, &domain_handle);
5729 printf("Testing PASSWORDS or ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
5732 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
5733 if (!torture_setting_bool(tctx, "samba3", false)) {
5734 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops, machine_credentials);
5736 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops, machine_credentials);
5738 printf("Testing PASSWORDS PWDLASTSET on domain %s failed!\n", dom_sid_string(tctx, sid));
5741 case TORTURE_SAMR_OTHER:
5742 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops, NULL);
5744 printf("Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid));
5746 if (!torture_setting_bool(tctx, "samba3", false)) {
5747 ret &= test_QuerySecurity(p, tctx, &domain_handle);
5749 ret &= test_RemoveMemberFromForeignDomain(p, tctx, &domain_handle);
5750 ret &= test_CreateAlias(p, tctx, &domain_handle, &alias_handle, sid);
5751 ret &= test_CreateDomainGroup(p, tctx, &domain_handle, &group_handle, sid);
5752 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
5753 ret &= test_QueryDomainInfo2(p, tctx, &domain_handle);
5754 ret &= test_EnumDomainUsers(p, tctx, &domain_handle);
5755 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
5756 ret &= test_EnumDomainGroups(p, tctx, &domain_handle);
5757 ret &= test_EnumDomainAliases(p, tctx, &domain_handle);
5758 ret &= test_QueryDisplayInfo2(p, tctx, &domain_handle);
5759 ret &= test_QueryDisplayInfo3(p, tctx, &domain_handle);
5760 ret &= test_QueryDisplayInfo_continue(p, tctx, &domain_handle);
5762 if (torture_setting_bool(tctx, "samba4", false)) {
5763 torture_comment(tctx, "skipping GetDisplayEnumerationIndex test against Samba4\n");
5765 ret &= test_GetDisplayEnumerationIndex(p, tctx, &domain_handle);
5766 ret &= test_GetDisplayEnumerationIndex2(p, tctx, &domain_handle);
5768 ret &= test_GroupList(p, tctx, &domain_handle);
5769 ret &= test_TestPrivateFunctionsDomain(p, tctx, &domain_handle);
5770 ret &= test_RidToSid(p, tctx, sid, &domain_handle);
5771 ret &= test_GetBootKeyInformation(p, tctx, &domain_handle);
5773 torture_comment(tctx, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx, sid));
5778 if (!policy_handle_empty(&user_handle) &&
5779 !test_DeleteUser(p, tctx, &user_handle)) {
5783 if (!policy_handle_empty(&alias_handle) &&
5784 !test_DeleteAlias(p, tctx, &alias_handle)) {
5788 if (!policy_handle_empty(&group_handle) &&
5789 !test_DeleteDomainGroup(p, tctx, &group_handle)) {
5793 ret &= test_samr_handle_Close(p, tctx, &domain_handle);
5795 /* reconnect the main handle */
5796 ret &= test_Connect(p, tctx, handle);
5799 printf("Testing domain %s failed!\n", dom_sid_string(tctx, sid));
5805 static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
5806 struct policy_handle *handle, const char *domain,
5807 enum torture_samr_choice which_ops,
5808 struct cli_credentials *machine_credentials)
5811 struct samr_LookupDomain r;
5812 struct dom_sid2 *sid = NULL;
5813 struct lsa_String n1;
5814 struct lsa_String n2;
5817 torture_comment(tctx, "Testing LookupDomain(%s)\n", domain);
5819 /* check for correct error codes */
5820 r.in.connect_handle = handle;
5821 r.in.domain_name = &n2;
5825 status = dcerpc_samr_LookupDomain(p, tctx, &r);
5826 torture_assert_ntstatus_equal(tctx, NT_STATUS_INVALID_PARAMETER, status, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
5828 init_lsa_String(&n2, "xxNODOMAINxx");
5830 status = dcerpc_samr_LookupDomain(p, tctx, &r);
5831 torture_assert_ntstatus_equal(tctx, NT_STATUS_NO_SUCH_DOMAIN, status, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
5833 r.in.connect_handle = handle;
5835 init_lsa_String(&n1, domain);
5836 r.in.domain_name = &n1;
5838 status = dcerpc_samr_LookupDomain(p, tctx, &r);
5839 torture_assert_ntstatus_ok(tctx, status, "LookupDomain");
5841 if (!test_GetDomPwInfo(p, tctx, &n1)) {
5845 if (!test_OpenDomain(p, tctx, handle, *r.out.sid, which_ops,
5846 machine_credentials)) {
5854 static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
5855 struct policy_handle *handle, enum torture_samr_choice which_ops,
5856 struct cli_credentials *machine_credentials)
5859 struct samr_EnumDomains r;
5860 uint32_t resume_handle = 0;
5861 uint32_t num_entries = 0;
5862 struct samr_SamArray *sam = NULL;
5866 r.in.connect_handle = handle;
5867 r.in.resume_handle = &resume_handle;
5868 r.in.buf_size = (uint32_t)-1;
5869 r.out.resume_handle = &resume_handle;
5870 r.out.num_entries = &num_entries;
5873 status = dcerpc_samr_EnumDomains(p, tctx, &r);
5874 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
5880 for (i=0;i<sam->count;i++) {
5881 if (!test_LookupDomain(p, tctx, handle,
5882 sam->entries[i].name.string, which_ops,
5883 machine_credentials)) {
5888 status = dcerpc_samr_EnumDomains(p, tctx, &r);
5889 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
5895 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
5896 struct policy_handle *handle)
5899 struct samr_Connect r;
5900 struct samr_Connect2 r2;
5901 struct samr_Connect3 r3;
5902 struct samr_Connect4 r4;
5903 struct samr_Connect5 r5;
5904 union samr_ConnectInfo info;
5905 struct policy_handle h;
5906 uint32_t level_out = 0;
5907 bool ret = true, got_handle = false;
5909 torture_comment(tctx, "testing samr_Connect\n");
5911 r.in.system_name = 0;
5912 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5913 r.out.connect_handle = &h;
5915 status = dcerpc_samr_Connect(p, tctx, &r);
5916 if (!NT_STATUS_IS_OK(status)) {
5917 torture_comment(tctx, "Connect failed - %s\n", nt_errstr(status));
5924 torture_comment(tctx, "testing samr_Connect2\n");
5926 r2.in.system_name = NULL;
5927 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5928 r2.out.connect_handle = &h;
5930 status = dcerpc_samr_Connect2(p, tctx, &r2);
5931 if (!NT_STATUS_IS_OK(status)) {
5932 torture_comment(tctx, "Connect2 failed - %s\n", nt_errstr(status));
5936 test_samr_handle_Close(p, tctx, handle);
5942 torture_comment(tctx, "testing samr_Connect3\n");
5944 r3.in.system_name = NULL;
5946 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5947 r3.out.connect_handle = &h;
5949 status = dcerpc_samr_Connect3(p, tctx, &r3);
5950 if (!NT_STATUS_IS_OK(status)) {
5951 printf("Connect3 failed - %s\n", nt_errstr(status));
5955 test_samr_handle_Close(p, tctx, handle);
5961 torture_comment(tctx, "testing samr_Connect4\n");
5963 r4.in.system_name = "";
5964 r4.in.client_version = 0;
5965 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5966 r4.out.connect_handle = &h;
5968 status = dcerpc_samr_Connect4(p, tctx, &r4);
5969 if (!NT_STATUS_IS_OK(status)) {
5970 printf("Connect4 failed - %s\n", nt_errstr(status));
5974 test_samr_handle_Close(p, tctx, handle);
5980 torture_comment(tctx, "testing samr_Connect5\n");
5982 info.info1.client_version = 0;
5983 info.info1.unknown2 = 0;
5985 r5.in.system_name = "";
5986 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5988 r5.out.level_out = &level_out;
5989 r5.in.info_in = &info;
5990 r5.out.info_out = &info;
5991 r5.out.connect_handle = &h;
5993 status = dcerpc_samr_Connect5(p, tctx, &r5);
5994 if (!NT_STATUS_IS_OK(status)) {
5995 printf("Connect5 failed - %s\n", nt_errstr(status));
5999 test_samr_handle_Close(p, tctx, handle);
6009 bool torture_rpc_samr(struct torture_context *torture)
6012 struct dcerpc_pipe *p;
6014 struct policy_handle handle;
6016 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6017 if (!NT_STATUS_IS_OK(status)) {
6021 ret &= test_Connect(p, torture, &handle);
6023 if (!torture_setting_bool(torture, "samba3", false)) {
6024 ret &= test_QuerySecurity(p, torture, &handle);
6027 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_OTHER, NULL);
6029 ret &= test_SetDsrmPassword(p, torture, &handle);
6031 ret &= test_Shutdown(p, torture, &handle);
6033 ret &= test_samr_handle_Close(p, torture, &handle);
6039 bool torture_rpc_samr_users(struct torture_context *torture)
6042 struct dcerpc_pipe *p;
6044 struct policy_handle handle;
6046 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6047 if (!NT_STATUS_IS_OK(status)) {
6051 ret &= test_Connect(p, torture, &handle);
6053 if (!torture_setting_bool(torture, "samba3", false)) {
6054 ret &= test_QuerySecurity(p, torture, &handle);
6057 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_USER_ATTRIBUTES, NULL);
6059 ret &= test_SetDsrmPassword(p, torture, &handle);
6061 ret &= test_Shutdown(p, torture, &handle);
6063 ret &= test_samr_handle_Close(p, torture, &handle);
6069 bool torture_rpc_samr_passwords(struct torture_context *torture)
6072 struct dcerpc_pipe *p;
6074 struct policy_handle handle;
6076 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6077 if (!NT_STATUS_IS_OK(status)) {
6081 ret &= test_Connect(p, torture, &handle);
6083 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_PASSWORDS, NULL);
6085 ret &= test_samr_handle_Close(p, torture, &handle);
6090 static bool torture_rpc_samr_pwdlastset(struct torture_context *torture,
6091 struct dcerpc_pipe *p2,
6092 struct cli_credentials *machine_credentials)
6095 struct dcerpc_pipe *p;
6097 struct policy_handle handle;
6099 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6100 if (!NT_STATUS_IS_OK(status)) {
6104 ret &= test_Connect(p, torture, &handle);
6106 ret &= test_EnumDomains(p, torture, &handle,
6107 TORTURE_SAMR_PASSWORDS_PWDLASTSET,
6108 machine_credentials);
6110 ret &= test_samr_handle_Close(p, torture, &handle);
6115 struct torture_suite *torture_rpc_samr_passwords_pwdlastset(struct torture_context *tctx)
6117 struct torture_suite *suite = torture_suite_create(tctx, "SAMR-PASSWORDS-PWDLASTSET");
6118 struct torture_rpc_tcase *tcase;
6120 tcase = torture_suite_add_machine_rpc_iface_tcase(suite, "samr",
6122 TEST_ACCOUNT_NAME_PWD);
6124 torture_rpc_tcase_add_test_creds(tcase, "pwdLastSet",
6125 torture_rpc_samr_pwdlastset);