2 Unix SMB/CIFS implementation.
3 test suite for samr rpc operations
5 Copyright (C) Andrew Tridgell 2003
6 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003
7 Copyright (C) Guenther Deschner 2008,2009
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "torture/torture.h"
25 #include "system/time.h"
26 #include "librpc/gen_ndr/lsa.h"
27 #include "librpc/gen_ndr/ndr_netlogon.h"
28 #include "librpc/gen_ndr/ndr_netlogon_c.h"
29 #include "librpc/gen_ndr/ndr_samr_c.h"
30 #include "librpc/gen_ndr/ndr_lsa_c.h"
31 #include "../lib/crypto/crypto.h"
32 #include "libcli/auth/libcli_auth.h"
33 #include "libcli/security/security.h"
34 #include "torture/rpc/rpc.h"
35 #include "param/param.h"
39 #define TEST_ACCOUNT_NAME "samrtorturetest"
40 #define TEST_ACCOUNT_NAME_PWD "samrpwdlastset"
41 #define TEST_ALIASNAME "samrtorturetestalias"
42 #define TEST_GROUPNAME "samrtorturetestgroup"
43 #define TEST_MACHINENAME "samrtestmach$"
44 #define TEST_DOMAINNAME "samrtestdom$"
46 enum torture_samr_choice {
47 TORTURE_SAMR_PASSWORDS,
48 TORTURE_SAMR_PASSWORDS_PWDLASTSET,
49 TORTURE_SAMR_USER_ATTRIBUTES,
50 TORTURE_SAMR_USER_PRIVILEGES,
52 TORTURE_SAMR_MANY_ACCOUNTS,
53 TORTURE_SAMR_MANY_GROUPS,
54 TORTURE_SAMR_MANY_ALIASES
57 struct torture_samr_context {
58 struct policy_handle handle;
59 struct cli_credentials *machine_credentials;
60 enum torture_samr_choice choice;
61 uint32_t num_objects_large_dc;
64 static bool test_QueryUserInfo(struct dcerpc_pipe *p,
65 struct torture_context *tctx,
66 struct policy_handle *handle);
68 static bool test_QueryUserInfo2(struct dcerpc_pipe *p,
69 struct torture_context *tctx,
70 struct policy_handle *handle);
72 static bool test_QueryAliasInfo(struct dcerpc_pipe *p,
73 struct torture_context *tctx,
74 struct policy_handle *handle);
76 static bool test_ChangePassword(struct dcerpc_pipe *p,
77 struct torture_context *tctx,
78 const char *acct_name,
79 struct policy_handle *domain_handle, char **password);
81 static void init_lsa_String(struct lsa_String *string, const char *s)
86 static void init_lsa_StringLarge(struct lsa_StringLarge *string, const char *s)
91 static void init_lsa_BinaryString(struct lsa_BinaryString *string, const char *s, uint32_t length)
93 string->length = length;
94 string->size = length;
95 string->array = (uint16_t *)discard_const(s);
98 bool test_samr_handle_Close(struct dcerpc_pipe *p, struct torture_context *tctx,
99 struct policy_handle *handle)
104 r.in.handle = handle;
105 r.out.handle = handle;
107 status = dcerpc_samr_Close(p, tctx, &r);
108 torture_assert_ntstatus_ok(tctx, status, "Close");
113 static bool test_Shutdown(struct dcerpc_pipe *p, struct torture_context *tctx,
114 struct policy_handle *handle)
117 struct samr_Shutdown r;
119 if (!torture_setting_bool(tctx, "dangerous", false)) {
120 torture_skip(tctx, "samr_Shutdown disabled - enable dangerous tests to use\n");
124 r.in.connect_handle = handle;
126 torture_comment(tctx, "testing samr_Shutdown\n");
128 status = dcerpc_samr_Shutdown(p, tctx, &r);
129 torture_assert_ntstatus_ok(tctx, status, "samr_Shutdown");
134 static bool test_SetDsrmPassword(struct dcerpc_pipe *p, struct torture_context *tctx,
135 struct policy_handle *handle)
138 struct samr_SetDsrmPassword r;
139 struct lsa_String string;
140 struct samr_Password hash;
142 if (!torture_setting_bool(tctx, "dangerous", false)) {
143 torture_skip(tctx, "samr_SetDsrmPassword disabled - enable dangerous tests to use");
146 E_md4hash("TeSTDSRM123", hash.hash);
148 init_lsa_String(&string, "Administrator");
154 torture_comment(tctx, "testing samr_SetDsrmPassword\n");
156 status = dcerpc_samr_SetDsrmPassword(p, tctx, &r);
157 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_SUPPORTED, "samr_SetDsrmPassword");
163 static bool test_QuerySecurity(struct dcerpc_pipe *p,
164 struct torture_context *tctx,
165 struct policy_handle *handle)
168 struct samr_QuerySecurity r;
169 struct samr_SetSecurity s;
170 struct sec_desc_buf *sdbuf = NULL;
172 r.in.handle = handle;
174 r.out.sdbuf = &sdbuf;
176 status = dcerpc_samr_QuerySecurity(p, tctx, &r);
177 torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
179 torture_assert(tctx, sdbuf != NULL, "sdbuf is NULL");
181 s.in.handle = handle;
185 if (torture_setting_bool(tctx, "samba4", false)) {
186 torture_skip(tctx, "skipping SetSecurity test against Samba4\n");
189 status = dcerpc_samr_SetSecurity(p, tctx, &s);
190 torture_assert_ntstatus_ok(tctx, status, "SetSecurity");
192 status = dcerpc_samr_QuerySecurity(p, tctx, &r);
193 torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
199 static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
200 struct policy_handle *handle, uint32_t base_acct_flags,
201 const char *base_account_name)
204 struct samr_SetUserInfo s;
205 struct samr_SetUserInfo2 s2;
206 struct samr_QueryUserInfo q;
207 struct samr_QueryUserInfo q0;
208 union samr_UserInfo u;
209 union samr_UserInfo *info;
211 const char *test_account_name;
213 uint32_t user_extra_flags = 0;
215 if (!torture_setting_bool(tctx, "samba3", false)) {
216 if (base_acct_flags == ACB_NORMAL) {
217 /* When created, accounts are expired by default */
218 user_extra_flags = ACB_PW_EXPIRED;
222 s.in.user_handle = handle;
225 s2.in.user_handle = handle;
228 q.in.user_handle = handle;
232 #define TESTCALL(call, r) \
233 status = dcerpc_samr_ ##call(p, tctx, &r); \
234 if (!NT_STATUS_IS_OK(status)) { \
235 torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
236 r.in.level, nt_errstr(status), __location__); \
241 #define STRING_EQUAL(s1, s2, field) \
242 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
243 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
244 #field, s2, __location__); \
249 #define MEM_EQUAL(s1, s2, length, field) \
250 if ((s1 && !s2) || (s2 && !s1) || memcmp(s1, s2, length)) { \
251 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
252 #field, (const char *)s2, __location__); \
257 #define INT_EQUAL(i1, i2, field) \
259 torture_comment(tctx, "Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \
260 #field, (unsigned long long)i2, (unsigned long long)i1, __location__); \
265 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
266 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
268 TESTCALL(QueryUserInfo, q) \
270 s2.in.level = lvl1; \
273 ZERO_STRUCT(u.info21); \
274 u.info21.fields_present = fpval; \
276 init_lsa_String(&u.info ## lvl1.field1, value); \
277 TESTCALL(SetUserInfo, s) \
278 TESTCALL(SetUserInfo2, s2) \
279 init_lsa_String(&u.info ## lvl1.field1, ""); \
280 TESTCALL(QueryUserInfo, q); \
282 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
284 TESTCALL(QueryUserInfo, q) \
286 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
289 #define TEST_USERINFO_BINARYSTRING(lvl1, field1, lvl2, field2, value, fpval) do { \
290 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
292 TESTCALL(QueryUserInfo, q) \
294 s2.in.level = lvl1; \
297 ZERO_STRUCT(u.info21); \
298 u.info21.fields_present = fpval; \
300 init_lsa_BinaryString(&u.info ## lvl1.field1, value, strlen(value)); \
301 TESTCALL(SetUserInfo, s) \
302 TESTCALL(SetUserInfo2, s2) \
303 init_lsa_BinaryString(&u.info ## lvl1.field1, "", 1); \
304 TESTCALL(QueryUserInfo, q); \
306 MEM_EQUAL(u.info ## lvl1.field1.array, value, strlen(value), field1); \
308 TESTCALL(QueryUserInfo, q) \
310 MEM_EQUAL(u.info ## lvl2.field2.array, value, strlen(value), field2); \
313 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
314 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
316 TESTCALL(QueryUserInfo, q) \
318 s2.in.level = lvl1; \
321 uint8_t *bits = u.info21.logon_hours.bits; \
322 ZERO_STRUCT(u.info21); \
323 if (fpval == SAMR_FIELD_LOGON_HOURS) { \
324 u.info21.logon_hours.units_per_week = 168; \
325 u.info21.logon_hours.bits = bits; \
327 u.info21.fields_present = fpval; \
329 u.info ## lvl1.field1 = value; \
330 TESTCALL(SetUserInfo, s) \
331 TESTCALL(SetUserInfo2, s2) \
332 u.info ## lvl1.field1 = 0; \
333 TESTCALL(QueryUserInfo, q); \
335 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
337 TESTCALL(QueryUserInfo, q) \
339 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
342 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
343 TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
347 do { TESTCALL(QueryUserInfo, q0) } while (0);
349 TEST_USERINFO_STRING(2, comment, 1, comment, "xx2-1 comment", 0);
350 TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
351 TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment",
354 test_account_name = talloc_asprintf(tctx, "%sxx7-1", base_account_name);
355 TEST_USERINFO_STRING(7, account_name, 1, account_name, base_account_name, 0);
356 test_account_name = talloc_asprintf(tctx, "%sxx7-3", base_account_name);
357 TEST_USERINFO_STRING(7, account_name, 3, account_name, base_account_name, 0);
358 test_account_name = talloc_asprintf(tctx, "%sxx7-5", base_account_name);
359 TEST_USERINFO_STRING(7, account_name, 5, account_name, base_account_name, 0);
360 test_account_name = talloc_asprintf(tctx, "%sxx7-6", base_account_name);
361 TEST_USERINFO_STRING(7, account_name, 6, account_name, base_account_name, 0);
362 test_account_name = talloc_asprintf(tctx, "%sxx7-7", base_account_name);
363 TEST_USERINFO_STRING(7, account_name, 7, account_name, base_account_name, 0);
364 test_account_name = talloc_asprintf(tctx, "%sxx7-21", base_account_name);
365 TEST_USERINFO_STRING(7, account_name, 21, account_name, base_account_name, 0);
366 test_account_name = base_account_name;
367 TEST_USERINFO_STRING(21, account_name, 21, account_name, base_account_name,
368 SAMR_FIELD_ACCOUNT_NAME);
370 TEST_USERINFO_STRING(6, full_name, 1, full_name, "xx6-1 full_name", 0);
371 TEST_USERINFO_STRING(6, full_name, 3, full_name, "xx6-3 full_name", 0);
372 TEST_USERINFO_STRING(6, full_name, 5, full_name, "xx6-5 full_name", 0);
373 TEST_USERINFO_STRING(6, full_name, 6, full_name, "xx6-6 full_name", 0);
374 TEST_USERINFO_STRING(6, full_name, 8, full_name, "xx6-8 full_name", 0);
375 TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
376 TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
377 TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name",
378 SAMR_FIELD_FULL_NAME);
380 TEST_USERINFO_STRING(6, full_name, 1, full_name, "", 0);
381 TEST_USERINFO_STRING(6, full_name, 3, full_name, "", 0);
382 TEST_USERINFO_STRING(6, full_name, 5, full_name, "", 0);
383 TEST_USERINFO_STRING(6, full_name, 6, full_name, "", 0);
384 TEST_USERINFO_STRING(6, full_name, 8, full_name, "", 0);
385 TEST_USERINFO_STRING(6, full_name, 21, full_name, "", 0);
386 TEST_USERINFO_STRING(8, full_name, 21, full_name, "", 0);
387 TEST_USERINFO_STRING(21, full_name, 21, full_name, "",
388 SAMR_FIELD_FULL_NAME);
390 TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
391 TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
392 TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
393 TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script",
394 SAMR_FIELD_LOGON_SCRIPT);
396 TEST_USERINFO_STRING(12, profile_path, 3, profile_path, "xx12-3 profile_path", 0);
397 TEST_USERINFO_STRING(12, profile_path, 5, profile_path, "xx12-5 profile_path", 0);
398 TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
399 TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path",
400 SAMR_FIELD_PROFILE_PATH);
402 TEST_USERINFO_STRING(10, home_directory, 3, home_directory, "xx10-3 home_directory", 0);
403 TEST_USERINFO_STRING(10, home_directory, 5, home_directory, "xx10-5 home_directory", 0);
404 TEST_USERINFO_STRING(10, home_directory, 21, home_directory, "xx10-21 home_directory", 0);
405 TEST_USERINFO_STRING(21, home_directory, 21, home_directory, "xx21-21 home_directory",
406 SAMR_FIELD_HOME_DIRECTORY);
407 TEST_USERINFO_STRING(21, home_directory, 10, home_directory, "xx21-10 home_directory",
408 SAMR_FIELD_HOME_DIRECTORY);
410 TEST_USERINFO_STRING(10, home_drive, 3, home_drive, "xx10-3 home_drive", 0);
411 TEST_USERINFO_STRING(10, home_drive, 5, home_drive, "xx10-5 home_drive", 0);
412 TEST_USERINFO_STRING(10, home_drive, 21, home_drive, "xx10-21 home_drive", 0);
413 TEST_USERINFO_STRING(21, home_drive, 21, home_drive, "xx21-21 home_drive",
414 SAMR_FIELD_HOME_DRIVE);
415 TEST_USERINFO_STRING(21, home_drive, 10, home_drive, "xx21-10 home_drive",
416 SAMR_FIELD_HOME_DRIVE);
418 TEST_USERINFO_STRING(13, description, 1, description, "xx13-1 description", 0);
419 TEST_USERINFO_STRING(13, description, 5, description, "xx13-5 description", 0);
420 TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
421 TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description",
422 SAMR_FIELD_DESCRIPTION);
424 TEST_USERINFO_STRING(14, workstations, 3, workstations, "14workstation3", 0);
425 TEST_USERINFO_STRING(14, workstations, 5, workstations, "14workstation4", 0);
426 TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
427 TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21",
428 SAMR_FIELD_WORKSTATIONS);
429 TEST_USERINFO_STRING(21, workstations, 3, workstations, "21workstation3",
430 SAMR_FIELD_WORKSTATIONS);
431 TEST_USERINFO_STRING(21, workstations, 5, workstations, "21workstation5",
432 SAMR_FIELD_WORKSTATIONS);
433 TEST_USERINFO_STRING(21, workstations, 14, workstations, "21workstation14",
434 SAMR_FIELD_WORKSTATIONS);
436 TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
437 TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "xx21-21 parameters",
438 SAMR_FIELD_PARAMETERS);
439 TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "xx21-20 parameters",
440 SAMR_FIELD_PARAMETERS);
441 /* also empty user parameters are allowed */
442 TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "", 0);
443 TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "",
444 SAMR_FIELD_PARAMETERS);
445 TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "",
446 SAMR_FIELD_PARAMETERS);
448 /* Samba 3 cannot store country_code and copy_page atm. - gd */
449 if (!torture_setting_bool(tctx, "samba3", false)) {
450 TEST_USERINFO_INT(2, country_code, 2, country_code, __LINE__, 0);
451 TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
452 TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__,
453 SAMR_FIELD_COUNTRY_CODE);
454 TEST_USERINFO_INT(21, country_code, 2, country_code, __LINE__,
455 SAMR_FIELD_COUNTRY_CODE);
457 TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
458 TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__,
459 SAMR_FIELD_CODE_PAGE);
460 TEST_USERINFO_INT(21, code_page, 2, code_page, __LINE__,
461 SAMR_FIELD_CODE_PAGE);
464 if (!torture_setting_bool(tctx, "samba3", false)) {
465 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, __LINE__, 0);
466 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, __LINE__, 0);
467 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, __LINE__,
468 SAMR_FIELD_ACCT_EXPIRY);
469 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, __LINE__,
470 SAMR_FIELD_ACCT_EXPIRY);
471 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, __LINE__,
472 SAMR_FIELD_ACCT_EXPIRY);
474 /* Samba 3 can only store seconds / time_t in passdb - gd */
476 unix_to_nt_time(&nt, time(NULL) + __LINE__);
477 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, nt, 0);
478 unix_to_nt_time(&nt, time(NULL) + __LINE__);
479 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, nt, 0);
480 unix_to_nt_time(&nt, time(NULL) + __LINE__);
481 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
482 unix_to_nt_time(&nt, time(NULL) + __LINE__);
483 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
484 unix_to_nt_time(&nt, time(NULL) + __LINE__);
485 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
488 TEST_USERINFO_INT(4, logon_hours.bits[3], 3, logon_hours.bits[3], 1, 0);
489 TEST_USERINFO_INT(4, logon_hours.bits[3], 5, logon_hours.bits[3], 2, 0);
490 TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
491 TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4,
492 SAMR_FIELD_LOGON_HOURS);
494 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
495 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
496 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
498 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
499 (base_acct_flags | ACB_DISABLED),
500 (base_acct_flags | ACB_DISABLED | user_extra_flags),
503 /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
504 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
505 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
506 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
508 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
509 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
510 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
514 /* The 'autolock' flag doesn't stick - check this */
515 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
516 (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK),
517 (base_acct_flags | ACB_DISABLED | user_extra_flags),
520 /* Removing the 'disabled' flag doesn't stick - check this */
521 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
523 (base_acct_flags | ACB_DISABLED | user_extra_flags),
527 /* Samba3 cannot store these atm */
528 if (!torture_setting_bool(tctx, "samba3", false)) {
529 /* The 'store plaintext' flag does stick */
530 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
531 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED),
532 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags),
534 /* The 'use DES' flag does stick */
535 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
536 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY),
537 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags),
539 /* The 'don't require kerberos pre-authentication flag does stick */
540 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
541 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH),
542 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags),
544 /* The 'no kerberos PAC required' flag sticks */
545 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
546 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD),
547 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags),
550 TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags,
551 (base_acct_flags | ACB_DISABLED),
552 (base_acct_flags | ACB_DISABLED | user_extra_flags),
553 SAMR_FIELD_ACCT_FLAGS);
556 /* these fail with win2003 - it appears you can't set the primary gid?
557 the set succeeds, but the gid isn't changed. Very weird! */
558 TEST_USERINFO_INT(9, primary_gid, 1, primary_gid, 513);
559 TEST_USERINFO_INT(9, primary_gid, 3, primary_gid, 513);
560 TEST_USERINFO_INT(9, primary_gid, 5, primary_gid, 513);
561 TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
568 generate a random password for password change tests
570 static char *samr_rand_pass_silent(TALLOC_CTX *mem_ctx, int min_len)
572 size_t len = MAX(8, min_len) + (random() % 6);
573 char *s = generate_random_str(mem_ctx, len);
577 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
579 char *s = samr_rand_pass_silent(mem_ctx, min_len);
580 printf("Generated password '%s'\n", s);
586 generate a random password for password change tests
588 static DATA_BLOB samr_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
591 DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
592 generate_random_buffer(password.data, password.length);
594 for (i=0; i < len; i++) {
595 if (((uint16_t *)password.data)[i] == 0) {
596 ((uint16_t *)password.data)[i] = 1;
604 generate a random password for password change tests (fixed length)
606 static char *samr_rand_pass_fixed_len(TALLOC_CTX *mem_ctx, int len)
608 char *s = generate_random_str(mem_ctx, len);
609 printf("Generated password '%s'\n", s);
613 static bool test_SetUserPass(struct dcerpc_pipe *p, struct torture_context *tctx,
614 struct policy_handle *handle, char **password)
617 struct samr_SetUserInfo s;
618 union samr_UserInfo u;
620 DATA_BLOB session_key;
622 struct samr_GetUserPwInfo pwp;
623 struct samr_PwInfo info;
624 int policy_min_pw_len = 0;
625 pwp.in.user_handle = handle;
626 pwp.out.info = &info;
628 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
629 if (NT_STATUS_IS_OK(status)) {
630 policy_min_pw_len = pwp.out.info->min_password_length;
632 newpass = samr_rand_pass(tctx, policy_min_pw_len);
634 s.in.user_handle = handle;
638 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
639 u.info24.password_expired = 0;
641 status = dcerpc_fetch_session_key(p, &session_key);
642 if (!NT_STATUS_IS_OK(status)) {
643 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
644 s.in.level, nt_errstr(status));
648 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
650 torture_comment(tctx, "Testing SetUserInfo level 24 (set password)\n");
652 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
653 if (!NT_STATUS_IS_OK(status)) {
654 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
655 s.in.level, nt_errstr(status));
665 static bool test_SetUserPass_23(struct dcerpc_pipe *p, struct torture_context *tctx,
666 struct policy_handle *handle, uint32_t fields_present,
670 struct samr_SetUserInfo s;
671 union samr_UserInfo u;
673 DATA_BLOB session_key;
675 struct samr_GetUserPwInfo pwp;
676 struct samr_PwInfo info;
677 int policy_min_pw_len = 0;
678 pwp.in.user_handle = handle;
679 pwp.out.info = &info;
681 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
682 if (NT_STATUS_IS_OK(status)) {
683 policy_min_pw_len = pwp.out.info->min_password_length;
685 newpass = samr_rand_pass(tctx, policy_min_pw_len);
687 s.in.user_handle = handle;
693 u.info23.info.fields_present = fields_present;
695 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
697 status = dcerpc_fetch_session_key(p, &session_key);
698 if (!NT_STATUS_IS_OK(status)) {
699 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
700 s.in.level, nt_errstr(status));
704 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
706 torture_comment(tctx, "Testing SetUserInfo level 23 (set password)\n");
708 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
709 if (!NT_STATUS_IS_OK(status)) {
710 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
711 s.in.level, nt_errstr(status));
717 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
719 status = dcerpc_fetch_session_key(p, &session_key);
720 if (!NT_STATUS_IS_OK(status)) {
721 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
722 s.in.level, nt_errstr(status));
726 /* This should break the key nicely */
727 session_key.length--;
728 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
730 torture_comment(tctx, "Testing SetUserInfo level 23 (set password) with wrong password\n");
732 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
733 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
734 torture_warning(tctx, "SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
735 s.in.level, nt_errstr(status));
743 static bool test_SetUserPassEx(struct dcerpc_pipe *p, struct torture_context *tctx,
744 struct policy_handle *handle, bool makeshort,
748 struct samr_SetUserInfo s;
749 union samr_UserInfo u;
751 DATA_BLOB session_key;
752 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
753 uint8_t confounder[16];
755 struct MD5Context ctx;
756 struct samr_GetUserPwInfo pwp;
757 struct samr_PwInfo info;
758 int policy_min_pw_len = 0;
759 pwp.in.user_handle = handle;
760 pwp.out.info = &info;
762 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
763 if (NT_STATUS_IS_OK(status)) {
764 policy_min_pw_len = pwp.out.info->min_password_length;
766 if (makeshort && policy_min_pw_len) {
767 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len - 1);
769 newpass = samr_rand_pass(tctx, policy_min_pw_len);
772 s.in.user_handle = handle;
776 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
777 u.info26.password_expired = 0;
779 status = dcerpc_fetch_session_key(p, &session_key);
780 if (!NT_STATUS_IS_OK(status)) {
781 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
782 s.in.level, nt_errstr(status));
786 generate_random_buffer((uint8_t *)confounder, 16);
789 MD5Update(&ctx, confounder, 16);
790 MD5Update(&ctx, session_key.data, session_key.length);
791 MD5Final(confounded_session_key.data, &ctx);
793 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
794 memcpy(&u.info26.password.data[516], confounder, 16);
796 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex)\n");
798 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
799 if (!NT_STATUS_IS_OK(status)) {
800 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
801 s.in.level, nt_errstr(status));
807 /* This should break the key nicely */
808 confounded_session_key.data[0]++;
810 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
811 memcpy(&u.info26.password.data[516], confounder, 16);
813 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
815 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
816 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
817 torture_warning(tctx, "SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
818 s.in.level, nt_errstr(status));
827 static bool test_SetUserPass_25(struct dcerpc_pipe *p, struct torture_context *tctx,
828 struct policy_handle *handle, uint32_t fields_present,
832 struct samr_SetUserInfo s;
833 union samr_UserInfo u;
835 DATA_BLOB session_key;
836 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
837 struct MD5Context ctx;
838 uint8_t confounder[16];
840 struct samr_GetUserPwInfo pwp;
841 struct samr_PwInfo info;
842 int policy_min_pw_len = 0;
843 pwp.in.user_handle = handle;
844 pwp.out.info = &info;
846 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
847 if (NT_STATUS_IS_OK(status)) {
848 policy_min_pw_len = pwp.out.info->min_password_length;
850 newpass = samr_rand_pass(tctx, policy_min_pw_len);
852 s.in.user_handle = handle;
858 u.info25.info.fields_present = fields_present;
860 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
862 status = dcerpc_fetch_session_key(p, &session_key);
863 if (!NT_STATUS_IS_OK(status)) {
864 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
865 s.in.level, nt_errstr(status));
869 generate_random_buffer((uint8_t *)confounder, 16);
872 MD5Update(&ctx, confounder, 16);
873 MD5Update(&ctx, session_key.data, session_key.length);
874 MD5Final(confounded_session_key.data, &ctx);
876 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
877 memcpy(&u.info25.password.data[516], confounder, 16);
879 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex)\n");
881 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
882 if (!NT_STATUS_IS_OK(status)) {
883 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
884 s.in.level, nt_errstr(status));
890 /* This should break the key nicely */
891 confounded_session_key.data[0]++;
893 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
894 memcpy(&u.info25.password.data[516], confounder, 16);
896 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
898 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
899 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
900 torture_warning(tctx, "SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
901 s.in.level, nt_errstr(status));
908 static bool test_SetUserPass_18(struct dcerpc_pipe *p, struct torture_context *tctx,
909 struct policy_handle *handle, char **password)
912 struct samr_SetUserInfo s;
913 union samr_UserInfo u;
915 DATA_BLOB session_key;
917 struct samr_GetUserPwInfo pwp;
918 struct samr_PwInfo info;
919 int policy_min_pw_len = 0;
920 uint8_t lm_hash[16], nt_hash[16];
922 pwp.in.user_handle = handle;
923 pwp.out.info = &info;
925 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
926 if (NT_STATUS_IS_OK(status)) {
927 policy_min_pw_len = pwp.out.info->min_password_length;
929 newpass = samr_rand_pass(tctx, policy_min_pw_len);
931 s.in.user_handle = handle;
937 u.info18.nt_pwd_active = true;
938 u.info18.lm_pwd_active = true;
940 E_md4hash(newpass, nt_hash);
941 E_deshash(newpass, lm_hash);
943 status = dcerpc_fetch_session_key(p, &session_key);
944 if (!NT_STATUS_IS_OK(status)) {
945 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
946 s.in.level, nt_errstr(status));
952 in = data_blob_const(nt_hash, 16);
953 out = data_blob_talloc_zero(tctx, 16);
954 sess_crypt_blob(&out, &in, &session_key, true);
955 memcpy(u.info18.nt_pwd.hash, out.data, out.length);
959 in = data_blob_const(lm_hash, 16);
960 out = data_blob_talloc_zero(tctx, 16);
961 sess_crypt_blob(&out, &in, &session_key, true);
962 memcpy(u.info18.lm_pwd.hash, out.data, out.length);
965 torture_comment(tctx, "Testing SetUserInfo level 18 (set password hash)\n");
967 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
968 if (!NT_STATUS_IS_OK(status)) {
969 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
970 s.in.level, nt_errstr(status));
979 static bool test_SetUserPass_21(struct dcerpc_pipe *p, struct torture_context *tctx,
980 struct policy_handle *handle, uint32_t fields_present,
984 struct samr_SetUserInfo s;
985 union samr_UserInfo u;
987 DATA_BLOB session_key;
989 struct samr_GetUserPwInfo pwp;
990 struct samr_PwInfo info;
991 int policy_min_pw_len = 0;
992 uint8_t lm_hash[16], nt_hash[16];
994 pwp.in.user_handle = handle;
995 pwp.out.info = &info;
997 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
998 if (NT_STATUS_IS_OK(status)) {
999 policy_min_pw_len = pwp.out.info->min_password_length;
1001 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1003 s.in.user_handle = handle;
1007 E_md4hash(newpass, nt_hash);
1008 E_deshash(newpass, lm_hash);
1012 u.info21.fields_present = fields_present;
1014 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1015 u.info21.lm_owf_password.length = 16;
1016 u.info21.lm_owf_password.size = 16;
1017 u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
1018 u.info21.lm_password_set = true;
1021 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1022 u.info21.nt_owf_password.length = 16;
1023 u.info21.nt_owf_password.size = 16;
1024 u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
1025 u.info21.nt_password_set = true;
1028 status = dcerpc_fetch_session_key(p, &session_key);
1029 if (!NT_STATUS_IS_OK(status)) {
1030 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
1031 s.in.level, nt_errstr(status));
1035 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1037 in = data_blob_const(u.info21.lm_owf_password.array,
1038 u.info21.lm_owf_password.length);
1039 out = data_blob_talloc_zero(tctx, 16);
1040 sess_crypt_blob(&out, &in, &session_key, true);
1041 u.info21.lm_owf_password.array = (uint16_t *)out.data;
1044 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1046 in = data_blob_const(u.info21.nt_owf_password.array,
1047 u.info21.nt_owf_password.length);
1048 out = data_blob_talloc_zero(tctx, 16);
1049 sess_crypt_blob(&out, &in, &session_key, true);
1050 u.info21.nt_owf_password.array = (uint16_t *)out.data;
1053 torture_comment(tctx, "Testing SetUserInfo level 21 (set password hash)\n");
1055 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1056 if (!NT_STATUS_IS_OK(status)) {
1057 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
1058 s.in.level, nt_errstr(status));
1061 *password = newpass;
1064 /* try invalid length */
1065 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1067 u.info21.nt_owf_password.length++;
1069 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1071 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1072 torture_warning(tctx, "SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1073 s.in.level, nt_errstr(status));
1078 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1080 u.info21.lm_owf_password.length++;
1082 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1084 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1085 torture_warning(tctx, "SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1086 s.in.level, nt_errstr(status));
1094 static bool test_SetUserPass_level_ex(struct dcerpc_pipe *p,
1095 struct torture_context *tctx,
1096 struct policy_handle *handle,
1098 uint32_t fields_present,
1099 char **password, uint8_t password_expired,
1101 bool *matched_expected_error)
1104 NTSTATUS expected_error = NT_STATUS_OK;
1105 struct samr_SetUserInfo s;
1106 struct samr_SetUserInfo2 s2;
1107 union samr_UserInfo u;
1109 DATA_BLOB session_key;
1110 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
1111 struct MD5Context ctx;
1112 uint8_t confounder[16];
1114 struct samr_GetUserPwInfo pwp;
1115 struct samr_PwInfo info;
1116 int policy_min_pw_len = 0;
1117 const char *comment = NULL;
1118 uint8_t lm_hash[16], nt_hash[16];
1120 pwp.in.user_handle = handle;
1121 pwp.out.info = &info;
1123 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1124 if (NT_STATUS_IS_OK(status)) {
1125 policy_min_pw_len = pwp.out.info->min_password_length;
1127 newpass = samr_rand_pass_silent(tctx, policy_min_pw_len);
1130 s2.in.user_handle = handle;
1132 s2.in.level = level;
1134 s.in.user_handle = handle;
1139 if (fields_present & SAMR_FIELD_COMMENT) {
1140 comment = talloc_asprintf(tctx, "comment: %ld\n", time(NULL));
1147 E_md4hash(newpass, nt_hash);
1148 E_deshash(newpass, lm_hash);
1150 u.info18.nt_pwd_active = true;
1151 u.info18.lm_pwd_active = true;
1152 u.info18.password_expired = password_expired;
1154 memcpy(u.info18.lm_pwd.hash, lm_hash, 16);
1155 memcpy(u.info18.nt_pwd.hash, nt_hash, 16);
1159 E_md4hash(newpass, nt_hash);
1160 E_deshash(newpass, lm_hash);
1162 u.info21.fields_present = fields_present;
1163 u.info21.password_expired = password_expired;
1164 u.info21.comment.string = comment;
1166 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1167 u.info21.lm_owf_password.length = 16;
1168 u.info21.lm_owf_password.size = 16;
1169 u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
1170 u.info21.lm_password_set = true;
1173 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1174 u.info21.nt_owf_password.length = 16;
1175 u.info21.nt_owf_password.size = 16;
1176 u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
1177 u.info21.nt_password_set = true;
1182 u.info23.info.fields_present = fields_present;
1183 u.info23.info.password_expired = password_expired;
1184 u.info23.info.comment.string = comment;
1186 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
1190 u.info24.password_expired = password_expired;
1192 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
1196 u.info25.info.fields_present = fields_present;
1197 u.info25.info.password_expired = password_expired;
1198 u.info25.info.comment.string = comment;
1200 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
1204 u.info26.password_expired = password_expired;
1206 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
1211 status = dcerpc_fetch_session_key(p, &session_key);
1212 if (!NT_STATUS_IS_OK(status)) {
1213 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
1214 s.in.level, nt_errstr(status));
1218 generate_random_buffer((uint8_t *)confounder, 16);
1221 MD5Update(&ctx, confounder, 16);
1222 MD5Update(&ctx, session_key.data, session_key.length);
1223 MD5Final(confounded_session_key.data, &ctx);
1229 in = data_blob_const(u.info18.nt_pwd.hash, 16);
1230 out = data_blob_talloc_zero(tctx, 16);
1231 sess_crypt_blob(&out, &in, &session_key, true);
1232 memcpy(u.info18.nt_pwd.hash, out.data, out.length);
1236 in = data_blob_const(u.info18.lm_pwd.hash, 16);
1237 out = data_blob_talloc_zero(tctx, 16);
1238 sess_crypt_blob(&out, &in, &session_key, true);
1239 memcpy(u.info18.lm_pwd.hash, out.data, out.length);
1244 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1246 in = data_blob_const(u.info21.lm_owf_password.array,
1247 u.info21.lm_owf_password.length);
1248 out = data_blob_talloc_zero(tctx, 16);
1249 sess_crypt_blob(&out, &in, &session_key, true);
1250 u.info21.lm_owf_password.array = (uint16_t *)out.data;
1252 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1254 in = data_blob_const(u.info21.nt_owf_password.array,
1255 u.info21.nt_owf_password.length);
1256 out = data_blob_talloc_zero(tctx, 16);
1257 sess_crypt_blob(&out, &in, &session_key, true);
1258 u.info21.nt_owf_password.array = (uint16_t *)out.data;
1262 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
1265 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
1268 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
1269 memcpy(&u.info25.password.data[516], confounder, 16);
1272 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
1273 memcpy(&u.info26.password.data[516], confounder, 16);
1278 status = dcerpc_samr_SetUserInfo2(p, tctx, &s2);
1280 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1283 if (!NT_STATUS_IS_OK(status)) {
1284 if (fields_present == 0) {
1285 expected_error = NT_STATUS_INVALID_PARAMETER;
1287 if (fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
1288 expected_error = NT_STATUS_ACCESS_DENIED;
1292 if (!NT_STATUS_IS_OK(expected_error)) {
1294 torture_assert_ntstatus_equal(tctx,
1296 expected_error, "SetUserInfo2 failed");
1298 torture_assert_ntstatus_equal(tctx,
1300 expected_error, "SetUserInfo failed");
1302 *matched_expected_error = true;
1306 if (!NT_STATUS_IS_OK(status)) {
1307 torture_warning(tctx, "SetUserInfo%s level %u failed - %s\n",
1308 use_setinfo2 ? "2":"", level, nt_errstr(status));
1311 *password = newpass;
1317 static bool test_SetAliasInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1318 struct policy_handle *handle)
1321 struct samr_SetAliasInfo r;
1322 struct samr_QueryAliasInfo q;
1323 union samr_AliasInfo *info;
1324 uint16_t levels[] = {2, 3};
1328 /* Ignoring switch level 1, as that includes the number of members for the alias
1329 * and setting this to a wrong value might have negative consequences
1332 for (i=0;i<ARRAY_SIZE(levels);i++) {
1333 torture_comment(tctx, "Testing SetAliasInfo level %u\n", levels[i]);
1335 r.in.alias_handle = handle;
1336 r.in.level = levels[i];
1337 r.in.info = talloc(tctx, union samr_AliasInfo);
1338 switch (r.in.level) {
1339 case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
1340 case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
1341 "Test Description, should test I18N as well"); break;
1342 case ALIASINFOALL: torture_comment(tctx, "ALIASINFOALL ignored\n"); break;
1345 status = dcerpc_samr_SetAliasInfo(p, tctx, &r);
1346 if (!NT_STATUS_IS_OK(status)) {
1347 torture_warning(tctx, "SetAliasInfo level %u failed - %s\n",
1348 levels[i], nt_errstr(status));
1352 q.in.alias_handle = handle;
1353 q.in.level = levels[i];
1356 status = dcerpc_samr_QueryAliasInfo(p, tctx, &q);
1357 if (!NT_STATUS_IS_OK(status)) {
1358 torture_warning(tctx, "QueryAliasInfo level %u failed - %s\n",
1359 levels[i], nt_errstr(status));
1367 static bool test_GetGroupsForUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1368 struct policy_handle *user_handle)
1370 struct samr_GetGroupsForUser r;
1371 struct samr_RidWithAttributeArray *rids = NULL;
1374 torture_comment(tctx, "testing GetGroupsForUser\n");
1376 r.in.user_handle = user_handle;
1379 status = dcerpc_samr_GetGroupsForUser(p, tctx, &r);
1380 torture_assert_ntstatus_ok(tctx, status, "GetGroupsForUser");
1386 static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1387 struct lsa_String *domain_name)
1390 struct samr_GetDomPwInfo r;
1391 struct samr_PwInfo info;
1393 r.in.domain_name = domain_name;
1396 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1398 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1399 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1401 r.in.domain_name->string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1402 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1404 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1405 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1407 r.in.domain_name->string = "\\\\__NONAME__";
1408 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1410 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1411 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1413 r.in.domain_name->string = "\\\\Builtin";
1414 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1416 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1417 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1422 static bool test_GetUserPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1423 struct policy_handle *handle)
1426 struct samr_GetUserPwInfo r;
1427 struct samr_PwInfo info;
1429 torture_comment(tctx, "Testing GetUserPwInfo\n");
1431 r.in.user_handle = handle;
1434 status = dcerpc_samr_GetUserPwInfo(p, tctx, &r);
1435 torture_assert_ntstatus_ok(tctx, status, "GetUserPwInfo");
1440 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, struct torture_context *tctx,
1441 struct policy_handle *domain_handle, const char *name,
1445 struct samr_LookupNames n;
1446 struct lsa_String sname[2];
1447 struct samr_Ids rids, types;
1449 init_lsa_String(&sname[0], name);
1451 n.in.domain_handle = domain_handle;
1455 n.out.types = &types;
1456 status = dcerpc_samr_LookupNames(p, tctx, &n);
1457 if (NT_STATUS_IS_OK(status)) {
1458 *rid = n.out.rids->ids[0];
1463 init_lsa_String(&sname[1], "xxNONAMExx");
1465 status = dcerpc_samr_LookupNames(p, tctx, &n);
1466 if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
1467 torture_warning(tctx, "LookupNames[2] failed - %s\n", nt_errstr(status));
1468 if (NT_STATUS_IS_OK(status)) {
1469 return NT_STATUS_UNSUCCESSFUL;
1475 status = dcerpc_samr_LookupNames(p, tctx, &n);
1476 if (!NT_STATUS_IS_OK(status)) {
1477 torture_warning(tctx, "LookupNames[0] failed - %s\n", nt_errstr(status));
1481 init_lsa_String(&sname[0], "xxNONAMExx");
1483 status = dcerpc_samr_LookupNames(p, tctx, &n);
1484 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1485 torture_warning(tctx, "LookupNames[1 bad name] failed - %s\n", nt_errstr(status));
1486 if (NT_STATUS_IS_OK(status)) {
1487 return NT_STATUS_UNSUCCESSFUL;
1492 init_lsa_String(&sname[0], "xxNONAMExx");
1493 init_lsa_String(&sname[1], "xxNONAME2xx");
1495 status = dcerpc_samr_LookupNames(p, tctx, &n);
1496 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1497 torture_warning(tctx, "LookupNames[2 bad names] failed - %s\n", nt_errstr(status));
1498 if (NT_STATUS_IS_OK(status)) {
1499 return NT_STATUS_UNSUCCESSFUL;
1504 return NT_STATUS_OK;
1507 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p,
1508 struct torture_context *tctx,
1509 struct policy_handle *domain_handle,
1510 const char *name, struct policy_handle *user_handle)
1513 struct samr_OpenUser r;
1516 status = test_LookupName(p, tctx, domain_handle, name, &rid);
1517 if (!NT_STATUS_IS_OK(status)) {
1521 r.in.domain_handle = domain_handle;
1522 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1524 r.out.user_handle = user_handle;
1525 status = dcerpc_samr_OpenUser(p, tctx, &r);
1526 if (!NT_STATUS_IS_OK(status)) {
1527 torture_warning(tctx, "OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(status));
1534 static bool test_ChangePasswordNT3(struct dcerpc_pipe *p,
1535 struct torture_context *tctx,
1536 struct policy_handle *handle)
1539 struct samr_ChangePasswordUser r;
1541 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1542 struct policy_handle user_handle;
1543 char *oldpass = "test";
1544 char *newpass = "test2";
1545 uint8_t old_nt_hash[16], new_nt_hash[16];
1546 uint8_t old_lm_hash[16], new_lm_hash[16];
1548 status = test_OpenUser_byname(p, tctx, handle, "testuser", &user_handle);
1549 if (!NT_STATUS_IS_OK(status)) {
1553 torture_comment(tctx, "Testing ChangePasswordUser for user 'testuser'\n");
1555 torture_comment(tctx, "old password: %s\n", oldpass);
1556 torture_comment(tctx, "new password: %s\n", newpass);
1558 E_md4hash(oldpass, old_nt_hash);
1559 E_md4hash(newpass, new_nt_hash);
1560 E_deshash(oldpass, old_lm_hash);
1561 E_deshash(newpass, new_lm_hash);
1563 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1564 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1565 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1566 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1567 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1568 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1570 r.in.handle = &user_handle;
1571 r.in.lm_present = 1;
1572 r.in.old_lm_crypted = &hash1;
1573 r.in.new_lm_crypted = &hash2;
1574 r.in.nt_present = 1;
1575 r.in.old_nt_crypted = &hash3;
1576 r.in.new_nt_crypted = &hash4;
1577 r.in.cross1_present = 1;
1578 r.in.nt_cross = &hash5;
1579 r.in.cross2_present = 1;
1580 r.in.lm_cross = &hash6;
1582 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1583 if (!NT_STATUS_IS_OK(status)) {
1584 torture_warning(tctx, "ChangePasswordUser failed - %s\n", nt_errstr(status));
1588 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
1596 static bool test_ChangePasswordUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1597 const char *acct_name,
1598 struct policy_handle *handle, char **password)
1601 struct samr_ChangePasswordUser r;
1603 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1604 struct policy_handle user_handle;
1606 uint8_t old_nt_hash[16], new_nt_hash[16];
1607 uint8_t old_lm_hash[16], new_lm_hash[16];
1608 bool changed = true;
1611 struct samr_GetUserPwInfo pwp;
1612 struct samr_PwInfo info;
1613 int policy_min_pw_len = 0;
1615 status = test_OpenUser_byname(p, tctx, handle, acct_name, &user_handle);
1616 if (!NT_STATUS_IS_OK(status)) {
1619 pwp.in.user_handle = &user_handle;
1620 pwp.out.info = &info;
1622 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1623 if (NT_STATUS_IS_OK(status)) {
1624 policy_min_pw_len = pwp.out.info->min_password_length;
1626 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1628 torture_comment(tctx, "Testing ChangePasswordUser\n");
1630 torture_assert(tctx, *password != NULL,
1631 "Failing ChangePasswordUser as old password was NULL. Previous test failed?");
1633 oldpass = *password;
1635 E_md4hash(oldpass, old_nt_hash);
1636 E_md4hash(newpass, new_nt_hash);
1637 E_deshash(oldpass, old_lm_hash);
1638 E_deshash(newpass, new_lm_hash);
1640 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1641 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1642 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1643 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1644 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1645 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1647 r.in.user_handle = &user_handle;
1648 r.in.lm_present = 1;
1649 /* Break the LM hash */
1651 r.in.old_lm_crypted = &hash1;
1652 r.in.new_lm_crypted = &hash2;
1653 r.in.nt_present = 1;
1654 r.in.old_nt_crypted = &hash3;
1655 r.in.new_nt_crypted = &hash4;
1656 r.in.cross1_present = 1;
1657 r.in.nt_cross = &hash5;
1658 r.in.cross2_present = 1;
1659 r.in.lm_cross = &hash6;
1661 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1662 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1663 "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash");
1665 /* Unbreak the LM hash */
1668 r.in.user_handle = &user_handle;
1669 r.in.lm_present = 1;
1670 r.in.old_lm_crypted = &hash1;
1671 r.in.new_lm_crypted = &hash2;
1672 /* Break the NT hash */
1674 r.in.nt_present = 1;
1675 r.in.old_nt_crypted = &hash3;
1676 r.in.new_nt_crypted = &hash4;
1677 r.in.cross1_present = 1;
1678 r.in.nt_cross = &hash5;
1679 r.in.cross2_present = 1;
1680 r.in.lm_cross = &hash6;
1682 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1683 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1684 "expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash");
1686 /* Unbreak the NT hash */
1689 r.in.user_handle = &user_handle;
1690 r.in.lm_present = 1;
1691 r.in.old_lm_crypted = &hash1;
1692 r.in.new_lm_crypted = &hash2;
1693 r.in.nt_present = 1;
1694 r.in.old_nt_crypted = &hash3;
1695 r.in.new_nt_crypted = &hash4;
1696 r.in.cross1_present = 1;
1697 r.in.nt_cross = &hash5;
1698 r.in.cross2_present = 1;
1699 /* Break the LM cross */
1701 r.in.lm_cross = &hash6;
1703 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1704 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1705 torture_warning(tctx, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status));
1709 /* Unbreak the LM cross */
1712 r.in.user_handle = &user_handle;
1713 r.in.lm_present = 1;
1714 r.in.old_lm_crypted = &hash1;
1715 r.in.new_lm_crypted = &hash2;
1716 r.in.nt_present = 1;
1717 r.in.old_nt_crypted = &hash3;
1718 r.in.new_nt_crypted = &hash4;
1719 r.in.cross1_present = 1;
1720 /* Break the NT cross */
1722 r.in.nt_cross = &hash5;
1723 r.in.cross2_present = 1;
1724 r.in.lm_cross = &hash6;
1726 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1727 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1728 torture_warning(tctx, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status));
1732 /* Unbreak the NT cross */
1736 /* Reset the hashes to not broken values */
1737 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1738 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1739 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1740 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1741 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1742 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1744 r.in.user_handle = &user_handle;
1745 r.in.lm_present = 1;
1746 r.in.old_lm_crypted = &hash1;
1747 r.in.new_lm_crypted = &hash2;
1748 r.in.nt_present = 1;
1749 r.in.old_nt_crypted = &hash3;
1750 r.in.new_nt_crypted = &hash4;
1751 r.in.cross1_present = 1;
1752 r.in.nt_cross = &hash5;
1753 r.in.cross2_present = 0;
1754 r.in.lm_cross = NULL;
1756 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1757 if (NT_STATUS_IS_OK(status)) {
1759 *password = newpass;
1760 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1761 torture_warning(tctx, "ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(status));
1766 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1768 E_md4hash(oldpass, old_nt_hash);
1769 E_md4hash(newpass, new_nt_hash);
1770 E_deshash(oldpass, old_lm_hash);
1771 E_deshash(newpass, new_lm_hash);
1774 /* Reset the hashes to not broken values */
1775 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1776 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1777 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1778 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1779 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1780 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1782 r.in.user_handle = &user_handle;
1783 r.in.lm_present = 1;
1784 r.in.old_lm_crypted = &hash1;
1785 r.in.new_lm_crypted = &hash2;
1786 r.in.nt_present = 1;
1787 r.in.old_nt_crypted = &hash3;
1788 r.in.new_nt_crypted = &hash4;
1789 r.in.cross1_present = 0;
1790 r.in.nt_cross = NULL;
1791 r.in.cross2_present = 1;
1792 r.in.lm_cross = &hash6;
1794 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1795 if (NT_STATUS_IS_OK(status)) {
1797 *password = newpass;
1798 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1799 torture_warning(tctx, "ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status));
1804 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1806 E_md4hash(oldpass, old_nt_hash);
1807 E_md4hash(newpass, new_nt_hash);
1808 E_deshash(oldpass, old_lm_hash);
1809 E_deshash(newpass, new_lm_hash);
1812 /* Reset the hashes to not broken values */
1813 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1814 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1815 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1816 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1817 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1818 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1820 r.in.user_handle = &user_handle;
1821 r.in.lm_present = 1;
1822 r.in.old_lm_crypted = &hash1;
1823 r.in.new_lm_crypted = &hash2;
1824 r.in.nt_present = 1;
1825 r.in.old_nt_crypted = &hash3;
1826 r.in.new_nt_crypted = &hash4;
1827 r.in.cross1_present = 1;
1828 r.in.nt_cross = &hash5;
1829 r.in.cross2_present = 1;
1830 r.in.lm_cross = &hash6;
1832 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1833 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1834 torture_comment(tctx, "ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1835 } else if (!NT_STATUS_IS_OK(status)) {
1836 torture_warning(tctx, "ChangePasswordUser failed - %s\n", nt_errstr(status));
1840 *password = newpass;
1843 r.in.user_handle = &user_handle;
1844 r.in.lm_present = 1;
1845 r.in.old_lm_crypted = &hash1;
1846 r.in.new_lm_crypted = &hash2;
1847 r.in.nt_present = 1;
1848 r.in.old_nt_crypted = &hash3;
1849 r.in.new_nt_crypted = &hash4;
1850 r.in.cross1_present = 1;
1851 r.in.nt_cross = &hash5;
1852 r.in.cross2_present = 1;
1853 r.in.lm_cross = &hash6;
1856 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1857 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1858 torture_comment(tctx, "ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1859 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1860 torture_warning(tctx, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status));
1866 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
1874 static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
1875 const char *acct_name,
1876 struct policy_handle *handle, char **password)
1879 struct samr_OemChangePasswordUser2 r;
1881 struct samr_Password lm_verifier;
1882 struct samr_CryptPassword lm_pass;
1883 struct lsa_AsciiString server, account, account_bad;
1886 uint8_t old_lm_hash[16], new_lm_hash[16];
1888 struct samr_GetDomPwInfo dom_pw_info;
1889 struct samr_PwInfo info;
1890 int policy_min_pw_len = 0;
1892 struct lsa_String domain_name;
1894 domain_name.string = "";
1895 dom_pw_info.in.domain_name = &domain_name;
1896 dom_pw_info.out.info = &info;
1898 torture_comment(tctx, "Testing OemChangePasswordUser2\n");
1900 torture_assert(tctx, *password != NULL,
1901 "Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?");
1903 oldpass = *password;
1905 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
1906 if (NT_STATUS_IS_OK(status)) {
1907 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
1910 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1912 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1913 account.string = acct_name;
1915 E_deshash(oldpass, old_lm_hash);
1916 E_deshash(newpass, new_lm_hash);
1918 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1919 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1920 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1922 r.in.server = &server;
1923 r.in.account = &account;
1924 r.in.password = &lm_pass;
1925 r.in.hash = &lm_verifier;
1927 /* Break the verification */
1928 lm_verifier.hash[0]++;
1930 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1932 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1933 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1934 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1939 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1940 /* Break the old password */
1942 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1943 /* unbreak it for the next operation */
1945 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1947 r.in.server = &server;
1948 r.in.account = &account;
1949 r.in.password = &lm_pass;
1950 r.in.hash = &lm_verifier;
1952 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1954 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1955 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1956 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1961 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1962 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1964 r.in.server = &server;
1965 r.in.account = &account;
1966 r.in.password = &lm_pass;
1969 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1971 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1972 && !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1973 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
1978 /* This shouldn't be a valid name */
1979 account_bad.string = TEST_ACCOUNT_NAME "XX";
1980 r.in.account = &account_bad;
1982 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1984 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1985 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
1990 /* This shouldn't be a valid name */
1991 account_bad.string = TEST_ACCOUNT_NAME "XX";
1992 r.in.account = &account_bad;
1993 r.in.password = &lm_pass;
1994 r.in.hash = &lm_verifier;
1996 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1998 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1999 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
2004 /* This shouldn't be a valid name */
2005 account_bad.string = TEST_ACCOUNT_NAME "XX";
2006 r.in.account = &account_bad;
2007 r.in.password = NULL;
2008 r.in.hash = &lm_verifier;
2010 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
2012 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
2013 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
2018 E_deshash(oldpass, old_lm_hash);
2019 E_deshash(newpass, new_lm_hash);
2021 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
2022 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2023 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
2025 r.in.server = &server;
2026 r.in.account = &account;
2027 r.in.password = &lm_pass;
2028 r.in.hash = &lm_verifier;
2030 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
2031 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2032 torture_comment(tctx, "OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
2033 } else if (!NT_STATUS_IS_OK(status)) {
2034 torture_warning(tctx, "OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
2037 *password = newpass;
2044 static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
2045 const char *acct_name,
2047 char *newpass, bool allow_password_restriction)
2050 struct samr_ChangePasswordUser2 r;
2052 struct lsa_String server, account;
2053 struct samr_CryptPassword nt_pass, lm_pass;
2054 struct samr_Password nt_verifier, lm_verifier;
2056 uint8_t old_nt_hash[16], new_nt_hash[16];
2057 uint8_t old_lm_hash[16], new_lm_hash[16];
2059 struct samr_GetDomPwInfo dom_pw_info;
2060 struct samr_PwInfo info;
2062 struct lsa_String domain_name;
2064 domain_name.string = "";
2065 dom_pw_info.in.domain_name = &domain_name;
2066 dom_pw_info.out.info = &info;
2068 torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name);
2070 torture_assert(tctx, *password != NULL,
2071 "Failing ChangePasswordUser2 as old password was NULL. Previous test failed?");
2072 oldpass = *password;
2075 int policy_min_pw_len = 0;
2076 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
2077 if (NT_STATUS_IS_OK(status)) {
2078 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
2081 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2084 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2085 init_lsa_String(&account, acct_name);
2087 E_md4hash(oldpass, old_nt_hash);
2088 E_md4hash(newpass, new_nt_hash);
2090 E_deshash(oldpass, old_lm_hash);
2091 E_deshash(newpass, new_lm_hash);
2093 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
2094 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2095 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2097 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2098 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2099 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2101 r.in.server = &server;
2102 r.in.account = &account;
2103 r.in.nt_password = &nt_pass;
2104 r.in.nt_verifier = &nt_verifier;
2106 r.in.lm_password = &lm_pass;
2107 r.in.lm_verifier = &lm_verifier;
2109 status = dcerpc_samr_ChangePasswordUser2(p, tctx, &r);
2110 if (allow_password_restriction && NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2111 torture_comment(tctx, "ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
2112 } else if (!NT_STATUS_IS_OK(status)) {
2113 torture_warning(tctx, "ChangePasswordUser2 failed - %s\n", nt_errstr(status));
2116 *password = newpass;
2123 bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tctx,
2124 const char *account_string,
2125 int policy_min_pw_len,
2127 const char *newpass,
2128 NTTIME last_password_change,
2129 bool handle_reject_reason)
2132 struct samr_ChangePasswordUser3 r;
2134 struct lsa_String server, account, account_bad;
2135 struct samr_CryptPassword nt_pass, lm_pass;
2136 struct samr_Password nt_verifier, lm_verifier;
2138 uint8_t old_nt_hash[16], new_nt_hash[16];
2139 uint8_t old_lm_hash[16], new_lm_hash[16];
2141 struct samr_DomInfo1 *dominfo = NULL;
2142 struct userPwdChangeFailureInformation *reject = NULL;
2144 torture_comment(tctx, "Testing ChangePasswordUser3\n");
2146 if (newpass == NULL) {
2148 if (policy_min_pw_len == 0) {
2149 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2151 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len);
2153 } while (check_password_quality(newpass) == false);
2155 torture_comment(tctx, "Using password '%s'\n", newpass);
2158 torture_assert(tctx, *password != NULL,
2159 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2161 oldpass = *password;
2162 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2163 init_lsa_String(&account, account_string);
2165 E_md4hash(oldpass, old_nt_hash);
2166 E_md4hash(newpass, new_nt_hash);
2168 E_deshash(oldpass, old_lm_hash);
2169 E_deshash(newpass, new_lm_hash);
2171 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2172 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2173 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2175 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2176 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2177 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2179 /* Break the verification */
2180 nt_verifier.hash[0]++;
2182 r.in.server = &server;
2183 r.in.account = &account;
2184 r.in.nt_password = &nt_pass;
2185 r.in.nt_verifier = &nt_verifier;
2187 r.in.lm_password = &lm_pass;
2188 r.in.lm_verifier = &lm_verifier;
2189 r.in.password3 = NULL;
2190 r.out.dominfo = &dominfo;
2191 r.out.reject = &reject;
2193 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2194 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
2195 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
2196 torture_warning(tctx, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
2201 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2202 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2203 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2205 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2206 /* Break the NT hash */
2208 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2209 /* Unbreak it again */
2211 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2213 r.in.server = &server;
2214 r.in.account = &account;
2215 r.in.nt_password = &nt_pass;
2216 r.in.nt_verifier = &nt_verifier;
2218 r.in.lm_password = &lm_pass;
2219 r.in.lm_verifier = &lm_verifier;
2220 r.in.password3 = NULL;
2221 r.out.dominfo = &dominfo;
2222 r.out.reject = &reject;
2224 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2225 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
2226 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
2227 torture_warning(tctx, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
2232 /* This shouldn't be a valid name */
2233 init_lsa_String(&account_bad, talloc_asprintf(tctx, "%sXX", account_string));
2235 r.in.account = &account_bad;
2236 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2237 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
2238 torture_warning(tctx, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
2243 E_md4hash(oldpass, old_nt_hash);
2244 E_md4hash(newpass, new_nt_hash);
2246 E_deshash(oldpass, old_lm_hash);
2247 E_deshash(newpass, new_lm_hash);
2249 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2250 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2251 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2253 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2254 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2255 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2257 r.in.server = &server;
2258 r.in.account = &account;
2259 r.in.nt_password = &nt_pass;
2260 r.in.nt_verifier = &nt_verifier;
2262 r.in.lm_password = &lm_pass;
2263 r.in.lm_verifier = &lm_verifier;
2264 r.in.password3 = NULL;
2265 r.out.dominfo = &dominfo;
2266 r.out.reject = &reject;
2268 unix_to_nt_time(&t, time(NULL));
2270 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2272 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
2275 && handle_reject_reason
2276 && (!null_nttime(last_password_change) || !dominfo->min_password_age)) {
2277 if (dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
2279 if (reject && (reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR)) {
2280 torture_warning(tctx, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2281 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2286 /* We tested the order of precendence which is as follows:
2295 if ((dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
2296 (last_password_change + dominfo->min_password_age > t)) {
2298 if (reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2299 torture_warning(tctx, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2300 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2304 } else if ((dominfo->min_password_length > 0) &&
2305 (strlen(newpass) < dominfo->min_password_length)) {
2307 if (reject->extendedFailureReason != SAM_PWD_CHANGE_PASSWORD_TOO_SHORT) {
2308 torture_warning(tctx, "expected SAM_PWD_CHANGE_PASSWORD_TOO_SHORT (%d), got %d\n",
2309 SAM_PWD_CHANGE_PASSWORD_TOO_SHORT, reject->extendedFailureReason);
2313 } else if ((dominfo->password_history_length > 0) &&
2314 strequal(oldpass, newpass)) {
2316 if (reject->extendedFailureReason != SAM_PWD_CHANGE_PWD_IN_HISTORY) {
2317 torture_warning(tctx, "expected SAM_PWD_CHANGE_PWD_IN_HISTORY (%d), got %d\n",
2318 SAM_PWD_CHANGE_PWD_IN_HISTORY, reject->extendedFailureReason);
2321 } else if (dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
2323 if (reject->extendedFailureReason != SAM_PWD_CHANGE_NOT_COMPLEX) {
2324 torture_warning(tctx, "expected SAM_PWD_CHANGE_NOT_COMPLEX (%d), got %d\n",
2325 SAM_PWD_CHANGE_NOT_COMPLEX, reject->extendedFailureReason);
2331 if (reject->extendedFailureReason == SAM_PWD_CHANGE_PASSWORD_TOO_SHORT) {
2332 /* retry with adjusted size */
2333 return test_ChangePasswordUser3(p, tctx, account_string,
2334 dominfo->min_password_length,
2335 password, NULL, 0, false);
2339 } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2340 if (reject && reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2341 torture_warning(tctx, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2342 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2345 /* Perhaps the server has a 'min password age' set? */
2348 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3");
2349 *password = talloc_strdup(tctx, newpass);
2355 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_context *tctx,
2356 const char *account_string,
2357 struct policy_handle *handle,
2361 struct samr_ChangePasswordUser3 r;
2362 struct samr_SetUserInfo s;
2363 union samr_UserInfo u;
2364 DATA_BLOB session_key;
2365 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
2366 uint8_t confounder[16];
2367 struct MD5Context ctx;
2370 struct lsa_String server, account;
2371 struct samr_CryptPassword nt_pass;
2372 struct samr_Password nt_verifier;
2373 DATA_BLOB new_random_pass;
2376 uint8_t old_nt_hash[16], new_nt_hash[16];
2378 struct samr_DomInfo1 *dominfo = NULL;
2379 struct userPwdChangeFailureInformation *reject = NULL;
2381 new_random_pass = samr_very_rand_pass(tctx, 128);
2383 torture_assert(tctx, *password != NULL,
2384 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2386 oldpass = *password;
2387 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2388 init_lsa_String(&account, account_string);
2390 s.in.user_handle = handle;
2396 u.info25.info.fields_present = SAMR_FIELD_NT_PASSWORD_PRESENT;
2398 set_pw_in_buffer(u.info25.password.data, &new_random_pass);
2400 status = dcerpc_fetch_session_key(p, &session_key);
2401 if (!NT_STATUS_IS_OK(status)) {
2402 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
2403 s.in.level, nt_errstr(status));
2407 generate_random_buffer((uint8_t *)confounder, 16);
2410 MD5Update(&ctx, confounder, 16);
2411 MD5Update(&ctx, session_key.data, session_key.length);
2412 MD5Final(confounded_session_key.data, &ctx);
2414 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
2415 memcpy(&u.info25.password.data[516], confounder, 16);
2417 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
2419 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
2420 if (!NT_STATUS_IS_OK(status)) {
2421 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
2422 s.in.level, nt_errstr(status));
2426 torture_comment(tctx, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
2428 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2430 new_random_pass = samr_very_rand_pass(tctx, 128);
2432 mdfour(new_nt_hash, new_random_pass.data, new_random_pass.length);
2434 set_pw_in_buffer(nt_pass.data, &new_random_pass);
2435 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2436 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2438 r.in.server = &server;
2439 r.in.account = &account;
2440 r.in.nt_password = &nt_pass;
2441 r.in.nt_verifier = &nt_verifier;
2443 r.in.lm_password = NULL;
2444 r.in.lm_verifier = NULL;
2445 r.in.password3 = NULL;
2446 r.out.dominfo = &dominfo;
2447 r.out.reject = &reject;
2449 unix_to_nt_time(&t, time(NULL));
2451 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2453 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2454 if (reject && reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2455 torture_warning(tctx, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2456 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2459 /* Perhaps the server has a 'min password age' set? */
2461 } else if (!NT_STATUS_IS_OK(status)) {
2462 torture_warning(tctx, "ChangePasswordUser3 failed - %s\n", nt_errstr(status));
2466 newpass = samr_rand_pass(tctx, 128);
2468 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2470 E_md4hash(newpass, new_nt_hash);
2472 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2473 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2474 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2476 r.in.server = &server;
2477 r.in.account = &account;
2478 r.in.nt_password = &nt_pass;
2479 r.in.nt_verifier = &nt_verifier;
2481 r.in.lm_password = NULL;
2482 r.in.lm_verifier = NULL;
2483 r.in.password3 = NULL;
2484 r.out.dominfo = &dominfo;
2485 r.out.reject = &reject;
2487 unix_to_nt_time(&t, time(NULL));
2489 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2491 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2492 if (reject && reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2493 torture_warning(tctx, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2494 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2497 /* Perhaps the server has a 'min password age' set? */
2500 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3 (on second random password)");
2501 *password = talloc_strdup(tctx, newpass);
2508 static bool test_GetMembersInAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2509 struct policy_handle *alias_handle)
2511 struct samr_GetMembersInAlias r;
2512 struct lsa_SidArray sids;
2515 torture_comment(tctx, "Testing GetMembersInAlias\n");
2517 r.in.alias_handle = alias_handle;
2520 status = dcerpc_samr_GetMembersInAlias(p, tctx, &r);
2521 torture_assert_ntstatus_ok(tctx, status, "GetMembersInAlias");
2526 static bool test_AddMemberToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2527 struct policy_handle *alias_handle,
2528 const struct dom_sid *domain_sid)
2530 struct samr_AddAliasMember r;
2531 struct samr_DeleteAliasMember d;
2533 struct dom_sid *sid;
2535 sid = dom_sid_add_rid(tctx, domain_sid, 512);
2537 torture_comment(tctx, "testing AddAliasMember\n");
2538 r.in.alias_handle = alias_handle;
2541 status = dcerpc_samr_AddAliasMember(p, tctx, &r);
2542 torture_assert_ntstatus_ok(tctx, status, "AddAliasMember");
2544 d.in.alias_handle = alias_handle;
2547 status = dcerpc_samr_DeleteAliasMember(p, tctx, &d);
2548 torture_assert_ntstatus_ok(tctx, status, "DelAliasMember");
2553 static bool test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2554 struct policy_handle *alias_handle)
2556 struct samr_AddMultipleMembersToAlias a;
2557 struct samr_RemoveMultipleMembersFromAlias r;
2559 struct lsa_SidArray sids;
2561 torture_comment(tctx, "testing AddMultipleMembersToAlias\n");
2562 a.in.alias_handle = alias_handle;
2566 sids.sids = talloc_array(tctx, struct lsa_SidPtr, 3);
2568 sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2569 sids.sids[1].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-2");
2570 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-3");
2572 status = dcerpc_samr_AddMultipleMembersToAlias(p, tctx, &a);
2573 torture_assert_ntstatus_ok(tctx, status, "AddMultipleMembersToAlias");
2576 torture_comment(tctx, "testing RemoveMultipleMembersFromAlias\n");
2577 r.in.alias_handle = alias_handle;
2580 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2581 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2583 /* strange! removing twice doesn't give any error */
2584 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2585 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2587 /* but removing an alias that isn't there does */
2588 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-4");
2590 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2591 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, "RemoveMultipleMembersFromAlias");
2596 static bool test_GetAliasMembership(struct dcerpc_pipe *p,
2597 struct torture_context *tctx,
2598 struct policy_handle *domain_handle)
2600 struct samr_GetAliasMembership r;
2601 struct lsa_SidArray sids;
2602 struct samr_Ids rids;
2605 torture_comment(tctx, "Testing GetAliasMembership\n");
2607 if (torture_setting_bool(tctx, "samba4", false)) {
2608 torture_skip(tctx, "skipping GetAliasMembership against s4");
2611 r.in.domain_handle = domain_handle;
2616 sids.sids = talloc_zero_array(tctx, struct lsa_SidPtr, sids.num_sids);
2618 status = dcerpc_samr_GetAliasMembership(p, tctx, &r);
2619 torture_assert_ntstatus_ok(tctx, status,
2620 "samr_GetAliasMembership failed");
2622 torture_assert_int_equal(tctx, sids.num_sids, rids.count,
2623 "protocol misbehaviour");
2626 sids.sids = talloc_zero_array(tctx, struct lsa_SidPtr, sids.num_sids);
2627 sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2629 status = dcerpc_samr_GetAliasMembership(p, tctx, &r);
2630 torture_assert_ntstatus_ok(tctx, status,
2631 "samr_GetAliasMembership failed");
2634 /* only true for w2k8 it seems
2635 * win7, xp, w2k3 will return a 0 length array pointer */
2637 torture_assert(tctx, (rids.ids && !rids.count),
2638 "samr_GetAliasMembership protocol misbehaviour");
2640 torture_assert(tctx, (!rids.ids && rids.count),
2641 "samr_GetAliasMembership protocol misbehaviour");
2646 static bool test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2647 struct policy_handle *user_handle)
2649 struct samr_TestPrivateFunctionsUser r;
2652 torture_comment(tctx, "Testing TestPrivateFunctionsUser\n");
2654 r.in.user_handle = user_handle;
2656 status = dcerpc_samr_TestPrivateFunctionsUser(p, tctx, &r);
2657 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsUser");
2662 static bool test_QueryUserInfo_pwdlastset(struct dcerpc_pipe *p,
2663 struct torture_context *tctx,
2664 struct policy_handle *handle,
2669 uint16_t levels[] = { /* 3, */ 5, 21 };
2671 NTTIME pwdlastset3 = 0;
2672 NTTIME pwdlastset5 = 0;
2673 NTTIME pwdlastset21 = 0;
2675 torture_comment(tctx, "Testing QueryUserInfo%s level 5 and 21 call ",
2676 use_info2 ? "2":"");
2678 for (i=0; i<ARRAY_SIZE(levels); i++) {
2680 struct samr_QueryUserInfo r;
2681 struct samr_QueryUserInfo2 r2;
2682 union samr_UserInfo *info;
2685 r2.in.user_handle = handle;
2686 r2.in.level = levels[i];
2687 r2.out.info = &info;
2688 status = dcerpc_samr_QueryUserInfo2(p, tctx, &r2);
2691 r.in.user_handle = handle;
2692 r.in.level = levels[i];
2694 status = dcerpc_samr_QueryUserInfo(p, tctx, &r);
2697 if (!NT_STATUS_IS_OK(status) &&
2698 !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
2699 torture_warning(tctx, "QueryUserInfo%s level %u failed - %s\n",
2700 use_info2 ? "2":"", levels[i], nt_errstr(status));
2704 switch (levels[i]) {
2706 pwdlastset3 = info->info3.last_password_change;
2709 pwdlastset5 = info->info5.last_password_change;
2712 pwdlastset21 = info->info21.last_password_change;
2718 /* torture_assert_int_equal(tctx, pwdlastset3, pwdlastset5,
2719 "pwdlastset mixup"); */
2720 torture_assert_int_equal(tctx, pwdlastset5, pwdlastset21,
2721 "pwdlastset mixup");
2723 *pwdlastset = pwdlastset21;
2725 torture_comment(tctx, "(pwdlastset: %lld)\n", *pwdlastset);
2730 static bool test_SamLogon(struct torture_context *tctx,
2731 struct dcerpc_pipe *p,
2732 struct cli_credentials *test_credentials,
2733 NTSTATUS expected_result)
2736 struct netr_LogonSamLogonEx r;
2737 union netr_LogonLevel logon;
2738 union netr_Validation validation;
2739 uint8_t authoritative;
2740 struct netr_NetworkInfo ninfo;
2741 DATA_BLOB names_blob, chal, lm_resp, nt_resp;
2742 int flags = CLI_CRED_NTLM_AUTH;
2743 uint32_t samlogon_flags = 0;
2745 if (lp_client_lanman_auth(tctx->lp_ctx)) {
2746 flags |= CLI_CRED_LANMAN_AUTH;
2749 if (lp_client_ntlmv2_auth(tctx->lp_ctx)) {
2750 flags |= CLI_CRED_NTLMv2_AUTH;
2753 cli_credentials_get_ntlm_username_domain(test_credentials, tctx,
2754 &ninfo.identity_info.account_name.string,
2755 &ninfo.identity_info.domain_name.string);
2757 generate_random_buffer(ninfo.challenge,
2758 sizeof(ninfo.challenge));
2759 chal = data_blob_const(ninfo.challenge,
2760 sizeof(ninfo.challenge));
2762 names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(test_credentials),
2763 cli_credentials_get_domain(test_credentials));
2765 status = cli_credentials_get_ntlm_response(test_credentials, tctx,
2771 torture_assert_ntstatus_ok(tctx, status, "cli_credentials_get_ntlm_response failed");
2773 ninfo.lm.data = lm_resp.data;
2774 ninfo.lm.length = lm_resp.length;
2776 ninfo.nt.data = nt_resp.data;
2777 ninfo.nt.length = nt_resp.length;
2779 ninfo.identity_info.parameter_control =
2780 MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT |
2781 MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;
2782 ninfo.identity_info.logon_id_low = 0;
2783 ninfo.identity_info.logon_id_high = 0;
2784 ninfo.identity_info.workstation.string = cli_credentials_get_workstation(test_credentials);
2786 logon.network = &ninfo;
2788 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2789 r.in.computer_name = cli_credentials_get_workstation(test_credentials);
2790 r.in.logon_level = NetlogonNetworkInformation;
2791 r.in.logon = &logon;
2792 r.in.flags = &samlogon_flags;
2793 r.out.flags = &samlogon_flags;
2794 r.out.validation = &validation;
2795 r.out.authoritative = &authoritative;
2797 torture_comment(tctx, "Testing LogonSamLogon with name %s\n", ninfo.identity_info.account_name.string);
2799 r.in.validation_level = 6;
2801 status = dcerpc_netr_LogonSamLogonEx(p, tctx, &r);
2802 if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
2803 r.in.validation_level = 3;
2804 status = dcerpc_netr_LogonSamLogonEx(p, tctx, &r);
2806 if (!NT_STATUS_IS_OK(status)) {
2807 torture_assert_ntstatus_equal(tctx, status, expected_result, "LogonSamLogonEx failed");
2810 torture_assert_ntstatus_ok(tctx, status, "LogonSamLogonEx failed");
2816 static bool test_SamLogon_with_creds(struct torture_context *tctx,
2817 struct dcerpc_pipe *p,
2818 struct cli_credentials *machine_creds,
2819 const char *acct_name,
2821 NTSTATUS expected_samlogon_result)
2824 struct cli_credentials *test_credentials;
2826 test_credentials = cli_credentials_init(tctx);
2828 cli_credentials_set_workstation(test_credentials,
2829 cli_credentials_get_workstation(machine_creds), CRED_SPECIFIED);
2830 cli_credentials_set_domain(test_credentials,
2831 cli_credentials_get_domain(machine_creds), CRED_SPECIFIED);
2832 cli_credentials_set_username(test_credentials,
2833 acct_name, CRED_SPECIFIED);
2834 cli_credentials_set_password(test_credentials,
2835 password, CRED_SPECIFIED);
2837 torture_comment(tctx, "testing samlogon as %s password: %s\n",
2838 acct_name, password);
2840 if (!test_SamLogon(tctx, p, test_credentials,
2841 expected_samlogon_result)) {
2842 torture_warning(tctx, "new password did not work\n");
2849 static bool test_SetPassword_level(struct dcerpc_pipe *p,
2850 struct dcerpc_pipe *np,
2851 struct torture_context *tctx,
2852 struct policy_handle *handle,
2854 uint32_t fields_present,
2855 uint8_t password_expired,
2856 bool *matched_expected_error,
2858 const char *acct_name,
2860 struct cli_credentials *machine_creds,
2861 bool use_queryinfo2,
2863 NTSTATUS expected_samlogon_result)
2865 const char *fields = NULL;
2872 fields = talloc_asprintf(tctx, "(fields_present: 0x%08x)",
2879 torture_comment(tctx, "Testing SetUserInfo%s level %d call "
2880 "(password_expired: %d) %s\n",
2881 use_setinfo2 ? "2":"", level, password_expired,
2882 fields ? fields : "");
2884 if (!test_SetUserPass_level_ex(p, tctx, handle, level,
2889 matched_expected_error)) {
2893 if (!test_QueryUserInfo_pwdlastset(p, tctx, handle,
2899 if (*matched_expected_error == true) {
2903 if (!test_SamLogon_with_creds(tctx, np,
2907 expected_samlogon_result)) {
2914 static bool test_SetPassword_pwdlastset(struct dcerpc_pipe *p,
2915 struct torture_context *tctx,
2916 uint32_t acct_flags,
2917 const char *acct_name,
2918 struct policy_handle *handle,
2920 struct cli_credentials *machine_credentials)
2922 int s = 0, q = 0, f = 0, l = 0, z = 0;
2923 struct dcerpc_binding *b;
2926 bool set_levels[] = { false, true };
2927 bool query_levels[] = { false, true };
2928 uint32_t levels[] = { 18, 21, 26, 23, 24, 25 }; /* Second half only used when TEST_ALL_LEVELS defined */
2929 uint32_t nonzeros[] = { 1, 24 };
2930 uint32_t fields_present[] = {
2932 SAMR_FIELD_EXPIRED_FLAG,
2933 SAMR_FIELD_LAST_PWD_CHANGE,
2934 SAMR_FIELD_EXPIRED_FLAG | SAMR_FIELD_LAST_PWD_CHANGE,
2936 SAMR_FIELD_NT_PASSWORD_PRESENT,
2937 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
2938 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
2939 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
2940 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
2941 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
2942 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE | SAMR_FIELD_EXPIRED_FLAG
2945 struct dcerpc_pipe *np = NULL;
2947 if (torture_setting_bool(tctx, "samba3", false)) {
2949 torture_comment(tctx, "Samba3 has second granularity, setting delay to: %d\n",
2953 status = torture_rpc_binding(tctx, &b);
2954 if (!NT_STATUS_IS_OK(status)) {
2959 /* We have to use schannel, otherwise the SamLogonEx fails
2960 * with INTERNAL_ERROR */
2962 b->flags &= ~DCERPC_AUTH_OPTIONS;
2963 b->flags |= DCERPC_SCHANNEL | DCERPC_SIGN | DCERPC_SCHANNEL_128;
2965 status = dcerpc_pipe_connect_b(tctx, &np, b,
2966 &ndr_table_netlogon,
2967 machine_credentials, tctx->ev, tctx->lp_ctx);
2969 if (!NT_STATUS_IS_OK(status)) {
2970 torture_warning(tctx, "RPC pipe connect as domain member failed: %s\n", nt_errstr(status));
2975 /* set to 1 to enable testing for all possible opcode
2976 (SetUserInfo, SetUserInfo2, QueryUserInfo, QueryUserInfo2)
2979 #define TEST_ALL_LEVELS 1
2980 #define TEST_SET_LEVELS 1
2981 #define TEST_QUERY_LEVELS 1
2983 #ifdef TEST_ALL_LEVELS
2984 for (l=0; l<ARRAY_SIZE(levels); l++) {
2986 for (l=0; l<(ARRAY_SIZE(levels))/2; l++) {
2988 for (z=0; z<ARRAY_SIZE(nonzeros); z++) {
2989 for (f=0; f<ARRAY_SIZE(fields_present); f++) {
2990 #ifdef TEST_SET_LEVELS
2991 for (s=0; s<ARRAY_SIZE(set_levels); s++) {
2993 #ifdef TEST_QUERY_LEVELS
2994 for (q=0; q<ARRAY_SIZE(query_levels); q++) {
2996 NTTIME pwdlastset_old = 0;
2997 NTTIME pwdlastset_new = 0;
2998 bool matched_expected_error = false;
2999 NTSTATUS expected_samlogon_result = NT_STATUS_ACCOUNT_DISABLED;
3001 torture_comment(tctx, "------------------------------\n"
3002 "Testing pwdLastSet attribute for flags: 0x%08x "
3003 "(s: %d (l: %d), q: %d)\n",
3004 acct_flags, s, levels[l], q);
3006 switch (levels[l]) {
3010 if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3011 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT))) {
3012 expected_samlogon_result = NT_STATUS_WRONG_PASSWORD;
3020 /* set a password and force password change (pwdlastset 0) by
3021 * setting the password expired flag to a non-0 value */
3023 if (!test_SetPassword_level(p, np, tctx, handle,
3027 &matched_expected_error,
3031 machine_credentials,
3034 expected_samlogon_result)) {
3038 if (matched_expected_error == true) {
3039 /* skipping on expected failure */
3043 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3044 * set without the SAMR_FIELD_EXPIRED_FLAG */
3046 switch (levels[l]) {
3050 if ((pwdlastset_new != 0) &&
3051 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
3052 torture_comment(tctx, "not considering a non-0 "
3053 "pwdLastSet as a an error as the "
3054 "SAMR_FIELD_EXPIRED_FLAG has not "
3059 if (pwdlastset_new != 0) {
3060 torture_warning(tctx, "pwdLastSet test failed: "
3061 "expected pwdLastSet 0 but got %lld\n",
3068 switch (levels[l]) {
3072 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3073 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3074 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3075 (pwdlastset_old >= pwdlastset_new)) {
3076 torture_warning(tctx, "pwdlastset not increasing\n");
3081 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3082 (pwdlastset_old >= pwdlastset_new)) {
3083 torture_warning(tctx, "pwdlastset not increasing\n");
3093 /* set a password, pwdlastset needs to get updated (increased
3094 * value), password_expired value used here is 0 */
3096 if (!test_SetPassword_level(p, np, tctx, handle,
3100 &matched_expected_error,
3104 machine_credentials,
3107 expected_samlogon_result)) {
3111 /* when a password has been changed, pwdlastset must not be 0 afterwards
3112 * and must be larger then the old value */
3114 switch (levels[l]) {
3119 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3120 * password has been changed, old and new pwdlastset
3121 * need to be the same value */
3123 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3124 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3125 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3127 torture_assert_int_equal(tctx, pwdlastset_old,
3128 pwdlastset_new, "pwdlastset must be equal");
3132 if (pwdlastset_old >= pwdlastset_new) {
3133 torture_warning(tctx, "pwdLastSet test failed: "
3134 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
3135 pwdlastset_old, pwdlastset_new);
3138 if (pwdlastset_new == 0) {
3139 torture_warning(tctx, "pwdLastSet test failed: "
3140 "expected non-0 pwdlastset, got: %lld\n",
3146 switch (levels[l]) {
3150 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3151 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3152 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3153 (pwdlastset_old >= pwdlastset_new)) {
3154 torture_warning(tctx, "pwdlastset not increasing\n");
3159 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3160 (pwdlastset_old >= pwdlastset_new)) {
3161 torture_warning(tctx, "pwdlastset not increasing\n");
3167 pwdlastset_old = pwdlastset_new;
3173 /* set a password, pwdlastset needs to get updated (increased
3174 * value), password_expired value used here is 0 */
3176 if (!test_SetPassword_level(p, np, tctx, handle,
3180 &matched_expected_error,
3184 machine_credentials,
3187 expected_samlogon_result)) {
3191 /* when a password has been changed, pwdlastset must not be 0 afterwards
3192 * and must be larger then the old value */
3194 switch (levels[l]) {
3199 /* if no password has been changed, old and new pwdlastset
3200 * need to be the same value */
3202 if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3203 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3205 torture_assert_int_equal(tctx, pwdlastset_old,
3206 pwdlastset_new, "pwdlastset must be equal");
3210 if (pwdlastset_old >= pwdlastset_new) {
3211 torture_warning(tctx, "pwdLastSet test failed: "
3212 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
3213 pwdlastset_old, pwdlastset_new);
3216 if (pwdlastset_new == 0) {
3217 torture_warning(tctx, "pwdLastSet test failed: "
3218 "expected non-0 pwdlastset, got: %lld\n",
3226 /* set a password and force password change (pwdlastset 0) by
3227 * setting the password expired flag to a non-0 value */
3229 if (!test_SetPassword_level(p, np, tctx, handle,
3233 &matched_expected_error,
3237 machine_credentials,
3240 expected_samlogon_result)) {
3244 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3245 * set without the SAMR_FIELD_EXPIRED_FLAG */
3247 switch (levels[l]) {
3251 if ((pwdlastset_new != 0) &&
3252 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
3253 torture_comment(tctx, "not considering a non-0 "
3254 "pwdLastSet as a an error as the "
3255 "SAMR_FIELD_EXPIRED_FLAG has not "
3260 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3261 * password has been changed, old and new pwdlastset
3262 * need to be the same value */
3264 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3265 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3266 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3268 torture_assert_int_equal(tctx, pwdlastset_old,
3269 pwdlastset_new, "pwdlastset must be equal");
3274 if (pwdlastset_old == pwdlastset_new) {
3275 torture_warning(tctx, "pwdLastSet test failed: "
3276 "expected last pwdlastset (%lld) != new pwdlastset (%lld)\n",
3277 pwdlastset_old, pwdlastset_new);
3281 if (pwdlastset_new != 0) {
3282 torture_warning(tctx, "pwdLastSet test failed: "
3283 "expected pwdLastSet 0, got %lld\n",
3290 switch (levels[l]) {
3294 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3295 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3296 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3297 (pwdlastset_old >= pwdlastset_new)) {
3298 torture_warning(tctx, "pwdlastset not increasing\n");
3303 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3304 (pwdlastset_old >= pwdlastset_new)) {
3305 torture_warning(tctx, "pwdlastset not increasing\n");
3311 /* if the level we are testing does not have a fields_present
3312 * field, skip all fields present tests by setting f to to
3314 switch (levels[l]) {
3318 f = ARRAY_SIZE(fields_present);
3322 #ifdef TEST_QUERY_LEVELS
3325 #ifdef TEST_SET_LEVELS
3328 } /* fields present */
3332 #undef TEST_SET_LEVELS
3333 #undef TEST_QUERY_LEVELS
3340 static bool test_DeleteUser_with_privs(struct dcerpc_pipe *p,
3341 struct dcerpc_pipe *lp,
3342 struct torture_context *tctx,
3343 struct policy_handle *domain_handle,
3344 struct policy_handle *lsa_handle,
3345 struct policy_handle *user_handle,
3346 const struct dom_sid *domain_sid,
3348 struct cli_credentials *machine_credentials)
3353 struct policy_handle lsa_acct_handle;
3354 struct dom_sid *user_sid;
3356 user_sid = dom_sid_add_rid(tctx, domain_sid, rid);
3359 struct lsa_EnumAccountRights r;
3360 struct lsa_RightSet rights;
3362 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
3364 r.in.handle = lsa_handle;
3365 r.in.sid = user_sid;
3366 r.out.rights = &rights;
3368 status = dcerpc_lsa_EnumAccountRights(lp, tctx, &r);
3369 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3370 "Expected enum rights for account to fail");
3374 struct lsa_RightSet rights;
3375 struct lsa_StringLarge names[2];
3376 struct lsa_AddAccountRights r;
3378 torture_comment(tctx, "Testing LSA AddAccountRights\n");
3380 init_lsa_StringLarge(&names[0], "SeMachineAccountPrivilege");
3381 init_lsa_StringLarge(&names[1], NULL);
3384 rights.names = names;
3386 r.in.handle = lsa_handle;
3387 r.in.sid = user_sid;
3388 r.in.rights = &rights;
3390 status = dcerpc_lsa_AddAccountRights(lp, tctx, &r);
3391 torture_assert_ntstatus_ok(tctx, status,
3392 "Failed to add privileges");
3396 struct lsa_EnumAccounts r;
3397 uint32_t resume_handle = 0;
3398 struct lsa_SidArray lsa_sid_array;
3400 bool found_sid = false;
3402 torture_comment(tctx, "Testing LSA EnumAccounts\n");
3404 r.in.handle = lsa_handle;
3405 r.in.num_entries = 0x1000;
3406 r.in.resume_handle = &resume_handle;
3407 r.out.sids = &lsa_sid_array;
3408 r.out.resume_handle = &resume_handle;
3410 status = dcerpc_lsa_EnumAccounts(lp, tctx, &r);
3411 torture_assert_ntstatus_ok(tctx, status,
3412 "Failed to enum accounts");
3414 for (i=0; i < lsa_sid_array.num_sids; i++) {
3415 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
3420 torture_assert(tctx, found_sid,
3421 "failed to list privileged account");
3425 struct lsa_EnumAccountRights r;
3426 struct lsa_RightSet user_rights;
3428 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
3430 r.in.handle = lsa_handle;
3431 r.in.sid = user_sid;
3432 r.out.rights = &user_rights;
3434 status = dcerpc_lsa_EnumAccountRights(lp, tctx, &r);
3435 torture_assert_ntstatus_ok(tctx, status,
3436 "Failed to enum rights for account");
3438 if (user_rights.count < 1) {
3439 torture_warning(tctx, "failed to find newly added rights");
3445 struct lsa_OpenAccount r;
3447 torture_comment(tctx, "Testing LSA OpenAccount\n");
3449 r.in.handle = lsa_handle;
3450 r.in.sid = user_sid;
3451 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3452 r.out.acct_handle = &lsa_acct_handle;
3454 status = dcerpc_lsa_OpenAccount(lp, tctx, &r);
3455 torture_assert_ntstatus_ok(tctx, status,
3456 "Failed to open lsa account");
3460 struct lsa_GetSystemAccessAccount r;
3461 uint32_t access_mask;
3463 torture_comment(tctx, "Testing LSA GetSystemAccessAccount\n");
3465 r.in.handle = &lsa_acct_handle;
3466 r.out.access_mask = &access_mask;
3468 status = dcerpc_lsa_GetSystemAccessAccount(lp, tctx, &r);
3469 torture_assert_ntstatus_ok(tctx, status,
3470 "Failed to get lsa system access account");
3476 torture_comment(tctx, "Testing LSA Close\n");
3478 r.in.handle = &lsa_acct_handle;
3479 r.out.handle = &lsa_acct_handle;
3481 status = dcerpc_lsa_Close(lp, tctx, &r);
3482 torture_assert_ntstatus_ok(tctx, status,
3483 "Failed to close lsa");
3487 struct samr_DeleteUser r;
3489 torture_comment(tctx, "Testing SAMR DeleteUser\n");
3491 r.in.user_handle = user_handle;
3492 r.out.user_handle = user_handle;
3494 status = dcerpc_samr_DeleteUser(p, tctx, &r);
3495 torture_assert_ntstatus_ok(tctx, status, "Delete User failed");
3499 struct lsa_EnumAccounts r;
3500 uint32_t resume_handle = 0;
3501 struct lsa_SidArray lsa_sid_array;
3503 bool found_sid = false;
3505 torture_comment(tctx, "Testing LSA EnumAccounts\n");
3507 r.in.handle = lsa_handle;
3508 r.in.num_entries = 0x1000;
3509 r.in.resume_handle = &resume_handle;
3510 r.out.sids = &lsa_sid_array;
3511 r.out.resume_handle = &resume_handle;
3513 status = dcerpc_lsa_EnumAccounts(lp, tctx, &r);
3514 torture_assert_ntstatus_ok(tctx, status,
3515 "Failed to enum accounts");
3517 for (i=0; i < lsa_sid_array.num_sids; i++) {
3518 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
3523 torture_assert(tctx, found_sid,
3524 "failed to list privileged account");
3528 struct lsa_EnumAccountRights r;
3529 struct lsa_RightSet user_rights;
3531 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
3533 r.in.handle = lsa_handle;
3534 r.in.sid = user_sid;
3535 r.out.rights = &user_rights;
3537 status = dcerpc_lsa_EnumAccountRights(lp, tctx, &r);
3538 torture_assert_ntstatus_ok(tctx, status,
3539 "Failed to enum rights for account");
3541 if (user_rights.count < 1) {
3542 torture_warning(tctx, "failed to find newly added rights");
3548 struct lsa_OpenAccount r;
3550 torture_comment(tctx, "Testing LSA OpenAccount\n");
3552 r.in.handle = lsa_handle;
3553 r.in.sid = user_sid;
3554 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3555 r.out.acct_handle = &lsa_acct_handle;
3557 status = dcerpc_lsa_OpenAccount(lp, tctx, &r);
3558 torture_assert_ntstatus_ok(tctx, status,
3559 "Failed to open lsa account");
3563 struct lsa_GetSystemAccessAccount r;
3564 uint32_t access_mask;
3566 torture_comment(tctx, "Testing LSA GetSystemAccessAccount\n");
3568 r.in.handle = &lsa_acct_handle;
3569 r.out.access_mask = &access_mask;
3571 status = dcerpc_lsa_GetSystemAccessAccount(lp, tctx, &r);
3572 torture_assert_ntstatus_ok(tctx, status,
3573 "Failed to get lsa system access account");
3577 struct lsa_DeleteObject r;
3579 torture_comment(tctx, "Testing LSA DeleteObject\n");
3581 r.in.handle = &lsa_acct_handle;
3582 r.out.handle = &lsa_acct_handle;
3584 status = dcerpc_lsa_DeleteObject(lp, tctx, &r);
3585 torture_assert_ntstatus_ok(tctx, status,
3586 "Failed to delete object");
3590 struct lsa_EnumAccounts r;
3591 uint32_t resume_handle = 0;
3592 struct lsa_SidArray lsa_sid_array;
3594 bool found_sid = false;
3596 torture_comment(tctx, "Testing LSA EnumAccounts\n");
3598 r.in.handle = lsa_handle;
3599 r.in.num_entries = 0x1000;
3600 r.in.resume_handle = &resume_handle;
3601 r.out.sids = &lsa_sid_array;
3602 r.out.resume_handle = &resume_handle;
3604 status = dcerpc_lsa_EnumAccounts(lp, tctx, &r);
3605 torture_assert_ntstatus_ok(tctx, status,
3606 "Failed to enum accounts");
3608 for (i=0; i < lsa_sid_array.num_sids; i++) {
3609 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
3614 torture_assert(tctx, !found_sid,
3615 "should not have listed privileged account");
3619 struct lsa_EnumAccountRights r;
3620 struct lsa_RightSet user_rights;
3622 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
3624 r.in.handle = lsa_handle;
3625 r.in.sid = user_sid;
3626 r.out.rights = &user_rights;
3628 status = dcerpc_lsa_EnumAccountRights(lp, tctx, &r);
3629 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3630 "Failed to enum rights for account");
3636 static bool test_user_ops(struct dcerpc_pipe *p,
3637 struct torture_context *tctx,
3638 struct policy_handle *user_handle,
3639 struct policy_handle *domain_handle,
3640 const struct dom_sid *domain_sid,
3641 uint32_t base_acct_flags,
3642 const char *base_acct_name, enum torture_samr_choice which_ops,
3643 struct cli_credentials *machine_credentials)
3645 char *password = NULL;
3646 struct samr_QueryUserInfo q;
3647 union samr_UserInfo *info;
3653 const uint32_t password_fields[] = {
3654 SAMR_FIELD_NT_PASSWORD_PRESENT,
3655 SAMR_FIELD_LM_PASSWORD_PRESENT,
3656 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
3660 status = test_LookupName(p, tctx, domain_handle, base_acct_name, &rid);
3661 if (!NT_STATUS_IS_OK(status)) {
3665 switch (which_ops) {
3666 case TORTURE_SAMR_USER_ATTRIBUTES:
3667 if (!test_QuerySecurity(p, tctx, user_handle)) {
3671 if (!test_QueryUserInfo(p, tctx, user_handle)) {
3675 if (!test_QueryUserInfo2(p, tctx, user_handle)) {
3679 if (!test_SetUserInfo(p, tctx, user_handle, base_acct_flags,
3684 if (!test_GetUserPwInfo(p, tctx, user_handle)) {
3688 if (!test_TestPrivateFunctionsUser(p, tctx, user_handle)) {
3692 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
3696 case TORTURE_SAMR_PASSWORDS:
3697 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
3698 char simple_pass[9];
3699 char *v = generate_random_str(tctx, 1);
3701 ZERO_STRUCT(simple_pass);
3702 memset(simple_pass, *v, sizeof(simple_pass) - 1);
3704 torture_comment(tctx, "Testing machine account password policy rules\n");
3706 /* Workstation trust accounts don't seem to need to honour password quality policy */
3707 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
3711 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
3715 /* reset again, to allow another 'user' password change */
3716 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
3720 /* Try a 'short' password */
3721 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
3725 /* Try a compleatly random password */
3726 if (!test_ChangePasswordRandomBytes(p, tctx, base_acct_name, user_handle, &password)) {
3731 for (i = 0; password_fields[i]; i++) {
3732 if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
3736 /* check it was set right */
3737 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3742 for (i = 0; password_fields[i]; i++) {
3743 if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
3747 /* check it was set right */
3748 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3753 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
3757 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
3761 if (torture_setting_bool(tctx, "samba4", false)) {
3762 torture_comment(tctx, "skipping Set Password level 18 and 21 against Samba4\n");
3765 if (!test_SetUserPass_18(p, tctx, user_handle, &password)) {
3769 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3773 for (i = 0; password_fields[i]; i++) {
3775 if (password_fields[i] == SAMR_FIELD_LM_PASSWORD_PRESENT) {
3776 /* we need to skip as that would break
3777 * the ChangePasswordUser3 verify */
3781 if (!test_SetUserPass_21(p, tctx, user_handle, password_fields[i], &password)) {
3785 /* check it was set right */
3786 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3792 q.in.user_handle = user_handle;
3796 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
3797 if (!NT_STATUS_IS_OK(status)) {
3798 torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
3799 q.in.level, nt_errstr(status));
3802 uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
3803 if ((info->info5.acct_flags) != expected_flags) {
3804 torture_warning(tctx, "QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
3805 info->info5.acct_flags,
3808 if (!torture_setting_bool(tctx, "samba3", false)) {
3812 if (info->info5.rid != rid) {
3813 torture_warning(tctx, "QuerUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
3814 info->info5.rid, rid);
3821 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
3823 /* test last password change timestamp behaviour */
3824 if (!test_SetPassword_pwdlastset(p, tctx, base_acct_flags,
3826 user_handle, &password,
3827 machine_credentials)) {
3832 torture_comment(tctx, "pwdLastSet test succeeded\n");
3834 torture_warning(tctx, "pwdLastSet test failed\n");
3839 case TORTURE_SAMR_USER_PRIVILEGES: {
3841 struct dcerpc_pipe *lp;
3842 struct policy_handle *lsa_handle;
3844 status = torture_rpc_connection(tctx, &lp, &ndr_table_lsarpc);
3845 torture_assert_ntstatus_ok(tctx, status, "Failed to open LSA pipe");
3847 if (!test_lsa_OpenPolicy2(lp, tctx, &lsa_handle)) {
3851 if (!test_DeleteUser_with_privs(p, lp, tctx,
3852 domain_handle, lsa_handle, user_handle,
3854 machine_credentials)) {
3858 if (!test_lsa_Close(lp, tctx, lsa_handle)) {
3863 torture_warning(tctx, "privileged user delete test failed\n");
3868 case TORTURE_SAMR_OTHER:
3869 /* We just need the account to exist */
3875 static bool test_alias_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
3876 struct policy_handle *alias_handle,
3877 const struct dom_sid *domain_sid)
3881 if (!torture_setting_bool(tctx, "samba3", false)) {
3882 if (!test_QuerySecurity(p, tctx, alias_handle)) {
3887 if (!test_QueryAliasInfo(p, tctx, alias_handle)) {
3891 if (!test_SetAliasInfo(p, tctx, alias_handle)) {
3895 if (!test_AddMemberToAlias(p, tctx, alias_handle, domain_sid)) {
3899 if (torture_setting_bool(tctx, "samba3", false) ||
3900 torture_setting_bool(tctx, "samba4", false)) {
3901 torture_comment(tctx, "skipping MultipleMembers Alias tests against Samba\n");
3905 if (!test_AddMultipleMembersToAlias(p, tctx, alias_handle)) {
3913 static bool test_DeleteUser(struct dcerpc_pipe *p, struct torture_context *tctx,
3914 struct policy_handle *user_handle)
3916 struct samr_DeleteUser d;
3918 torture_comment(tctx, "Testing DeleteUser\n");
3920 d.in.user_handle = user_handle;
3921 d.out.user_handle = user_handle;
3923 status = dcerpc_samr_DeleteUser(p, tctx, &d);
3924 torture_assert_ntstatus_ok(tctx, status, "DeleteUser");
3929 bool test_DeleteUser_byname(struct dcerpc_pipe *p,
3930 struct torture_context *tctx,
3931 struct policy_handle *handle, const char *name)
3934 struct samr_DeleteUser d;
3935 struct policy_handle user_handle;
3938 status = test_LookupName(p, tctx, handle, name, &rid);
3939 if (!NT_STATUS_IS_OK(status)) {
3943 status = test_OpenUser_byname(p, tctx, handle, name, &user_handle);
3944 if (!NT_STATUS_IS_OK(status)) {
3948 d.in.user_handle = &user_handle;
3949 d.out.user_handle = &user_handle;
3950 status = dcerpc_samr_DeleteUser(p, tctx, &d);
3951 if (!NT_STATUS_IS_OK(status)) {
3958 torture_warning(tctx, "DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
3963 static bool test_DeleteGroup_byname(struct dcerpc_pipe *p,
3964 struct torture_context *tctx,
3965 struct policy_handle *handle, const char *name)
3968 struct samr_OpenGroup r;
3969 struct samr_DeleteDomainGroup d;
3970 struct policy_handle group_handle;
3973 status = test_LookupName(p, tctx, handle, name, &rid);
3974 if (!NT_STATUS_IS_OK(status)) {
3978 r.in.domain_handle = handle;
3979 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3981 r.out.group_handle = &group_handle;
3982 status = dcerpc_samr_OpenGroup(p, tctx, &r);
3983 if (!NT_STATUS_IS_OK(status)) {
3987 d.in.group_handle = &group_handle;
3988 d.out.group_handle = &group_handle;
3989 status = dcerpc_samr_DeleteDomainGroup(p, tctx, &d);
3990 if (!NT_STATUS_IS_OK(status)) {
3997 torture_warning(tctx, "DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
4002 static bool test_DeleteAlias_byname(struct dcerpc_pipe *p,
4003 struct torture_context *tctx,
4004 struct policy_handle *domain_handle,
4008 struct samr_OpenAlias r;
4009 struct samr_DeleteDomAlias d;
4010 struct policy_handle alias_handle;
4013 torture_comment(tctx, "testing DeleteAlias_byname\n");
4015 status = test_LookupName(p, tctx, domain_handle, name, &rid);
4016 if (!NT_STATUS_IS_OK(status)) {
4020 r.in.domain_handle = domain_handle;
4021 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4023 r.out.alias_handle = &alias_handle;
4024 status = dcerpc_samr_OpenAlias(p, tctx, &r);
4025 if (!NT_STATUS_IS_OK(status)) {
4029 d.in.alias_handle = &alias_handle;
4030 d.out.alias_handle = &alias_handle;
4031 status = dcerpc_samr_DeleteDomAlias(p, tctx, &d);
4032 if (!NT_STATUS_IS_OK(status)) {
4039 torture_warning(tctx, "DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
4043 static bool test_DeleteAlias(struct dcerpc_pipe *p,
4044 struct torture_context *tctx,
4045 struct policy_handle *alias_handle)
4047 struct samr_DeleteDomAlias d;
4051 torture_comment(tctx, "Testing DeleteAlias\n");
4053 d.in.alias_handle = alias_handle;
4054 d.out.alias_handle = alias_handle;
4056 status = dcerpc_samr_DeleteDomAlias(p, tctx, &d);
4057 if (!NT_STATUS_IS_OK(status)) {
4058 torture_warning(tctx, "DeleteAlias failed - %s\n", nt_errstr(status));
4065 static bool test_CreateAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
4066 struct policy_handle *domain_handle,
4067 const char *alias_name,
4068 struct policy_handle *alias_handle,
4069 const struct dom_sid *domain_sid,
4073 struct samr_CreateDomAlias r;
4074 struct lsa_String name;
4078 init_lsa_String(&name, alias_name);
4079 r.in.domain_handle = domain_handle;
4080 r.in.alias_name = &name;
4081 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4082 r.out.alias_handle = alias_handle;
4085 torture_comment(tctx, "Testing CreateAlias (%s)\n", r.in.alias_name->string);
4087 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
4089 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
4090 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
4091 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.alias_name->string);
4094 torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.alias_name->string,
4100 if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
4101 if (!test_DeleteAlias_byname(p, tctx, domain_handle, r.in.alias_name->string)) {
4104 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
4107 if (!NT_STATUS_IS_OK(status)) {
4108 torture_warning(tctx, "CreateAlias failed - %s\n", nt_errstr(status));
4116 if (!test_alias_ops(p, tctx, alias_handle, domain_sid)) {
4123 static bool test_ChangePassword(struct dcerpc_pipe *p,
4124 struct torture_context *tctx,
4125 const char *acct_name,
4126 struct policy_handle *domain_handle, char **password)
4134 if (!test_ChangePasswordUser(p, tctx, acct_name, domain_handle, password)) {
4138 if (!test_ChangePasswordUser2(p, tctx, acct_name, password, 0, true)) {
4142 if (!test_OemChangePasswordUser2(p, tctx, acct_name, domain_handle, password)) {
4146 /* test what happens when setting the old password again */
4147 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, *password, 0, true)) {
4152 char simple_pass[9];
4153 char *v = generate_random_str(tctx, 1);
4155 ZERO_STRUCT(simple_pass);
4156 memset(simple_pass, *v, sizeof(simple_pass) - 1);
4158 /* test what happens when picking a simple password */
4159 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, simple_pass, 0, true)) {
4164 /* set samr_SetDomainInfo level 1 with min_length 5 */
4166 struct samr_QueryDomainInfo r;
4167 union samr_DomainInfo *info = NULL;
4168 struct samr_SetDomainInfo s;
4169 uint16_t len_old, len;
4170 uint32_t pwd_prop_old;
4171 int64_t min_pwd_age_old;
4176 r.in.domain_handle = domain_handle;
4180 torture_comment(tctx, "testing samr_QueryDomainInfo level 1\n");
4181 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
4182 if (!NT_STATUS_IS_OK(status)) {
4186 s.in.domain_handle = domain_handle;
4190 /* remember the old min length, so we can reset it */
4191 len_old = s.in.info->info1.min_password_length;
4192 s.in.info->info1.min_password_length = len;
4193 pwd_prop_old = s.in.info->info1.password_properties;
4194 /* turn off password complexity checks for this test */
4195 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
4197 min_pwd_age_old = s.in.info->info1.min_password_age;
4198 s.in.info->info1.min_password_age = 0;
4200 torture_comment(tctx, "testing samr_SetDomainInfo level 1\n");
4201 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
4202 if (!NT_STATUS_IS_OK(status)) {
4206 torture_comment(tctx, "calling test_ChangePasswordUser3 with too short password\n");
4208 if (!test_ChangePasswordUser3(p, tctx, acct_name, len - 1, password, NULL, 0, true)) {
4212 s.in.info->info1.min_password_length = len_old;
4213 s.in.info->info1.password_properties = pwd_prop_old;
4214 s.in.info->info1.min_password_age = min_pwd_age_old;
4216 torture_comment(tctx, "testing samr_SetDomainInfo level 1\n");
4217 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
4218 if (!NT_STATUS_IS_OK(status)) {
4226 struct samr_OpenUser r;
4227 struct samr_QueryUserInfo q;
4228 union samr_UserInfo *info;
4229 struct samr_LookupNames n;
4230 struct policy_handle user_handle;
4231 struct samr_Ids rids, types;
4233 n.in.domain_handle = domain_handle;
4235 n.in.names = talloc_array(tctx, struct lsa_String, 1);
4236 n.in.names[0].string = acct_name;
4238 n.out.types = &types;
4240 status = dcerpc_samr_LookupNames(p, tctx, &n);
4241 if (!NT_STATUS_IS_OK(status)) {
4242 torture_warning(tctx, "LookupNames failed - %s\n", nt_errstr(status));
4246 r.in.domain_handle = domain_handle;
4247 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4248 r.in.rid = n.out.rids->ids[0];
4249 r.out.user_handle = &user_handle;
4251 status = dcerpc_samr_OpenUser(p, tctx, &r);
4252 if (!NT_STATUS_IS_OK(status)) {
4253 torture_warning(tctx, "OpenUser(%u) failed - %s\n", n.out.rids->ids[0], nt_errstr(status));
4257 q.in.user_handle = &user_handle;
4261 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
4262 if (!NT_STATUS_IS_OK(status)) {
4263 torture_warning(tctx, "QueryUserInfo failed - %s\n", nt_errstr(status));
4267 torture_comment(tctx, "calling test_ChangePasswordUser3 with too early password change\n");
4269 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL,
4270 info->info5.last_password_change, true)) {
4275 /* we change passwords twice - this has the effect of verifying
4276 they were changed correctly for the final call */
4277 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
4281 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
4288 static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
4289 struct policy_handle *domain_handle,
4290 const char *user_name,
4291 struct policy_handle *user_handle_out,
4292 struct dom_sid *domain_sid,
4293 enum torture_samr_choice which_ops,
4294 struct cli_credentials *machine_credentials,
4298 TALLOC_CTX *user_ctx;
4301 struct samr_CreateUser r;
4302 struct samr_QueryUserInfo q;
4303 union samr_UserInfo *info;
4304 struct samr_DeleteUser d;
4307 /* This call creates a 'normal' account - check that it really does */
4308 const uint32_t acct_flags = ACB_NORMAL;
4309 struct lsa_String name;
4312 struct policy_handle user_handle;
4313 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
4314 init_lsa_String(&name, user_name);
4316 r.in.domain_handle = domain_handle;
4317 r.in.account_name = &name;
4318 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4319 r.out.user_handle = &user_handle;
4322 torture_comment(tctx, "Testing CreateUser(%s)\n", r.in.account_name->string);
4324 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
4326 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
4327 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
4328 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.account_name->string);
4331 torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
4337 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
4338 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
4339 talloc_free(user_ctx);
4342 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
4345 if (!NT_STATUS_IS_OK(status)) {
4346 talloc_free(user_ctx);
4347 torture_warning(tctx, "CreateUser failed - %s\n", nt_errstr(status));
4352 if (user_handle_out) {
4353 *user_handle_out = user_handle;
4359 q.in.user_handle = &user_handle;
4363 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
4364 if (!NT_STATUS_IS_OK(status)) {
4365 torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
4366 q.in.level, nt_errstr(status));
4369 if ((info->info16.acct_flags & acct_flags) != acct_flags) {
4370 torture_warning(tctx, "QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
4371 info->info16.acct_flags,
4377 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
4378 domain_sid, acct_flags, name.string, which_ops,
4379 machine_credentials)) {
4383 if (user_handle_out) {
4384 *user_handle_out = user_handle;
4386 torture_comment(tctx, "Testing DeleteUser (createuser test)\n");
4388 d.in.user_handle = &user_handle;
4389 d.out.user_handle = &user_handle;
4391 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
4392 if (!NT_STATUS_IS_OK(status)) {
4393 torture_warning(tctx, "DeleteUser failed - %s\n", nt_errstr(status));
4400 talloc_free(user_ctx);
4406 static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
4407 struct policy_handle *domain_handle,
4408 struct dom_sid *domain_sid,
4409 enum torture_samr_choice which_ops,
4410 struct cli_credentials *machine_credentials)
4413 struct samr_CreateUser2 r;
4414 struct samr_QueryUserInfo q;
4415 union samr_UserInfo *info;
4416 struct samr_DeleteUser d;
4417 struct policy_handle user_handle;
4419 struct lsa_String name;
4424 uint32_t acct_flags;
4425 const char *account_name;
4427 } account_types[] = {
4428 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
4429 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
4430 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
4431 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
4432 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
4433 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
4434 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
4435 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
4436 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
4437 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_ACCESS_DENIED },
4438 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
4439 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
4440 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
4441 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
4442 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
4445 for (i = 0; account_types[i].account_name; i++) {
4446 TALLOC_CTX *user_ctx;
4447 uint32_t acct_flags = account_types[i].acct_flags;
4448 uint32_t access_granted;
4449 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
4450 init_lsa_String(&name, account_types[i].account_name);
4452 r.in.domain_handle = domain_handle;
4453 r.in.account_name = &name;
4454 r.in.acct_flags = acct_flags;
4455 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4456 r.out.user_handle = &user_handle;
4457 r.out.access_granted = &access_granted;
4460 torture_comment(tctx, "Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
4462 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
4464 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
4465 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
4466 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.account_name->string);
4469 torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
4476 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
4477 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
4478 talloc_free(user_ctx);
4482 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
4485 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
4486 torture_warning(tctx, "CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
4487 nt_errstr(status), nt_errstr(account_types[i].nt_status));
4491 if (NT_STATUS_IS_OK(status)) {
4492 q.in.user_handle = &user_handle;
4496 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
4497 if (!NT_STATUS_IS_OK(status)) {
4498 torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
4499 q.in.level, nt_errstr(status));
4502 uint32_t expected_flags = (acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
4503 if (acct_flags == ACB_NORMAL) {
4504 expected_flags |= ACB_PW_EXPIRED;
4506 if ((info->info5.acct_flags) != expected_flags) {
4507 torture_warning(tctx, "QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
4508 info->info5.acct_flags,
4512 switch (acct_flags) {
4514 if (info->info5.primary_gid != DOMAIN_RID_DCS) {
4515 torture_warning(tctx, "QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n",
4516 DOMAIN_RID_DCS, info->info5.primary_gid);
4521 if (info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
4522 torture_warning(tctx, "QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
4523 DOMAIN_RID_DOMAIN_MEMBERS, info->info5.primary_gid);
4528 if (info->info5.primary_gid != DOMAIN_RID_USERS) {
4529 torture_warning(tctx, "QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n",
4530 DOMAIN_RID_USERS, info->info5.primary_gid);
4537 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
4538 domain_sid, acct_flags, name.string, which_ops,
4539 machine_credentials)) {
4543 if (!policy_handle_empty(&user_handle)) {
4544 torture_comment(tctx, "Testing DeleteUser (createuser2 test)\n");
4546 d.in.user_handle = &user_handle;
4547 d.out.user_handle = &user_handle;
4549 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
4550 if (!NT_STATUS_IS_OK(status)) {
4551 torture_warning(tctx, "DeleteUser failed - %s\n", nt_errstr(status));
4556 talloc_free(user_ctx);
4562 static bool test_QueryAliasInfo(struct dcerpc_pipe *p,
4563 struct torture_context *tctx,
4564 struct policy_handle *handle)
4567 struct samr_QueryAliasInfo r;
4568 union samr_AliasInfo *info;
4569 uint16_t levels[] = {1, 2, 3};
4573 for (i=0;i<ARRAY_SIZE(levels);i++) {
4574 torture_comment(tctx, "Testing QueryAliasInfo level %u\n", levels[i]);
4576 r.in.alias_handle = handle;
4577 r.in.level = levels[i];
4580 status = dcerpc_samr_QueryAliasInfo(p, tctx, &r);
4581 if (!NT_STATUS_IS_OK(status)) {
4582 torture_warning(tctx, "QueryAliasInfo level %u failed - %s\n",
4583 levels[i], nt_errstr(status));
4591 static bool test_QueryGroupInfo(struct dcerpc_pipe *p,
4592 struct torture_context *tctx,
4593 struct policy_handle *handle)
4596 struct samr_QueryGroupInfo r;
4597 union samr_GroupInfo *info;
4598 uint16_t levels[] = {1, 2, 3, 4, 5};
4602 for (i=0;i<ARRAY_SIZE(levels);i++) {
4603 torture_comment(tctx, "Testing QueryGroupInfo level %u\n", levels[i]);
4605 r.in.group_handle = handle;
4606 r.in.level = levels[i];
4609 status = dcerpc_samr_QueryGroupInfo(p, tctx, &r);
4610 if (!NT_STATUS_IS_OK(status)) {
4611 torture_warning(tctx, "QueryGroupInfo level %u failed - %s\n",
4612 levels[i], nt_errstr(status));
4620 static bool test_QueryGroupMember(struct dcerpc_pipe *p,
4621 struct torture_context *tctx,
4622 struct policy_handle *handle)
4625 struct samr_QueryGroupMember r;
4626 struct samr_RidTypeArray *rids = NULL;
4629 torture_comment(tctx, "Testing QueryGroupMember\n");
4631 r.in.group_handle = handle;
4634 status = dcerpc_samr_QueryGroupMember(p, tctx, &r);
4635 if (!NT_STATUS_IS_OK(status)) {
4636 torture_warning(tctx, "QueryGroupInfo failed - %s\n", nt_errstr(status));
4644 static bool test_SetGroupInfo(struct dcerpc_pipe *p,
4645 struct torture_context *tctx,
4646 struct policy_handle *handle)
4649 struct samr_QueryGroupInfo r;
4650 union samr_GroupInfo *info;
4651 struct samr_SetGroupInfo s;
4652 uint16_t levels[] = {1, 2, 3, 4};
4653 uint16_t set_ok[] = {0, 1, 1, 1};
4657 for (i=0;i<ARRAY_SIZE(levels);i++) {
4658 torture_comment(tctx, "Testing QueryGroupInfo level %u\n", levels[i]);
4660 r.in.group_handle = handle;
4661 r.in.level = levels[i];
4664 status = dcerpc_samr_QueryGroupInfo(p, tctx, &r);
4665 if (!NT_STATUS_IS_OK(status)) {
4666 torture_warning(tctx, "QueryGroupInfo level %u failed - %s\n",
4667 levels[i], nt_errstr(status));
4671 torture_comment(tctx, "Testing SetGroupInfo level %u\n", levels[i]);
4673 s.in.group_handle = handle;
4674 s.in.level = levels[i];
4675 s.in.info = *r.out.info;
4678 /* disabled this, as it changes the name only from the point of view of samr,
4679 but leaves the name from the point of view of w2k3 internals (and ldap). This means
4680 the name is still reserved, so creating the old name fails, but deleting by the old name
4682 if (s.in.level == 2) {
4683 init_lsa_String(&s.in.info->string, "NewName");
4687 if (s.in.level == 4) {
4688 init_lsa_String(&s.in.info->description, "test description");
4691 status = dcerpc_samr_SetGroupInfo(p, tctx, &s);
4693 if (!NT_STATUS_IS_OK(status)) {
4694 torture_warning(tctx, "SetGroupInfo level %u failed - %s\n",
4695 r.in.level, nt_errstr(status));
4700 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
4701 torture_warning(tctx, "SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
4702 r.in.level, nt_errstr(status));
4712 static bool test_QueryUserInfo(struct dcerpc_pipe *p,
4713 struct torture_context *tctx,
4714 struct policy_handle *handle)
4717 struct samr_QueryUserInfo r;
4718 union samr_UserInfo *info;
4719 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
4720 11, 12, 13, 14, 16, 17, 20, 21};
4724 for (i=0;i<ARRAY_SIZE(levels);i++) {
4725 torture_comment(tctx, "Testing QueryUserInfo level %u\n", levels[i]);
4727 r.in.user_handle = handle;
4728 r.in.level = levels[i];
4731 status = dcerpc_samr_QueryUserInfo(p, tctx, &r);
4732 if (!NT_STATUS_IS_OK(status)) {
4733 torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
4734 levels[i], nt_errstr(status));
4742 static bool test_QueryUserInfo2(struct dcerpc_pipe *p,
4743 struct torture_context *tctx,
4744 struct policy_handle *handle)
4747 struct samr_QueryUserInfo2 r;
4748 union samr_UserInfo *info;
4749 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
4750 11, 12, 13, 14, 16, 17, 20, 21};
4754 for (i=0;i<ARRAY_SIZE(levels);i++) {
4755 torture_comment(tctx, "Testing QueryUserInfo2 level %u\n", levels[i]);
4757 r.in.user_handle = handle;
4758 r.in.level = levels[i];
4761 status = dcerpc_samr_QueryUserInfo2(p, tctx, &r);
4762 if (!NT_STATUS_IS_OK(status)) {
4763 torture_warning(tctx, "QueryUserInfo2 level %u failed - %s\n",
4764 levels[i], nt_errstr(status));
4772 static bool test_OpenUser(struct dcerpc_pipe *p,
4773 struct torture_context *tctx,
4774 struct policy_handle *handle, uint32_t rid)
4777 struct samr_OpenUser r;
4778 struct policy_handle user_handle;
4781 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
4783 r.in.domain_handle = handle;
4784 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4786 r.out.user_handle = &user_handle;
4788 status = dcerpc_samr_OpenUser(p, tctx, &r);
4789 if (!NT_STATUS_IS_OK(status)) {
4790 torture_warning(tctx, "OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
4794 if (!test_QuerySecurity(p, tctx, &user_handle)) {
4798 if (!test_QueryUserInfo(p, tctx, &user_handle)) {
4802 if (!test_QueryUserInfo2(p, tctx, &user_handle)) {
4806 if (!test_GetUserPwInfo(p, tctx, &user_handle)) {
4810 if (!test_GetGroupsForUser(p,tctx, &user_handle)) {
4814 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
4821 static bool test_OpenGroup(struct dcerpc_pipe *p,
4822 struct torture_context *tctx,
4823 struct policy_handle *handle, uint32_t rid)
4826 struct samr_OpenGroup r;
4827 struct policy_handle group_handle;
4830 torture_comment(tctx, "Testing OpenGroup(%u)\n", rid);
4832 r.in.domain_handle = handle;
4833 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4835 r.out.group_handle = &group_handle;
4837 status = dcerpc_samr_OpenGroup(p, tctx, &r);
4838 if (!NT_STATUS_IS_OK(status)) {
4839 torture_warning(tctx, "OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
4843 if (!torture_setting_bool(tctx, "samba3", false)) {
4844 if (!test_QuerySecurity(p, tctx, &group_handle)) {
4849 if (!test_QueryGroupInfo(p, tctx, &group_handle)) {
4853 if (!test_QueryGroupMember(p, tctx, &group_handle)) {
4857 if (!test_samr_handle_Close(p, tctx, &group_handle)) {
4864 static bool test_OpenAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
4865 struct policy_handle *handle, uint32_t rid)
4868 struct samr_OpenAlias r;
4869 struct policy_handle alias_handle;
4872 torture_comment(tctx, "Testing OpenAlias(%u)\n", rid);
4874 r.in.domain_handle = handle;
4875 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4877 r.out.alias_handle = &alias_handle;
4879 status = dcerpc_samr_OpenAlias(p, tctx, &r);
4880 if (!NT_STATUS_IS_OK(status)) {
4881 torture_warning(tctx, "OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
4885 if (!torture_setting_bool(tctx, "samba3", false)) {
4886 if (!test_QuerySecurity(p, tctx, &alias_handle)) {
4891 if (!test_QueryAliasInfo(p, tctx, &alias_handle)) {
4895 if (!test_GetMembersInAlias(p, tctx, &alias_handle)) {
4899 if (!test_samr_handle_Close(p, tctx, &alias_handle)) {
4906 static bool check_mask(struct dcerpc_pipe *p, struct torture_context *tctx,
4907 struct policy_handle *handle, uint32_t rid,
4908 uint32_t acct_flag_mask)
4911 struct samr_OpenUser r;
4912 struct samr_QueryUserInfo q;
4913 union samr_UserInfo *info;
4914 struct policy_handle user_handle;
4917 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
4919 r.in.domain_handle = handle;
4920 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4922 r.out.user_handle = &user_handle;
4924 status = dcerpc_samr_OpenUser(p, tctx, &r);
4925 if (!NT_STATUS_IS_OK(status)) {
4926 torture_warning(tctx, "OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
4930 q.in.user_handle = &user_handle;
4934 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
4935 if (!NT_STATUS_IS_OK(status)) {
4936 torture_warning(tctx, "QueryUserInfo level 16 failed - %s\n",
4940 if ((acct_flag_mask & info->info16.acct_flags) == 0) {
4941 torture_warning(tctx, "Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
4942 acct_flag_mask, info->info16.acct_flags, rid);
4947 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
4954 static bool test_EnumDomainUsers_all(struct dcerpc_pipe *p,
4955 struct torture_context *tctx,
4956 struct policy_handle *handle)
4958 NTSTATUS status = STATUS_MORE_ENTRIES;
4959 struct samr_EnumDomainUsers r;
4960 uint32_t mask, resume_handle=0;
4963 struct samr_LookupNames n;
4964 struct samr_LookupRids lr ;
4965 struct lsa_Strings names;
4966 struct samr_Ids rids, types;
4967 struct samr_SamArray *sam = NULL;
4968 uint32_t num_entries = 0;
4970 uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
4971 ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
4972 ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
4975 torture_comment(tctx, "Testing EnumDomainUsers\n");
4977 for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
4978 r.in.domain_handle = handle;
4979 r.in.resume_handle = &resume_handle;
4980 r.in.acct_flags = mask = masks[mask_idx];
4981 r.in.max_size = (uint32_t)-1;
4982 r.out.resume_handle = &resume_handle;
4983 r.out.num_entries = &num_entries;
4986 status = dcerpc_samr_EnumDomainUsers(p, tctx, &r);
4987 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
4988 !NT_STATUS_IS_OK(status)) {
4989 torture_warning(tctx, "EnumDomainUsers failed - %s\n", nt_errstr(status));
4993 torture_assert(tctx, sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
4995 if (sam->count == 0) {
4999 for (i=0;i<sam->count;i++) {
5001 if (!check_mask(p, tctx, handle, sam->entries[i].idx, mask)) {
5004 } else if (!test_OpenUser(p, tctx, handle, sam->entries[i].idx)) {
5010 torture_comment(tctx, "Testing LookupNames\n");
5011 n.in.domain_handle = handle;
5012 n.in.num_names = sam->count;
5013 n.in.names = talloc_array(tctx, struct lsa_String, sam->count);
5015 n.out.types = &types;
5016 for (i=0;i<sam->count;i++) {
5017 n.in.names[i].string = sam->entries[i].name.string;
5019 status = dcerpc_samr_LookupNames(p, tctx, &n);
5020 if (!NT_STATUS_IS_OK(status)) {
5021 torture_warning(tctx, "LookupNames failed - %s\n", nt_errstr(status));
5026 torture_comment(tctx, "Testing LookupRids\n");
5027 lr.in.domain_handle = handle;
5028 lr.in.num_rids = sam->count;
5029 lr.in.rids = talloc_array(tctx, uint32_t, sam->count);
5030 lr.out.names = &names;
5031 lr.out.types = &types;
5032 for (i=0;i<sam->count;i++) {
5033 lr.in.rids[i] = sam->entries[i].idx;
5035 status = dcerpc_samr_LookupRids(p, tctx, &lr);
5036 torture_assert_ntstatus_ok(tctx, status, "LookupRids");
5042 try blasting the server with a bunch of sync requests
5044 static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, struct torture_context *tctx,
5045 struct policy_handle *handle)
5048 struct samr_EnumDomainUsers r;
5049 uint32_t resume_handle=0;
5051 #define ASYNC_COUNT 100
5052 struct rpc_request *req[ASYNC_COUNT];
5054 if (!torture_setting_bool(tctx, "dangerous", false)) {
5055 torture_skip(tctx, "samr async test disabled - enable dangerous tests to use\n");
5058 torture_comment(tctx, "Testing EnumDomainUsers_async\n");
5060 r.in.domain_handle = handle;
5061 r.in.resume_handle = &resume_handle;
5062 r.in.acct_flags = 0;
5063 r.in.max_size = (uint32_t)-1;
5064 r.out.resume_handle = &resume_handle;
5066 for (i=0;i<ASYNC_COUNT;i++) {
5067 req[i] = dcerpc_samr_EnumDomainUsers_send(p, tctx, &r);
5070 for (i=0;i<ASYNC_COUNT;i++) {
5071 status = dcerpc_ndr_request_recv(req[i]);
5072 if (!NT_STATUS_IS_OK(status)) {
5073 torture_warning(tctx, "EnumDomainUsers[%d] failed - %s\n",
5074 i, nt_errstr(status));
5079 torture_comment(tctx, "%d async requests OK\n", i);
5084 static bool test_EnumDomainGroups_all(struct dcerpc_pipe *p,
5085 struct torture_context *tctx,
5086 struct policy_handle *handle)
5089 struct samr_EnumDomainGroups r;
5090 uint32_t resume_handle=0;
5091 struct samr_SamArray *sam = NULL;
5092 uint32_t num_entries = 0;
5096 torture_comment(tctx, "Testing EnumDomainGroups\n");
5098 r.in.domain_handle = handle;
5099 r.in.resume_handle = &resume_handle;
5100 r.in.max_size = (uint32_t)-1;
5101 r.out.resume_handle = &resume_handle;
5102 r.out.num_entries = &num_entries;
5105 status = dcerpc_samr_EnumDomainGroups(p, tctx, &r);
5106 if (!NT_STATUS_IS_OK(status)) {
5107 torture_warning(tctx, "EnumDomainGroups failed - %s\n", nt_errstr(status));
5115 for (i=0;i<sam->count;i++) {
5116 if (!test_OpenGroup(p, tctx, handle, sam->entries[i].idx)) {
5124 static bool test_EnumDomainAliases_all(struct dcerpc_pipe *p,
5125 struct torture_context *tctx,
5126 struct policy_handle *handle)
5129 struct samr_EnumDomainAliases r;
5130 uint32_t resume_handle=0;
5131 struct samr_SamArray *sam = NULL;
5132 uint32_t num_entries = 0;
5136 torture_comment(tctx, "Testing EnumDomainAliases\n");
5138 r.in.domain_handle = handle;
5139 r.in.resume_handle = &resume_handle;
5140 r.in.max_size = (uint32_t)-1;
5142 r.out.num_entries = &num_entries;
5143 r.out.resume_handle = &resume_handle;
5145 status = dcerpc_samr_EnumDomainAliases(p, tctx, &r);
5146 if (!NT_STATUS_IS_OK(status)) {
5147 torture_warning(tctx, "EnumDomainAliases failed - %s\n", nt_errstr(status));
5155 for (i=0;i<sam->count;i++) {
5156 if (!test_OpenAlias(p, tctx, handle, sam->entries[i].idx)) {
5164 static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p,
5165 struct torture_context *tctx,
5166 struct policy_handle *handle)
5169 struct samr_GetDisplayEnumerationIndex r;
5171 uint16_t levels[] = {1, 2, 3, 4, 5};
5172 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
5173 struct lsa_String name;
5177 for (i=0;i<ARRAY_SIZE(levels);i++) {
5178 torture_comment(tctx, "Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
5180 init_lsa_String(&name, TEST_ACCOUNT_NAME);
5182 r.in.domain_handle = handle;
5183 r.in.level = levels[i];
5187 status = dcerpc_samr_GetDisplayEnumerationIndex(p, tctx, &r);
5190 !NT_STATUS_IS_OK(status) &&
5191 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
5192 torture_warning(tctx, "GetDisplayEnumerationIndex level %u failed - %s\n",
5193 levels[i], nt_errstr(status));
5197 init_lsa_String(&name, "zzzzzzzz");
5199 status = dcerpc_samr_GetDisplayEnumerationIndex(p, tctx, &r);
5201 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
5202 torture_warning(tctx, "GetDisplayEnumerationIndex level %u failed - %s\n",
5203 levels[i], nt_errstr(status));
5211 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p,
5212 struct torture_context *tctx,
5213 struct policy_handle *handle)
5216 struct samr_GetDisplayEnumerationIndex2 r;
5218 uint16_t levels[] = {1, 2, 3, 4, 5};
5219 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
5220 struct lsa_String name;
5224 for (i=0;i<ARRAY_SIZE(levels);i++) {
5225 torture_comment(tctx, "Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
5227 init_lsa_String(&name, TEST_ACCOUNT_NAME);
5229 r.in.domain_handle = handle;
5230 r.in.level = levels[i];
5234 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, tctx, &r);
5236 !NT_STATUS_IS_OK(status) &&
5237 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
5238 torture_warning(tctx, "GetDisplayEnumerationIndex2 level %u failed - %s\n",
5239 levels[i], nt_errstr(status));
5243 init_lsa_String(&name, "zzzzzzzz");
5245 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, tctx, &r);
5246 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
5247 torture_warning(tctx, "GetDisplayEnumerationIndex2 level %u failed - %s\n",
5248 levels[i], nt_errstr(status));
5256 #define STRING_EQUAL_QUERY(s1, s2, user) \
5257 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
5258 /* odd, but valid */ \
5259 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
5260 torture_warning(tctx, "%s mismatch for %s: %s != %s (%s)\n", \
5261 #s1, user.string, s1.string, s2.string, __location__); \
5264 #define INT_EQUAL_QUERY(s1, s2, user) \
5266 torture_warning(tctx, "%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
5267 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
5271 static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p,
5272 struct torture_context *tctx,
5273 struct samr_QueryDisplayInfo *querydisplayinfo,
5274 bool *seen_testuser)
5276 struct samr_OpenUser r;
5277 struct samr_QueryUserInfo q;
5278 union samr_UserInfo *info;
5279 struct policy_handle user_handle;
5282 r.in.domain_handle = querydisplayinfo->in.domain_handle;
5283 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5284 for (i = 0; ; i++) {
5285 switch (querydisplayinfo->in.level) {
5287 if (i >= querydisplayinfo->out.info->info1.count) {
5290 r.in.rid = querydisplayinfo->out.info->info1.entries[i].rid;
5293 if (i >= querydisplayinfo->out.info->info2.count) {
5296 r.in.rid = querydisplayinfo->out.info->info2.entries[i].rid;
5302 /* Not interested in validating just the account name */
5306 r.out.user_handle = &user_handle;
5308 switch (querydisplayinfo->in.level) {
5311 status = dcerpc_samr_OpenUser(p, tctx, &r);
5312 if (!NT_STATUS_IS_OK(status)) {
5313 torture_warning(tctx, "OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(status));
5318 q.in.user_handle = &user_handle;
5321 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
5322 if (!NT_STATUS_IS_OK(status)) {
5323 torture_warning(tctx, "QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(status));
5327 switch (querydisplayinfo->in.level) {
5329 if (seen_testuser && strcmp(info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
5330 *seen_testuser = true;
5332 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].full_name,
5333 info->info21.full_name, info->info21.account_name);
5334 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].account_name,
5335 info->info21.account_name, info->info21.account_name);
5336 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].description,
5337 info->info21.description, info->info21.account_name);
5338 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].rid,
5339 info->info21.rid, info->info21.account_name);
5340 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].acct_flags,
5341 info->info21.acct_flags, info->info21.account_name);
5345 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].account_name,
5346 info->info21.account_name, info->info21.account_name);
5347 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].description,
5348 info->info21.description, info->info21.account_name);
5349 INT_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].rid,
5350 info->info21.rid, info->info21.account_name);
5351 INT_EQUAL_QUERY((querydisplayinfo->out.info->info2.entries[i].acct_flags & ~ACB_NORMAL),
5352 info->info21.acct_flags, info->info21.account_name);
5354 if (!(querydisplayinfo->out.info->info2.entries[i].acct_flags & ACB_NORMAL)) {
5355 torture_warning(tctx, "Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
5356 info->info21.account_name.string);
5359 if (!(info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
5360 torture_warning(tctx, "Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
5361 info->info21.account_name.string,
5362 querydisplayinfo->out.info->info2.entries[i].acct_flags,
5363 info->info21.acct_flags);
5370 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
5377 static bool test_QueryDisplayInfo(struct dcerpc_pipe *p,
5378 struct torture_context *tctx,
5379 struct policy_handle *handle)
5382 struct samr_QueryDisplayInfo r;
5383 struct samr_QueryDomainInfo dom_info;
5384 union samr_DomainInfo *info = NULL;
5386 uint16_t levels[] = {1, 2, 3, 4, 5};
5388 bool seen_testuser = false;
5389 uint32_t total_size;
5390 uint32_t returned_size;
5391 union samr_DispInfo disp_info;
5394 for (i=0;i<ARRAY_SIZE(levels);i++) {
5395 torture_comment(tctx, "Testing QueryDisplayInfo level %u\n", levels[i]);
5398 status = STATUS_MORE_ENTRIES;
5399 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
5400 r.in.domain_handle = handle;
5401 r.in.level = levels[i];
5402 r.in.max_entries = 2;
5403 r.in.buf_size = (uint32_t)-1;
5404 r.out.total_size = &total_size;
5405 r.out.returned_size = &returned_size;
5406 r.out.info = &disp_info;
5408 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &r);
5409 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(status)) {
5410 torture_warning(tctx, "QueryDisplayInfo level %u failed - %s\n",
5411 levels[i], nt_errstr(status));
5414 switch (r.in.level) {
5416 if (!test_each_DisplayInfo_user(p, tctx, &r, &seen_testuser)) {
5419 r.in.start_idx += r.out.info->info1.count;
5422 if (!test_each_DisplayInfo_user(p, tctx, &r, NULL)) {
5425 r.in.start_idx += r.out.info->info2.count;
5428 r.in.start_idx += r.out.info->info3.count;
5431 r.in.start_idx += r.out.info->info4.count;
5434 r.in.start_idx += r.out.info->info5.count;
5438 dom_info.in.domain_handle = handle;
5439 dom_info.in.level = 2;
5440 dom_info.out.info = &info;
5442 /* Check number of users returned is correct */
5443 status = dcerpc_samr_QueryDomainInfo(p, tctx, &dom_info);
5444 if (!NT_STATUS_IS_OK(status)) {
5445 torture_warning(tctx, "QueryDomainInfo level %u failed - %s\n",
5446 r.in.level, nt_errstr(status));
5450 switch (r.in.level) {
5453 if (info->general.num_users < r.in.start_idx) {
5454 torture_warning(tctx, "QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
5455 r.in.start_idx, info->general.num_groups,
5456 info->general.domain_name.string);
5459 if (!seen_testuser) {
5460 struct policy_handle user_handle;
5461 if (NT_STATUS_IS_OK(test_OpenUser_byname(p, tctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
5462 torture_warning(tctx, "Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
5463 info->general.domain_name.string);
5465 test_samr_handle_Close(p, tctx, &user_handle);
5471 if (info->general.num_groups != r.in.start_idx) {
5472 torture_warning(tctx, "QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
5473 r.in.start_idx, info->general.num_groups,
5474 info->general.domain_name.string);
5486 static bool test_QueryDisplayInfo2(struct dcerpc_pipe *p,
5487 struct torture_context *tctx,
5488 struct policy_handle *handle)
5491 struct samr_QueryDisplayInfo2 r;
5493 uint16_t levels[] = {1, 2, 3, 4, 5};
5495 uint32_t total_size;
5496 uint32_t returned_size;
5497 union samr_DispInfo info;
5499 for (i=0;i<ARRAY_SIZE(levels);i++) {
5500 torture_comment(tctx, "Testing QueryDisplayInfo2 level %u\n", levels[i]);
5502 r.in.domain_handle = handle;
5503 r.in.level = levels[i];
5505 r.in.max_entries = 1000;
5506 r.in.buf_size = (uint32_t)-1;
5507 r.out.total_size = &total_size;
5508 r.out.returned_size = &returned_size;
5511 status = dcerpc_samr_QueryDisplayInfo2(p, tctx, &r);
5512 if (!NT_STATUS_IS_OK(status)) {
5513 torture_warning(tctx, "QueryDisplayInfo2 level %u failed - %s\n",
5514 levels[i], nt_errstr(status));
5522 static bool test_QueryDisplayInfo3(struct dcerpc_pipe *p, struct torture_context *tctx,
5523 struct policy_handle *handle)
5526 struct samr_QueryDisplayInfo3 r;
5528 uint16_t levels[] = {1, 2, 3, 4, 5};
5530 uint32_t total_size;
5531 uint32_t returned_size;
5532 union samr_DispInfo info;
5534 for (i=0;i<ARRAY_SIZE(levels);i++) {
5535 torture_comment(tctx, "Testing QueryDisplayInfo3 level %u\n", levels[i]);
5537 r.in.domain_handle = handle;
5538 r.in.level = levels[i];
5540 r.in.max_entries = 1000;
5541 r.in.buf_size = (uint32_t)-1;
5542 r.out.total_size = &total_size;
5543 r.out.returned_size = &returned_size;
5546 status = dcerpc_samr_QueryDisplayInfo3(p, tctx, &r);
5547 if (!NT_STATUS_IS_OK(status)) {
5548 torture_warning(tctx, "QueryDisplayInfo3 level %u failed - %s\n",
5549 levels[i], nt_errstr(status));
5558 static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p,
5559 struct torture_context *tctx,
5560 struct policy_handle *handle)
5563 struct samr_QueryDisplayInfo r;
5565 uint32_t total_size;
5566 uint32_t returned_size;
5567 union samr_DispInfo info;
5569 torture_comment(tctx, "Testing QueryDisplayInfo continuation\n");
5571 r.in.domain_handle = handle;
5574 r.in.max_entries = 1;
5575 r.in.buf_size = (uint32_t)-1;
5576 r.out.total_size = &total_size;
5577 r.out.returned_size = &returned_size;
5581 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &r);
5582 if (NT_STATUS_IS_OK(status) && *r.out.returned_size != 0) {
5583 if (r.out.info->info1.entries[0].idx != r.in.start_idx + 1) {
5584 torture_warning(tctx, "expected idx %d but got %d\n",
5586 r.out.info->info1.entries[0].idx);
5590 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
5591 !NT_STATUS_IS_OK(status)) {
5592 torture_warning(tctx, "QueryDisplayInfo level %u failed - %s\n",
5593 r.in.level, nt_errstr(status));
5598 } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
5599 NT_STATUS_IS_OK(status)) &&
5600 *r.out.returned_size != 0);
5605 static bool test_QueryDomainInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
5606 struct policy_handle *handle)
5609 struct samr_QueryDomainInfo r;
5610 union samr_DomainInfo *info = NULL;
5611 struct samr_SetDomainInfo s;
5612 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
5613 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
5616 const char *domain_comment = talloc_asprintf(tctx,
5617 "Tortured by Samba4 RPC-SAMR: %s",
5618 timestring(tctx, time(NULL)));
5620 s.in.domain_handle = handle;
5622 s.in.info = talloc(tctx, union samr_DomainInfo);
5624 s.in.info->oem.oem_information.string = domain_comment;
5625 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
5626 if (!NT_STATUS_IS_OK(status)) {
5627 torture_warning(tctx, "SetDomainInfo level %u (set comment) failed - %s\n",
5628 s.in.level, nt_errstr(status));
5632 for (i=0;i<ARRAY_SIZE(levels);i++) {
5633 torture_comment(tctx, "Testing QueryDomainInfo level %u\n", levels[i]);
5635 r.in.domain_handle = handle;
5636 r.in.level = levels[i];
5639 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
5640 if (!NT_STATUS_IS_OK(status)) {
5641 torture_warning(tctx, "QueryDomainInfo level %u failed - %s\n",
5642 r.in.level, nt_errstr(status));
5647 switch (levels[i]) {
5649 if (strcmp(info->general.oem_information.string, domain_comment) != 0) {
5650 torture_warning(tctx, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
5651 levels[i], info->general.oem_information.string, domain_comment);
5652 if (!torture_setting_bool(tctx, "samba3", false)) {
5656 if (!info->general.primary.string) {
5657 torture_warning(tctx, "QueryDomainInfo level %u returned no PDC name\n",
5660 } else if (info->general.role == SAMR_ROLE_DOMAIN_PDC) {
5661 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), info->general.primary.string) != 0) {
5662 torture_warning(tctx, "QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
5663 levels[i], info->general.primary.string, dcerpc_server_name(p));
5668 if (strcmp(info->oem.oem_information.string, domain_comment) != 0) {
5669 torture_warning(tctx, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
5670 levels[i], info->oem.oem_information.string, domain_comment);
5671 if (!torture_setting_bool(tctx, "samba3", false)) {
5677 if (!info->info6.primary.string) {
5678 torture_warning(tctx, "QueryDomainInfo level %u returned no PDC name\n",
5684 if (strcmp(info->general2.general.oem_information.string, domain_comment) != 0) {
5685 torture_warning(tctx, "QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
5686 levels[i], info->general2.general.oem_information.string, domain_comment);
5687 if (!torture_setting_bool(tctx, "samba3", false)) {
5694 torture_comment(tctx, "Testing SetDomainInfo level %u\n", levels[i]);
5696 s.in.domain_handle = handle;
5697 s.in.level = levels[i];
5700 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
5702 if (!NT_STATUS_IS_OK(status)) {
5703 torture_warning(tctx, "SetDomainInfo level %u failed - %s\n",
5704 r.in.level, nt_errstr(status));
5709 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
5710 torture_warning(tctx, "SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
5711 r.in.level, nt_errstr(status));
5717 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
5718 if (!NT_STATUS_IS_OK(status)) {
5719 torture_warning(tctx, "QueryDomainInfo level %u failed - %s\n",
5720 r.in.level, nt_errstr(status));
5730 static bool test_QueryDomainInfo2(struct dcerpc_pipe *p, struct torture_context *tctx,
5731 struct policy_handle *handle)
5734 struct samr_QueryDomainInfo2 r;
5735 union samr_DomainInfo *info = NULL;
5736 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
5740 for (i=0;i<ARRAY_SIZE(levels);i++) {
5741 torture_comment(tctx, "Testing QueryDomainInfo2 level %u\n", levels[i]);
5743 r.in.domain_handle = handle;
5744 r.in.level = levels[i];
5747 status = dcerpc_samr_QueryDomainInfo2(p, tctx, &r);
5748 if (!NT_STATUS_IS_OK(status)) {
5749 torture_warning(tctx, "QueryDomainInfo2 level %u failed - %s\n",
5750 r.in.level, nt_errstr(status));
5759 /* Test whether querydispinfo level 5 and enumdomgroups return the same
5760 set of group names. */
5761 static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx,
5762 struct policy_handle *handle)
5764 struct samr_EnumDomainGroups q1;
5765 struct samr_QueryDisplayInfo q2;
5767 uint32_t resume_handle=0;
5768 struct samr_SamArray *sam = NULL;
5769 uint32_t num_entries = 0;
5772 uint32_t total_size;
5773 uint32_t returned_size;
5774 union samr_DispInfo info;
5777 const char **names = NULL;
5779 torture_comment(tctx, "Testing coherency of querydispinfo vs enumdomgroups\n");
5781 q1.in.domain_handle = handle;
5782 q1.in.resume_handle = &resume_handle;
5784 q1.out.resume_handle = &resume_handle;
5785 q1.out.num_entries = &num_entries;
5788 status = STATUS_MORE_ENTRIES;
5789 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
5790 status = dcerpc_samr_EnumDomainGroups(p, tctx, &q1);
5792 if (!NT_STATUS_IS_OK(status) &&
5793 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
5796 for (i=0; i<*q1.out.num_entries; i++) {
5797 add_string_to_array(tctx,
5798 sam->entries[i].name.string,
5799 &names, &num_names);
5803 torture_assert_ntstatus_ok(tctx, status, "EnumDomainGroups");
5805 torture_assert(tctx, sam, "EnumDomainGroups failed to return sam");
5807 q2.in.domain_handle = handle;
5809 q2.in.start_idx = 0;
5810 q2.in.max_entries = 5;
5811 q2.in.buf_size = (uint32_t)-1;
5812 q2.out.total_size = &total_size;
5813 q2.out.returned_size = &returned_size;
5814 q2.out.info = &info;
5816 status = STATUS_MORE_ENTRIES;
5817 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
5818 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &q2);
5820 if (!NT_STATUS_IS_OK(status) &&
5821 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
5824 for (i=0; i<q2.out.info->info5.count; i++) {
5826 const char *name = q2.out.info->info5.entries[i].account_name.string;
5828 for (j=0; j<num_names; j++) {
5829 if (names[j] == NULL)
5831 if (strequal(names[j], name)) {
5839 torture_warning(tctx, "QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
5844 q2.in.start_idx += q2.out.info->info5.count;
5847 if (!NT_STATUS_IS_OK(status)) {
5848 torture_warning(tctx, "QueryDisplayInfo level 5 failed - %s\n",
5853 for (i=0; i<num_names; i++) {
5854 if (names[i] != NULL) {
5855 torture_warning(tctx, "EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
5864 static bool test_DeleteDomainGroup(struct dcerpc_pipe *p, struct torture_context *tctx,
5865 struct policy_handle *group_handle)
5867 struct samr_DeleteDomainGroup d;
5870 torture_comment(tctx, "Testing DeleteDomainGroup\n");
5872 d.in.group_handle = group_handle;
5873 d.out.group_handle = group_handle;
5875 status = dcerpc_samr_DeleteDomainGroup(p, tctx, &d);
5876 torture_assert_ntstatus_ok(tctx, status, "DeleteDomainGroup");
5881 static bool test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
5882 struct policy_handle *domain_handle)
5884 struct samr_TestPrivateFunctionsDomain r;
5888 torture_comment(tctx, "Testing TestPrivateFunctionsDomain\n");
5890 r.in.domain_handle = domain_handle;
5892 status = dcerpc_samr_TestPrivateFunctionsDomain(p, tctx, &r);
5893 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsDomain");
5898 static bool test_RidToSid(struct dcerpc_pipe *p, struct torture_context *tctx,
5899 struct dom_sid *domain_sid,
5900 struct policy_handle *domain_handle)
5902 struct samr_RidToSid r;
5905 struct dom_sid *calc_sid, *out_sid;
5906 int rids[] = { 0, 42, 512, 10200 };
5909 for (i=0;i<ARRAY_SIZE(rids);i++) {
5910 torture_comment(tctx, "Testing RidToSid\n");
5912 calc_sid = dom_sid_dup(tctx, domain_sid);
5913 r.in.domain_handle = domain_handle;
5915 r.out.sid = &out_sid;
5917 status = dcerpc_samr_RidToSid(p, tctx, &r);
5918 if (!NT_STATUS_IS_OK(status)) {
5919 torture_warning(tctx, "RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
5922 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
5924 if (!dom_sid_equal(calc_sid, out_sid)) {
5925 torture_warning(tctx, "RidToSid for %d failed - got %s, expected %s\n", rids[i],
5926 dom_sid_string(tctx, out_sid),
5927 dom_sid_string(tctx, calc_sid));
5936 static bool test_GetBootKeyInformation(struct dcerpc_pipe *p, struct torture_context *tctx,
5937 struct policy_handle *domain_handle)
5939 struct samr_GetBootKeyInformation r;
5942 uint32_t unknown = 0;
5944 torture_comment(tctx, "Testing GetBootKeyInformation\n");
5946 r.in.domain_handle = domain_handle;
5947 r.out.unknown = &unknown;
5949 status = dcerpc_samr_GetBootKeyInformation(p, tctx, &r);
5950 if (!NT_STATUS_IS_OK(status)) {
5951 /* w2k3 seems to fail this sometimes and pass it sometimes */
5952 torture_comment(tctx, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
5958 static bool test_AddGroupMember(struct dcerpc_pipe *p, struct torture_context *tctx,
5959 struct policy_handle *domain_handle,
5960 struct policy_handle *group_handle)
5963 struct samr_AddGroupMember r;
5964 struct samr_DeleteGroupMember d;
5965 struct samr_QueryGroupMember q;
5966 struct samr_RidTypeArray *rids = NULL;
5967 struct samr_SetMemberAttributesOfGroup s;
5969 bool found_member = false;
5972 status = test_LookupName(p, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
5973 torture_assert_ntstatus_ok(tctx, status, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME);
5975 r.in.group_handle = group_handle;
5977 r.in.flags = 0; /* ??? */
5979 torture_comment(tctx, "Testing AddGroupMember, QueryGroupMember and DeleteGroupMember\n");
5981 d.in.group_handle = group_handle;
5984 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
5985 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_NOT_IN_GROUP, status, "DeleteGroupMember");
5987 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5988 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
5990 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5991 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_IN_GROUP, status, "AddGroupMember");
5993 if (torture_setting_bool(tctx, "samba4", false) ||
5994 torture_setting_bool(tctx, "samba3", false)) {
5995 torture_comment(tctx, "skipping SetMemberAttributesOfGroup test against Samba\n");
5997 /* this one is quite strange. I am using random inputs in the
5998 hope of triggering an error that might give us a clue */
6000 s.in.group_handle = group_handle;
6001 s.in.unknown1 = random();
6002 s.in.unknown2 = random();
6004 status = dcerpc_samr_SetMemberAttributesOfGroup(p, tctx, &s);
6005 torture_assert_ntstatus_ok(tctx, status, "SetMemberAttributesOfGroup");
6008 q.in.group_handle = group_handle;
6011 status = dcerpc_samr_QueryGroupMember(p, tctx, &q);
6012 torture_assert_ntstatus_ok(tctx, status, "QueryGroupMember");
6013 torture_assert(tctx, rids, "QueryGroupMember did not fill in rids structure");
6015 for (i=0; i < rids->count; i++) {
6016 if (rids->rids[i] == rid) {
6017 found_member = true;
6021 torture_assert(tctx, found_member, "QueryGroupMember did not list newly added member");
6023 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
6024 torture_assert_ntstatus_ok(tctx, status, "DeleteGroupMember");
6027 found_member = false;
6029 status = dcerpc_samr_QueryGroupMember(p, tctx, &q);
6030 torture_assert_ntstatus_ok(tctx, status, "QueryGroupMember");
6031 torture_assert(tctx, rids, "QueryGroupMember did not fill in rids structure");
6033 for (i=0; i < rids->count; i++) {
6034 if (rids->rids[i] == rid) {
6035 found_member = true;
6039 torture_assert(tctx, !found_member, "QueryGroupMember does still list removed member");
6041 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
6042 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
6048 static bool test_CreateDomainGroup(struct dcerpc_pipe *p,
6049 struct torture_context *tctx,
6050 struct policy_handle *domain_handle,
6051 const char *group_name,
6052 struct policy_handle *group_handle,
6053 struct dom_sid *domain_sid,
6057 struct samr_CreateDomainGroup r;
6059 struct lsa_String name;
6062 init_lsa_String(&name, group_name);
6064 r.in.domain_handle = domain_handle;
6066 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6067 r.out.group_handle = group_handle;
6070 torture_comment(tctx, "Testing CreateDomainGroup(%s)\n", r.in.name->string);
6072 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
6074 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
6075 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
6076 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.name->string);
6079 torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.name->string,
6085 if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS)) {
6086 if (!test_DeleteGroup_byname(p, tctx, domain_handle, r.in.name->string)) {
6087 torture_warning(tctx, "CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
6091 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
6093 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
6094 if (!test_DeleteUser_byname(p, tctx, domain_handle, r.in.name->string)) {
6096 torture_warning(tctx, "CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
6100 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
6102 torture_assert_ntstatus_ok(tctx, status, "CreateDomainGroup");
6108 if (!test_AddGroupMember(p, tctx, domain_handle, group_handle)) {
6109 torture_warning(tctx, "CreateDomainGroup failed - %s\n", nt_errstr(status));
6113 if (!test_SetGroupInfo(p, tctx, group_handle)) {
6122 its not totally clear what this does. It seems to accept any sid you like.
6124 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p,
6125 struct torture_context *tctx,
6126 struct policy_handle *domain_handle)
6129 struct samr_RemoveMemberFromForeignDomain r;
6131 r.in.domain_handle = domain_handle;
6132 r.in.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-12-34-56-78");
6134 status = dcerpc_samr_RemoveMemberFromForeignDomain(p, tctx, &r);
6135 torture_assert_ntstatus_ok(tctx, status, "RemoveMemberFromForeignDomain");
6140 static bool test_EnumDomainUsers(struct dcerpc_pipe *p,
6141 struct torture_context *tctx,
6142 struct policy_handle *domain_handle,
6143 uint32_t *total_num_entries_p)
6146 struct samr_EnumDomainUsers r;
6147 uint32_t resume_handle = 0;
6148 uint32_t num_entries = 0;
6149 uint32_t total_num_entries = 0;
6150 struct samr_SamArray *sam;
6152 r.in.domain_handle = domain_handle;
6153 r.in.acct_flags = 0;
6154 r.in.max_size = (uint32_t)-1;
6155 r.in.resume_handle = &resume_handle;
6158 r.out.num_entries = &num_entries;
6159 r.out.resume_handle = &resume_handle;
6161 torture_comment(tctx, "Testing EnumDomainUsers\n");
6164 status = dcerpc_samr_EnumDomainUsers(p, tctx, &r);
6165 if (NT_STATUS_IS_ERR(status)) {
6166 torture_assert_ntstatus_ok(tctx, status,
6167 "failed to enumerate users");
6170 total_num_entries += num_entries;
6171 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
6173 if (total_num_entries_p) {
6174 *total_num_entries_p = total_num_entries;
6180 static bool test_EnumDomainGroups(struct dcerpc_pipe *p,
6181 struct torture_context *tctx,
6182 struct policy_handle *domain_handle,
6183 uint32_t *total_num_entries_p)
6186 struct samr_EnumDomainGroups r;
6187 uint32_t resume_handle = 0;
6188 uint32_t num_entries = 0;
6189 uint32_t total_num_entries = 0;
6190 struct samr_SamArray *sam;
6192 r.in.domain_handle = domain_handle;
6193 r.in.max_size = (uint32_t)-1;
6194 r.in.resume_handle = &resume_handle;
6197 r.out.num_entries = &num_entries;
6198 r.out.resume_handle = &resume_handle;
6200 torture_comment(tctx, "Testing EnumDomainGroups\n");
6203 status = dcerpc_samr_EnumDomainGroups(p, tctx, &r);
6204 if (NT_STATUS_IS_ERR(status)) {
6205 torture_assert_ntstatus_ok(tctx, status,
6206 "failed to enumerate groups");
6209 total_num_entries += num_entries;
6210 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
6212 if (total_num_entries_p) {
6213 *total_num_entries_p = total_num_entries;
6219 static bool test_EnumDomainAliases(struct dcerpc_pipe *p,
6220 struct torture_context *tctx,
6221 struct policy_handle *domain_handle,
6222 uint32_t *total_num_entries_p)
6225 struct samr_EnumDomainAliases r;
6226 uint32_t resume_handle = 0;
6227 uint32_t num_entries = 0;
6228 uint32_t total_num_entries = 0;
6229 struct samr_SamArray *sam;
6231 r.in.domain_handle = domain_handle;
6232 r.in.max_size = (uint32_t)-1;
6233 r.in.resume_handle = &resume_handle;
6236 r.out.num_entries = &num_entries;
6237 r.out.resume_handle = &resume_handle;
6239 torture_comment(tctx, "Testing EnumDomainAliases\n");
6242 status = dcerpc_samr_EnumDomainAliases(p, tctx, &r);
6243 if (NT_STATUS_IS_ERR(status)) {
6244 torture_assert_ntstatus_ok(tctx, status,
6245 "failed to enumerate aliases");
6248 total_num_entries += num_entries;
6249 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
6251 if (total_num_entries_p) {
6252 *total_num_entries_p = total_num_entries;
6258 static bool test_QueryDisplayInfo_level(struct dcerpc_pipe *p,
6259 struct torture_context *tctx,
6260 struct policy_handle *handle,
6262 uint32_t *total_num_entries_p)
6265 struct samr_QueryDisplayInfo r;
6266 uint32_t total_num_entries = 0;
6268 r.in.domain_handle = handle;
6271 r.in.max_entries = (uint32_t)-1;
6272 r.in.buf_size = (uint32_t)-1;
6274 torture_comment(tctx, "Testing QueryDisplayInfo\n");
6277 uint32_t total_size;
6278 uint32_t returned_size;
6279 union samr_DispInfo info;
6281 r.out.total_size = &total_size;
6282 r.out.returned_size = &returned_size;
6285 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &r);
6286 if (NT_STATUS_IS_ERR(status)) {
6287 torture_assert_ntstatus_ok(tctx, status,
6288 "failed to query displayinfo");
6291 if (*r.out.returned_size == 0) {
6295 switch (r.in.level) {
6297 total_num_entries += info.info1.count;
6298 r.in.start_idx += info.info1.entries[info.info1.count - 1].idx + 1;
6301 total_num_entries += info.info2.count;
6302 r.in.start_idx += info.info2.entries[info.info2.count - 1].idx + 1;
6305 total_num_entries += info.info3.count;
6306 r.in.start_idx += info.info3.entries[info.info3.count - 1].idx + 1;
6309 total_num_entries += info.info4.count;
6310 r.in.start_idx += info.info4.entries[info.info4.count - 1].idx + 1;
6313 total_num_entries += info.info5.count;
6314 r.in.start_idx += info.info5.entries[info.info5.count - 1].idx + 1;
6320 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
6322 if (total_num_entries_p) {
6323 *total_num_entries_p = total_num_entries;
6329 static bool test_ManyObjects(struct dcerpc_pipe *p,
6330 struct torture_context *tctx,
6331 struct policy_handle *domain_handle,
6332 struct dom_sid *domain_sid,
6333 struct torture_samr_context *ctx)
6335 uint32_t num_total = ctx->num_objects_large_dc;
6336 uint32_t num_enum = 0;
6337 uint32_t num_disp = 0;
6338 uint32_t num_created = 0;
6339 uint32_t num_anounced = 0;
6344 struct policy_handle *handles = talloc_zero_array(tctx, struct policy_handle, num_total);
6349 struct samr_QueryDomainInfo2 r;
6350 union samr_DomainInfo *info;
6351 r.in.domain_handle = domain_handle;
6355 status = dcerpc_samr_QueryDomainInfo2(p, tctx, &r);
6356 torture_assert_ntstatus_ok(tctx, status,
6357 "failed to query domain info");
6359 switch (ctx->choice) {
6360 case TORTURE_SAMR_MANY_ACCOUNTS:
6361 num_anounced = info->general.num_users;
6363 case TORTURE_SAMR_MANY_GROUPS:
6364 num_anounced = info->general.num_groups;
6366 case TORTURE_SAMR_MANY_ALIASES:
6367 num_anounced = info->general.num_aliases;
6376 for (i=0; i < num_total; i++) {
6378 const char *name = NULL;
6380 switch (ctx->choice) {
6381 case TORTURE_SAMR_MANY_ACCOUNTS:
6382 name = talloc_asprintf(tctx, "%s%04d", TEST_ACCOUNT_NAME, i);
6383 ret &= test_CreateUser(p, tctx, domain_handle, name, &handles[i], domain_sid, 0, NULL, false);
6385 case TORTURE_SAMR_MANY_GROUPS:
6386 name = talloc_asprintf(tctx, "%s%04d", TEST_GROUPNAME, i);
6387 ret &= test_CreateDomainGroup(p, tctx, domain_handle, name, &handles[i], domain_sid, false);
6389 case TORTURE_SAMR_MANY_ALIASES:
6390 name = talloc_asprintf(tctx, "%s%04d", TEST_ALIASNAME, i);
6391 ret &= test_CreateAlias(p, tctx, domain_handle, name, &handles[i], domain_sid, false);
6396 if (!policy_handle_empty(&handles[i])) {
6403 switch (ctx->choice) {
6404 case TORTURE_SAMR_MANY_ACCOUNTS:
6405 ret &= test_EnumDomainUsers(p, tctx, domain_handle, &num_enum);
6407 case TORTURE_SAMR_MANY_GROUPS:
6408 ret &= test_EnumDomainGroups(p, tctx, domain_handle, &num_enum);
6410 case TORTURE_SAMR_MANY_ALIASES:
6411 ret &= test_EnumDomainAliases(p, tctx, domain_handle, &num_enum);
6419 switch (ctx->choice) {
6420 case TORTURE_SAMR_MANY_ACCOUNTS:
6421 ret &= test_QueryDisplayInfo_level(p, tctx, domain_handle, 1, &num_disp);
6423 case TORTURE_SAMR_MANY_GROUPS:
6424 ret &= test_QueryDisplayInfo_level(p, tctx, domain_handle, 3, &num_disp);
6426 case TORTURE_SAMR_MANY_ALIASES:
6427 /* no aliases in dispinfo */
6433 /* close or delete */
6435 for (i=0; i < num_total; i++) {
6437 if (policy_handle_empty(&handles[i])) {
6441 if (torture_setting_bool(tctx, "samba3", false)) {
6442 ret &= test_samr_handle_Close(p, tctx, &handles[i]);
6444 switch (ctx->choice) {
6445 case TORTURE_SAMR_MANY_ACCOUNTS:
6446 ret &= test_DeleteUser(p, tctx, &handles[i]);
6448 case TORTURE_SAMR_MANY_GROUPS:
6449 ret &= test_DeleteDomainGroup(p, tctx, &handles[i]);
6451 case TORTURE_SAMR_MANY_ALIASES:
6452 ret &= test_DeleteAlias(p, tctx, &handles[i]);
6460 talloc_free(handles);
6462 if (ctx->choice == TORTURE_SAMR_MANY_ACCOUNTS && num_enum != num_anounced + num_created) {
6463 torture_comment(tctx,
6464 "unexpected number of results (%u) returned in enum call, expected %u\n",
6465 num_enum, num_anounced + num_created);
6467 torture_comment(tctx,
6468 "unexpected number of results (%u) returned in dispinfo, call, expected %u\n",
6469 num_disp, num_anounced + num_created);
6474 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
6475 struct policy_handle *handle);
6477 static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
6478 struct torture_samr_context *ctx, struct dom_sid *sid)
6481 struct samr_OpenDomain r;
6482 struct policy_handle domain_handle;
6483 struct policy_handle alias_handle;
6484 struct policy_handle user_handle;
6485 struct policy_handle group_handle;
6488 ZERO_STRUCT(alias_handle);
6489 ZERO_STRUCT(user_handle);
6490 ZERO_STRUCT(group_handle);
6491 ZERO_STRUCT(domain_handle);
6493 torture_comment(tctx, "Testing OpenDomain of %s\n", dom_sid_string(tctx, sid));
6495 r.in.connect_handle = &ctx->handle;
6496 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6498 r.out.domain_handle = &domain_handle;
6500 status = dcerpc_samr_OpenDomain(p, tctx, &r);
6501 torture_assert_ntstatus_ok(tctx, status, "OpenDomain");
6503 /* run the domain tests with the main handle closed - this tests
6504 the servers reference counting */
6505 torture_assert(tctx, test_samr_handle_Close(p, tctx, &ctx->handle), "Failed to close SAMR handle");
6507 switch (ctx->choice) {
6508 case TORTURE_SAMR_PASSWORDS:
6509 case TORTURE_SAMR_USER_PRIVILEGES:
6510 if (!torture_setting_bool(tctx, "samba3", false)) {
6511 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, NULL);
6513 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
6515 torture_warning(tctx, "Testing PASSWORDS or PRIVILEGES on domain %s failed!\n", dom_sid_string(tctx, sid));
6518 case TORTURE_SAMR_USER_ATTRIBUTES:
6519 if (!torture_setting_bool(tctx, "samba3", false)) {
6520 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, NULL);
6522 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
6523 /* This test needs 'complex' users to validate */
6524 ret &= test_QueryDisplayInfo(p, tctx, &domain_handle);
6526 torture_warning(tctx, "Testing ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
6529 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
6530 if (!torture_setting_bool(tctx, "samba3", false)) {
6531 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, ctx->machine_credentials);
6533 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, ctx->machine_credentials, true);
6535 torture_warning(tctx, "Testing PASSWORDS PWDLASTSET on domain %s failed!\n", dom_sid_string(tctx, sid));
6538 case TORTURE_SAMR_MANY_ACCOUNTS:
6539 case TORTURE_SAMR_MANY_GROUPS:
6540 case TORTURE_SAMR_MANY_ALIASES:
6541 ret &= test_ManyObjects(p, tctx, &domain_handle, sid, ctx);
6543 torture_warning(tctx, "Testing MANY-{ACCOUNTS,GROUPS,ALIASES} on domain %s failed!\n", dom_sid_string(tctx, sid));
6546 case TORTURE_SAMR_OTHER:
6547 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
6549 torture_warning(tctx, "Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid));
6551 if (!torture_setting_bool(tctx, "samba3", false)) {
6552 ret &= test_QuerySecurity(p, tctx, &domain_handle);
6554 ret &= test_RemoveMemberFromForeignDomain(p, tctx, &domain_handle);
6555 ret &= test_CreateAlias(p, tctx, &domain_handle, TEST_ALIASNAME, &alias_handle, sid, true);
6556 ret &= test_CreateDomainGroup(p, tctx, &domain_handle, TEST_GROUPNAME, &group_handle, sid, true);
6557 ret &= test_GetAliasMembership(p, tctx, &domain_handle);
6558 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
6559 ret &= test_QueryDomainInfo2(p, tctx, &domain_handle);
6560 ret &= test_EnumDomainUsers_all(p, tctx, &domain_handle);
6561 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
6562 ret &= test_EnumDomainGroups_all(p, tctx, &domain_handle);
6563 ret &= test_EnumDomainAliases_all(p, tctx, &domain_handle);
6564 ret &= test_QueryDisplayInfo2(p, tctx, &domain_handle);
6565 ret &= test_QueryDisplayInfo3(p, tctx, &domain_handle);
6566 ret &= test_QueryDisplayInfo_continue(p, tctx, &domain_handle);
6568 if (torture_setting_bool(tctx, "samba4", false)) {
6569 torture_comment(tctx, "skipping GetDisplayEnumerationIndex test against Samba4\n");
6571 ret &= test_GetDisplayEnumerationIndex(p, tctx, &domain_handle);
6572 ret &= test_GetDisplayEnumerationIndex2(p, tctx, &domain_handle);
6574 ret &= test_GroupList(p, tctx, &domain_handle);
6575 ret &= test_TestPrivateFunctionsDomain(p, tctx, &domain_handle);
6576 ret &= test_RidToSid(p, tctx, sid, &domain_handle);
6577 ret &= test_GetBootKeyInformation(p, tctx, &domain_handle);
6579 torture_comment(tctx, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx, sid));
6584 if (!policy_handle_empty(&user_handle) &&
6585 !test_DeleteUser(p, tctx, &user_handle)) {
6589 if (!policy_handle_empty(&alias_handle) &&
6590 !test_DeleteAlias(p, tctx, &alias_handle)) {
6594 if (!policy_handle_empty(&group_handle) &&
6595 !test_DeleteDomainGroup(p, tctx, &group_handle)) {
6599 torture_assert(tctx, test_samr_handle_Close(p, tctx, &domain_handle), "Failed to close SAMR domain handle");
6601 torture_assert(tctx, test_Connect(p, tctx, &ctx->handle), "Faile to re-connect SAMR handle");
6602 /* reconnect the main handle */
6605 torture_warning(tctx, "Testing domain %s failed!\n", dom_sid_string(tctx, sid));
6611 static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
6612 struct torture_samr_context *ctx, const char *domain)
6615 struct samr_LookupDomain r;
6616 struct dom_sid2 *sid = NULL;
6617 struct lsa_String n1;
6618 struct lsa_String n2;
6621 torture_comment(tctx, "Testing LookupDomain(%s)\n", domain);
6623 /* check for correct error codes */
6624 r.in.connect_handle = &ctx->handle;
6625 r.in.domain_name = &n2;
6629 status = dcerpc_samr_LookupDomain(p, tctx, &r);
6630 torture_assert_ntstatus_equal(tctx, NT_STATUS_INVALID_PARAMETER, status, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
6632 init_lsa_String(&n2, "xxNODOMAINxx");
6634 status = dcerpc_samr_LookupDomain(p, tctx, &r);
6635 torture_assert_ntstatus_equal(tctx, NT_STATUS_NO_SUCH_DOMAIN, status, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
6637 r.in.connect_handle = &ctx->handle;
6639 init_lsa_String(&n1, domain);
6640 r.in.domain_name = &n1;
6642 status = dcerpc_samr_LookupDomain(p, tctx, &r);
6643 torture_assert_ntstatus_ok(tctx, status, "LookupDomain");
6645 if (!test_GetDomPwInfo(p, tctx, &n1)) {
6649 if (!test_OpenDomain(p, tctx, ctx, *r.out.sid)) {
6657 static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
6658 struct torture_samr_context *ctx)
6661 struct samr_EnumDomains r;
6662 uint32_t resume_handle = 0;
6663 uint32_t num_entries = 0;
6664 struct samr_SamArray *sam = NULL;
6668 r.in.connect_handle = &ctx->handle;
6669 r.in.resume_handle = &resume_handle;
6670 r.in.buf_size = (uint32_t)-1;
6671 r.out.resume_handle = &resume_handle;
6672 r.out.num_entries = &num_entries;
6675 status = dcerpc_samr_EnumDomains(p, tctx, &r);
6676 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
6682 for (i=0;i<sam->count;i++) {
6683 if (!test_LookupDomain(p, tctx, ctx,
6684 sam->entries[i].name.string)) {
6689 status = dcerpc_samr_EnumDomains(p, tctx, &r);
6690 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
6696 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
6697 struct policy_handle *handle)
6700 struct samr_Connect r;
6701 struct samr_Connect2 r2;
6702 struct samr_Connect3 r3;
6703 struct samr_Connect4 r4;
6704 struct samr_Connect5 r5;
6705 union samr_ConnectInfo info;
6706 struct policy_handle h;
6707 uint32_t level_out = 0;
6708 bool ret = true, got_handle = false;
6710 torture_comment(tctx, "testing samr_Connect\n");
6712 r.in.system_name = 0;
6713 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6714 r.out.connect_handle = &h;
6716 status = dcerpc_samr_Connect(p, tctx, &r);
6717 if (!NT_STATUS_IS_OK(status)) {
6718 torture_comment(tctx, "Connect failed - %s\n", nt_errstr(status));
6725 torture_comment(tctx, "testing samr_Connect2\n");
6727 r2.in.system_name = NULL;
6728 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6729 r2.out.connect_handle = &h;
6731 status = dcerpc_samr_Connect2(p, tctx, &r2);
6732 if (!NT_STATUS_IS_OK(status)) {
6733 torture_comment(tctx, "Connect2 failed - %s\n", nt_errstr(status));
6737 test_samr_handle_Close(p, tctx, handle);
6743 torture_comment(tctx, "testing samr_Connect3\n");
6745 r3.in.system_name = NULL;
6747 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6748 r3.out.connect_handle = &h;
6750 status = dcerpc_samr_Connect3(p, tctx, &r3);
6751 if (!NT_STATUS_IS_OK(status)) {
6752 torture_warning(tctx, "Connect3 failed - %s\n", nt_errstr(status));
6756 test_samr_handle_Close(p, tctx, handle);
6762 torture_comment(tctx, "testing samr_Connect4\n");
6764 r4.in.system_name = "";
6765 r4.in.client_version = 0;
6766 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6767 r4.out.connect_handle = &h;
6769 status = dcerpc_samr_Connect4(p, tctx, &r4);
6770 if (!NT_STATUS_IS_OK(status)) {
6771 torture_warning(tctx, "Connect4 failed - %s\n", nt_errstr(status));
6775 test_samr_handle_Close(p, tctx, handle);
6781 torture_comment(tctx, "testing samr_Connect5\n");
6783 info.info1.client_version = 0;
6784 info.info1.unknown2 = 0;
6786 r5.in.system_name = "";
6787 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6789 r5.out.level_out = &level_out;
6790 r5.in.info_in = &info;
6791 r5.out.info_out = &info;
6792 r5.out.connect_handle = &h;
6794 status = dcerpc_samr_Connect5(p, tctx, &r5);
6795 if (!NT_STATUS_IS_OK(status)) {
6796 torture_warning(tctx, "Connect5 failed - %s\n", nt_errstr(status));
6800 test_samr_handle_Close(p, tctx, handle);
6810 static bool test_samr_ValidatePassword(struct dcerpc_pipe *p, struct torture_context *tctx)
6812 struct samr_ValidatePassword r;
6813 union samr_ValidatePasswordReq req;
6814 union samr_ValidatePasswordRep *repp = NULL;
6816 const char *passwords[] = { "penguin", "p@ssw0rd", "p@ssw0rd123$", NULL };
6819 torture_comment(tctx, "testing samr_ValidatePassword\n");
6822 r.in.level = NetValidatePasswordReset;
6827 req.req3.account.string = "non-existant-account-aklsdji";
6829 for (i=0; passwords[i]; i++) {
6830 req.req3.password.string = passwords[i];
6831 status = dcerpc_samr_ValidatePassword(p, tctx, &r);
6832 torture_assert_ntstatus_ok(tctx, status, "samr_ValidatePassword");
6833 torture_comment(tctx, "Server %s password '%s' with code %i\n",
6834 repp->ctr3.status==SAMR_VALIDATION_STATUS_SUCCESS?"allowed":"refused",
6835 req.req3.password.string, repp->ctr3.status);
6841 bool torture_rpc_samr(struct torture_context *torture)
6844 struct dcerpc_pipe *p;
6846 struct torture_samr_context *ctx;
6848 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6849 if (!NT_STATUS_IS_OK(status)) {
6853 ctx = talloc_zero(torture, struct torture_samr_context);
6855 ctx->choice = TORTURE_SAMR_OTHER;
6857 ret &= test_Connect(p, torture, &ctx->handle);
6859 if (!torture_setting_bool(torture, "samba3", false)) {
6860 ret &= test_QuerySecurity(p, torture, &ctx->handle);
6863 ret &= test_EnumDomains(p, torture, ctx);
6865 ret &= test_SetDsrmPassword(p, torture, &ctx->handle);
6867 ret &= test_Shutdown(p, torture, &ctx->handle);
6869 ret &= test_samr_handle_Close(p, torture, &ctx->handle);
6875 bool torture_rpc_samr_users(struct torture_context *torture)
6878 struct dcerpc_pipe *p;
6880 struct torture_samr_context *ctx;
6882 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6883 if (!NT_STATUS_IS_OK(status)) {
6887 ctx = talloc_zero(torture, struct torture_samr_context);
6889 ctx->choice = TORTURE_SAMR_USER_ATTRIBUTES;
6891 ret &= test_Connect(p, torture, &ctx->handle);
6893 if (!torture_setting_bool(torture, "samba3", false)) {
6894 ret &= test_QuerySecurity(p, torture, &ctx->handle);
6897 ret &= test_EnumDomains(p, torture, ctx);
6899 ret &= test_SetDsrmPassword(p, torture, &ctx->handle);
6901 ret &= test_Shutdown(p, torture, &ctx->handle);
6903 ret &= test_samr_handle_Close(p, torture, &ctx->handle);
6909 bool torture_rpc_samr_passwords(struct torture_context *torture)
6912 struct dcerpc_pipe *p;
6914 struct torture_samr_context *ctx;
6916 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6917 if (!NT_STATUS_IS_OK(status)) {
6921 ctx = talloc_zero(torture, struct torture_samr_context);
6923 ctx->choice = TORTURE_SAMR_PASSWORDS;
6925 ret &= test_Connect(p, torture, &ctx->handle);
6927 ret &= test_EnumDomains(p, torture, ctx);
6929 ret &= test_samr_handle_Close(p, torture, &ctx->handle);
6931 ret &= test_samr_ValidatePassword(p, torture);
6936 static bool torture_rpc_samr_pwdlastset(struct torture_context *torture,
6937 struct dcerpc_pipe *p2,
6938 struct cli_credentials *machine_credentials)
6941 struct dcerpc_pipe *p;
6943 struct torture_samr_context *ctx;
6945 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6946 if (!NT_STATUS_IS_OK(status)) {
6950 ctx = talloc_zero(torture, struct torture_samr_context);
6952 ctx->choice = TORTURE_SAMR_PASSWORDS_PWDLASTSET;
6953 ctx->machine_credentials = machine_credentials;
6955 ret &= test_Connect(p, torture, &ctx->handle);
6957 ret &= test_EnumDomains(p, torture, ctx);
6959 ret &= test_samr_handle_Close(p, torture, &ctx->handle);
6964 struct torture_suite *torture_rpc_samr_passwords_pwdlastset(TALLOC_CTX *mem_ctx)
6966 struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-PASSWORDS-PWDLASTSET");
6967 struct torture_rpc_tcase *tcase;
6969 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
6971 TEST_ACCOUNT_NAME_PWD);
6973 torture_rpc_tcase_add_test_creds(tcase, "pwdLastSet",
6974 torture_rpc_samr_pwdlastset);
6979 static bool torture_rpc_samr_users_privileges_delete_user(struct torture_context *torture,
6980 struct dcerpc_pipe *p2,
6981 struct cli_credentials *machine_credentials)
6984 struct dcerpc_pipe *p;
6986 struct torture_samr_context *ctx;
6988 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6989 if (!NT_STATUS_IS_OK(status)) {
6993 ctx = talloc_zero(torture, struct torture_samr_context);
6995 ctx->choice = TORTURE_SAMR_USER_PRIVILEGES;
6996 ctx->machine_credentials = machine_credentials;
6998 ret &= test_Connect(p, torture, &ctx->handle);
7000 ret &= test_EnumDomains(p, torture, ctx);
7002 ret &= test_samr_handle_Close(p, torture, &ctx->handle);
7007 struct torture_suite *torture_rpc_samr_user_privileges(TALLOC_CTX *mem_ctx)
7009 struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-USERS-PRIVILEGES");
7010 struct torture_rpc_tcase *tcase;
7012 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
7014 TEST_ACCOUNT_NAME_PWD);
7016 torture_rpc_tcase_add_test_creds(tcase, "delete_privileged_user",
7017 torture_rpc_samr_users_privileges_delete_user);
7022 static bool torture_rpc_samr_many_accounts(struct torture_context *torture,
7023 struct dcerpc_pipe *p2,
7027 struct dcerpc_pipe *p;
7029 struct torture_samr_context *ctx =
7030 talloc_get_type_abort(data, struct torture_samr_context);
7032 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
7033 if (!NT_STATUS_IS_OK(status)) {
7037 ctx->choice = TORTURE_SAMR_MANY_ACCOUNTS;
7038 ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
7039 ctx->num_objects_large_dc);
7041 ret &= test_Connect(p, torture, &ctx->handle);
7043 ret &= test_EnumDomains(p, torture, ctx);
7045 ret &= test_samr_handle_Close(p, torture, &ctx->handle);
7050 static bool torture_rpc_samr_many_groups(struct torture_context *torture,
7051 struct dcerpc_pipe *p2,
7055 struct dcerpc_pipe *p;
7057 struct torture_samr_context *ctx =
7058 talloc_get_type_abort(data, struct torture_samr_context);
7060 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
7061 if (!NT_STATUS_IS_OK(status)) {
7065 ctx->choice = TORTURE_SAMR_MANY_GROUPS;
7066 ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
7067 ctx->num_objects_large_dc);
7069 ret &= test_Connect(p, torture, &ctx->handle);
7071 ret &= test_EnumDomains(p, torture, ctx);
7073 ret &= test_samr_handle_Close(p, torture, &ctx->handle);
7078 static bool torture_rpc_samr_many_aliases(struct torture_context *torture,
7079 struct dcerpc_pipe *p2,
7083 struct dcerpc_pipe *p;
7085 struct torture_samr_context *ctx =
7086 talloc_get_type_abort(data, struct torture_samr_context);
7088 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
7089 if (!NT_STATUS_IS_OK(status)) {
7093 ctx->choice = TORTURE_SAMR_MANY_ALIASES;
7094 ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
7095 ctx->num_objects_large_dc);
7097 ret &= test_Connect(p, torture, &ctx->handle);
7099 ret &= test_EnumDomains(p, torture, ctx);
7101 ret &= test_samr_handle_Close(p, torture, &ctx->handle);
7106 struct torture_suite *torture_rpc_samr_large_dc(TALLOC_CTX *mem_ctx)
7108 struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-LARGE-DC");
7109 struct torture_rpc_tcase *tcase;
7110 struct torture_samr_context *ctx;
7112 tcase = torture_suite_add_rpc_iface_tcase(suite, "samr", &ndr_table_samr);
7114 ctx = talloc_zero(suite, struct torture_samr_context);
7115 ctx->num_objects_large_dc = 150;
7117 torture_rpc_tcase_add_test_ex(tcase, "many_aliases",
7118 torture_rpc_samr_many_aliases, ctx);
7119 torture_rpc_tcase_add_test_ex(tcase, "many_groups",
7120 torture_rpc_samr_many_groups, ctx);
7121 torture_rpc_tcase_add_test_ex(tcase, "many_accounts",
7122 torture_rpc_samr_many_accounts, ctx);