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) Jelmer Vernooij 2005-2007
8 Copyright (C) Guenther Deschner 2008-2010
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
25 #include "torture/torture.h"
27 #include "system/time.h"
28 #include "system/network.h"
29 #include "librpc/gen_ndr/lsa.h"
30 #include "librpc/gen_ndr/ndr_netlogon.h"
31 #include "librpc/gen_ndr/ndr_netlogon_c.h"
32 #include "librpc/gen_ndr/ndr_samr_c.h"
33 #include "librpc/gen_ndr/ndr_lsa_c.h"
34 #include "lib/crypto/crypto.h"
35 #include "libcli/auth/libcli_auth.h"
36 #include "libcli/security/security.h"
37 #include "torture/rpc/torture_rpc.h"
38 #include "param/param.h"
39 #include "auth/gensec/gensec.h"
40 #include "auth/gensec/gensec_proto.h"
41 #include "../libcli/auth/schannel.h"
42 #include "torture/util.h"
43 #include "source4/librpc/rpc/dcerpc.h"
44 #include "source3/rpc_client/init_samr.h"
46 #define TEST_ACCOUNT_NAME "samrtorturetest"
47 #define TEST_ACCOUNT_NAME_PWD "samrpwdlastset"
48 #define TEST_ALIASNAME "samrtorturetestalias"
49 #define TEST_GROUPNAME "samrtorturetestgroup"
50 #define TEST_MACHINENAME "samrtestmach$"
51 #define TEST_DOMAINNAME "samrtestdom$"
53 #include <gnutls/gnutls.h>
54 #include <gnutls/crypto.h>
56 enum torture_samr_choice {
57 TORTURE_SAMR_PASSWORDS,
58 TORTURE_SAMR_PASSWORDS_PWDLASTSET,
59 TORTURE_SAMR_PASSWORDS_BADPWDCOUNT,
60 TORTURE_SAMR_PASSWORDS_LOCKOUT,
61 TORTURE_SAMR_USER_ATTRIBUTES,
62 TORTURE_SAMR_USER_PRIVILEGES,
64 TORTURE_SAMR_MANY_ACCOUNTS,
65 TORTURE_SAMR_MANY_GROUPS,
66 TORTURE_SAMR_MANY_ALIASES
69 struct torture_samr_context {
70 struct policy_handle handle;
71 struct cli_credentials *machine_credentials;
72 enum torture_samr_choice choice;
73 uint32_t num_objects_large_dc;
76 static bool test_QueryUserInfo(struct dcerpc_binding_handle *b,
77 struct torture_context *tctx,
78 struct policy_handle *handle);
80 static bool test_QueryUserInfo2(struct dcerpc_binding_handle *b,
81 struct torture_context *tctx,
82 struct policy_handle *handle);
84 static bool test_QueryAliasInfo(struct dcerpc_binding_handle *b,
85 struct torture_context *tctx,
86 struct policy_handle *handle);
88 static bool test_ChangePassword(struct dcerpc_pipe *p,
89 struct torture_context *tctx,
90 const char *acct_name,
91 struct policy_handle *domain_handle, char **password);
93 static void init_lsa_String(struct lsa_String *string, const char *s)
98 static void init_lsa_StringLarge(struct lsa_StringLarge *string, const char *s)
103 static void init_lsa_BinaryString(struct lsa_BinaryString *string, const char *s, uint32_t length)
105 string->length = length;
106 string->size = length;
107 string->array = (uint16_t *)discard_const(s);
110 bool test_samr_handle_Close(struct dcerpc_binding_handle *b,
111 struct torture_context *tctx,
112 struct policy_handle *handle)
116 r.in.handle = handle;
117 r.out.handle = handle;
119 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Close_r(b, tctx, &r),
121 torture_assert_ntstatus_ok(tctx, r.out.result, "Close failed");
126 static bool test_Shutdown(struct dcerpc_binding_handle *b,
127 struct torture_context *tctx,
128 struct policy_handle *handle)
130 struct samr_Shutdown r;
132 if (!torture_setting_bool(tctx, "dangerous", false)) {
133 torture_skip(tctx, "samr_Shutdown disabled - enable dangerous tests to use\n");
137 r.in.connect_handle = handle;
139 torture_comment(tctx, "Testing samr_Shutdown\n");
141 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Shutdown_r(b, tctx, &r),
143 torture_assert_ntstatus_ok(tctx, r.out.result, "Shutdown failed");
148 static bool test_SetDsrmPassword(struct dcerpc_binding_handle *b,
149 struct torture_context *tctx,
150 struct policy_handle *handle)
152 struct samr_SetDsrmPassword r;
153 struct lsa_String string;
154 struct samr_Password hash;
156 if (!torture_setting_bool(tctx, "dangerous", false)) {
157 torture_skip(tctx, "samr_SetDsrmPassword disabled - enable dangerous tests to use");
160 E_md4hash("TeSTDSRM123", hash.hash);
162 init_lsa_String(&string, "Administrator");
168 torture_comment(tctx, "Testing samr_SetDsrmPassword\n");
170 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDsrmPassword_r(b, tctx, &r),
171 "SetDsrmPassword failed");
172 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_SUPPORTED, "SetDsrmPassword failed");
178 static bool test_QuerySecurity(struct dcerpc_binding_handle *b,
179 struct torture_context *tctx,
180 struct policy_handle *handle)
182 struct samr_QuerySecurity r;
183 struct samr_SetSecurity s;
184 struct sec_desc_buf *sdbuf = NULL;
186 r.in.handle = handle;
188 r.out.sdbuf = &sdbuf;
190 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QuerySecurity_r(b, tctx, &r),
191 "QuerySecurity failed");
192 torture_assert_ntstatus_ok(tctx, r.out.result, "QuerySecurity failed");
194 torture_assert(tctx, sdbuf != NULL, "sdbuf is NULL");
196 s.in.handle = handle;
200 if (torture_setting_bool(tctx, "samba4", false)) {
201 torture_skip(tctx, "skipping SetSecurity test against Samba4\n");
204 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetSecurity_r(b, tctx, &s),
205 "SetSecurity failed");
206 torture_assert_ntstatus_ok(tctx, r.out.result, "SetSecurity failed");
208 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QuerySecurity_r(b, tctx, &r),
209 "QuerySecurity failed");
210 torture_assert_ntstatus_ok(tctx, r.out.result, "QuerySecurity failed");
216 static bool test_SetUserInfo(struct dcerpc_binding_handle *b, struct torture_context *tctx,
217 struct policy_handle *handle, uint32_t base_acct_flags,
218 const char *base_account_name)
220 struct samr_SetUserInfo s;
221 struct samr_SetUserInfo2 s2;
222 struct samr_QueryUserInfo q;
223 struct samr_QueryUserInfo q0;
224 union samr_UserInfo u;
225 union samr_UserInfo *info;
227 const char *test_account_name;
229 uint32_t user_extra_flags = 0;
231 if (!torture_setting_bool(tctx, "samba3", false)) {
232 if (base_acct_flags == ACB_NORMAL) {
233 /* When created, accounts are expired by default */
234 user_extra_flags = ACB_PW_EXPIRED;
238 s.in.user_handle = handle;
241 s2.in.user_handle = handle;
244 q.in.user_handle = handle;
248 #define TESTCALL(call, r) \
249 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ ##call## _r(b, tctx, &r),\
251 if (!NT_STATUS_IS_OK(r.out.result)) { \
252 torture_result(tctx, TORTURE_FAIL, #call " level %u failed - %s (%s)\n", \
253 r.in.level, nt_errstr(r.out.result), __location__); \
258 #define STRING_EQUAL(s1, s2, field) \
259 torture_assert_str_equal(tctx, s1, s2, "Failed to set " #field)
261 #define MEM_EQUAL(s1, s2, length, field) \
262 torture_assert_mem_equal(tctx, s1, s2, length, "Failed to set " #field)
264 #define INT_EQUAL(i1, i2, field) \
265 torture_assert_int_equal(tctx, i1, i2, "Failed to set " #field)
267 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
268 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
270 TESTCALL(QueryUserInfo, q) \
272 s2.in.level = lvl1; \
275 ZERO_STRUCT(u.info21); \
276 u.info21.fields_present = fpval; \
278 init_lsa_String(&u.info ## lvl1.field1, value); \
279 TESTCALL(SetUserInfo, s) \
280 TESTCALL(SetUserInfo2, s2) \
281 init_lsa_String(&u.info ## lvl1.field1, ""); \
282 TESTCALL(QueryUserInfo, q); \
284 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
286 TESTCALL(QueryUserInfo, q) \
288 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
291 #define TEST_USERINFO_BINARYSTRING(lvl1, field1, lvl2, field2, value, fpval) do { \
292 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
294 TESTCALL(QueryUserInfo, q) \
296 s2.in.level = lvl1; \
299 ZERO_STRUCT(u.info21); \
300 u.info21.fields_present = fpval; \
302 init_lsa_BinaryString(&u.info ## lvl1.field1, value, strlen(value)); \
303 TESTCALL(SetUserInfo, s) \
304 TESTCALL(SetUserInfo2, s2) \
305 init_lsa_BinaryString(&u.info ## lvl1.field1, "", 1); \
306 TESTCALL(QueryUserInfo, q); \
308 MEM_EQUAL(u.info ## lvl1.field1.array, value, strlen(value), field1); \
310 TESTCALL(QueryUserInfo, q) \
312 MEM_EQUAL(u.info ## lvl2.field2.array, value, strlen(value), field2); \
315 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
316 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
318 TESTCALL(QueryUserInfo, q) \
320 s2.in.level = lvl1; \
323 uint8_t *bits = u.info21.logon_hours.bits; \
324 ZERO_STRUCT(u.info21); \
325 if (fpval == SAMR_FIELD_LOGON_HOURS) { \
326 u.info21.logon_hours.units_per_week = 168; \
327 u.info21.logon_hours.bits = bits; \
329 u.info21.fields_present = fpval; \
331 u.info ## lvl1.field1 = value; \
332 TESTCALL(SetUserInfo, s) \
333 TESTCALL(SetUserInfo2, s2) \
334 u.info ## lvl1.field1 = 0; \
335 TESTCALL(QueryUserInfo, q); \
337 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
339 TESTCALL(QueryUserInfo, q) \
341 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
344 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
345 TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
349 do { TESTCALL(QueryUserInfo, q0) } while (0);
351 TEST_USERINFO_STRING(2, comment, 1, comment, "xx2-1 comment", 0);
352 TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
353 TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment",
356 test_account_name = talloc_asprintf(tctx, "%sxx7-1", base_account_name);
357 TEST_USERINFO_STRING(7, account_name, 1, account_name, test_account_name, 0);
358 test_account_name = talloc_asprintf(tctx, "%sxx7-3", base_account_name);
359 TEST_USERINFO_STRING(7, account_name, 3, account_name, test_account_name, 0);
360 test_account_name = talloc_asprintf(tctx, "%sxx7-5", base_account_name);
361 TEST_USERINFO_STRING(7, account_name, 5, account_name, test_account_name, 0);
362 test_account_name = talloc_asprintf(tctx, "%sxx7-6", base_account_name);
363 TEST_USERINFO_STRING(7, account_name, 6, account_name, test_account_name, 0);
364 test_account_name = talloc_asprintf(tctx, "%sxx7-7", base_account_name);
365 TEST_USERINFO_STRING(7, account_name, 7, account_name, test_account_name, 0);
366 test_account_name = talloc_asprintf(tctx, "%sxx7-21", base_account_name);
367 TEST_USERINFO_STRING(7, account_name, 21, account_name, test_account_name, 0);
368 test_account_name = base_account_name;
369 TEST_USERINFO_STRING(21, account_name, 21, account_name, test_account_name,
370 SAMR_FIELD_ACCOUNT_NAME);
372 TEST_USERINFO_STRING(6, full_name, 1, full_name, "xx6-1 full_name", 0);
373 TEST_USERINFO_STRING(6, full_name, 3, full_name, "xx6-3 full_name", 0);
374 TEST_USERINFO_STRING(6, full_name, 5, full_name, "xx6-5 full_name", 0);
375 TEST_USERINFO_STRING(6, full_name, 6, full_name, "xx6-6 full_name", 0);
376 TEST_USERINFO_STRING(6, full_name, 8, full_name, "xx6-8 full_name", 0);
377 TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
378 TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
379 TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name",
380 SAMR_FIELD_FULL_NAME);
382 TEST_USERINFO_STRING(6, full_name, 1, full_name, "", 0);
383 TEST_USERINFO_STRING(6, full_name, 3, full_name, "", 0);
384 TEST_USERINFO_STRING(6, full_name, 5, full_name, "", 0);
385 TEST_USERINFO_STRING(6, full_name, 6, full_name, "", 0);
386 TEST_USERINFO_STRING(6, full_name, 8, full_name, "", 0);
387 TEST_USERINFO_STRING(6, full_name, 21, full_name, "", 0);
388 TEST_USERINFO_STRING(8, full_name, 21, full_name, "", 0);
389 TEST_USERINFO_STRING(21, full_name, 21, full_name, "",
390 SAMR_FIELD_FULL_NAME);
392 TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
393 TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
394 TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
395 TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script",
396 SAMR_FIELD_LOGON_SCRIPT);
398 TEST_USERINFO_STRING(12, profile_path, 3, profile_path, "xx12-3 profile_path", 0);
399 TEST_USERINFO_STRING(12, profile_path, 5, profile_path, "xx12-5 profile_path", 0);
400 TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
401 TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path",
402 SAMR_FIELD_PROFILE_PATH);
404 TEST_USERINFO_STRING(10, home_directory, 3, home_directory, "xx10-3 home_directory", 0);
405 TEST_USERINFO_STRING(10, home_directory, 5, home_directory, "xx10-5 home_directory", 0);
406 TEST_USERINFO_STRING(10, home_directory, 21, home_directory, "xx10-21 home_directory", 0);
407 TEST_USERINFO_STRING(21, home_directory, 21, home_directory, "xx21-21 home_directory",
408 SAMR_FIELD_HOME_DIRECTORY);
409 TEST_USERINFO_STRING(21, home_directory, 10, home_directory, "xx21-10 home_directory",
410 SAMR_FIELD_HOME_DIRECTORY);
412 TEST_USERINFO_STRING(10, home_drive, 3, home_drive, "xx10-3 home_drive", 0);
413 TEST_USERINFO_STRING(10, home_drive, 5, home_drive, "xx10-5 home_drive", 0);
414 TEST_USERINFO_STRING(10, home_drive, 21, home_drive, "xx10-21 home_drive", 0);
415 TEST_USERINFO_STRING(21, home_drive, 21, home_drive, "xx21-21 home_drive",
416 SAMR_FIELD_HOME_DRIVE);
417 TEST_USERINFO_STRING(21, home_drive, 10, home_drive, "xx21-10 home_drive",
418 SAMR_FIELD_HOME_DRIVE);
420 TEST_USERINFO_STRING(13, description, 1, description, "xx13-1 description", 0);
421 TEST_USERINFO_STRING(13, description, 5, description, "xx13-5 description", 0);
422 TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
423 TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description",
424 SAMR_FIELD_DESCRIPTION);
426 TEST_USERINFO_STRING(14, workstations, 3, workstations, "14workstation3", 0);
427 TEST_USERINFO_STRING(14, workstations, 5, workstations, "14workstation4", 0);
428 TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
429 TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21",
430 SAMR_FIELD_WORKSTATIONS);
431 TEST_USERINFO_STRING(21, workstations, 3, workstations, "21workstation3",
432 SAMR_FIELD_WORKSTATIONS);
433 TEST_USERINFO_STRING(21, workstations, 5, workstations, "21workstation5",
434 SAMR_FIELD_WORKSTATIONS);
435 TEST_USERINFO_STRING(21, workstations, 14, workstations, "21workstation14",
436 SAMR_FIELD_WORKSTATIONS);
438 TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
439 TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "xx21-21 parameters",
440 SAMR_FIELD_PARAMETERS);
441 TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "xx21-20 parameters",
442 SAMR_FIELD_PARAMETERS);
443 /* also empty user parameters are allowed */
444 TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "", 0);
445 TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "",
446 SAMR_FIELD_PARAMETERS);
447 TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "",
448 SAMR_FIELD_PARAMETERS);
450 /* Samba 3 cannot store country_code and code_page atm. - gd */
451 if (!torture_setting_bool(tctx, "samba3", false)) {
452 TEST_USERINFO_INT(2, country_code, 2, country_code, __LINE__, 0);
453 TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
454 TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__,
455 SAMR_FIELD_COUNTRY_CODE);
456 TEST_USERINFO_INT(21, country_code, 2, country_code, __LINE__,
457 SAMR_FIELD_COUNTRY_CODE);
459 TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
460 TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__,
461 SAMR_FIELD_CODE_PAGE);
462 TEST_USERINFO_INT(21, code_page, 2, code_page, __LINE__,
463 SAMR_FIELD_CODE_PAGE);
466 if (!torture_setting_bool(tctx, "samba3", false)) {
467 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, __LINE__, 0);
468 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, __LINE__, 0);
469 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, __LINE__,
470 SAMR_FIELD_ACCT_EXPIRY);
471 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, __LINE__,
472 SAMR_FIELD_ACCT_EXPIRY);
473 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, __LINE__,
474 SAMR_FIELD_ACCT_EXPIRY);
476 /* Samba 3 can only store seconds / time_t in passdb - gd */
478 unix_to_nt_time(&nt, time(NULL) + __LINE__);
479 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, nt, 0);
480 unix_to_nt_time(&nt, time(NULL) + __LINE__);
481 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, nt, 0);
482 unix_to_nt_time(&nt, time(NULL) + __LINE__);
483 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
484 unix_to_nt_time(&nt, time(NULL) + __LINE__);
485 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
486 unix_to_nt_time(&nt, time(NULL) + __LINE__);
487 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
490 TEST_USERINFO_INT(4, logon_hours.bits[3], 3, logon_hours.bits[3], 1, 0);
491 TEST_USERINFO_INT(4, logon_hours.bits[3], 5, logon_hours.bits[3], 2, 0);
492 TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
493 TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4,
494 SAMR_FIELD_LOGON_HOURS);
496 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
497 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
498 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
500 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
501 (base_acct_flags | ACB_DISABLED),
502 (base_acct_flags | ACB_DISABLED | user_extra_flags),
505 /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
506 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
507 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
508 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
510 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
511 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
512 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
516 /* The 'autolock' flag doesn't stick - check this */
517 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
518 (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK),
519 (base_acct_flags | ACB_DISABLED | user_extra_flags),
522 /* Removing the 'disabled' flag doesn't stick - check this */
523 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
525 (base_acct_flags | ACB_DISABLED | user_extra_flags),
529 /* Samba3 cannot store these atm */
530 if (!torture_setting_bool(tctx, "samba3", false)) {
531 /* The 'store plaintext' flag does stick */
532 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
533 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED),
534 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags),
536 /* The 'use DES' flag does stick */
537 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
538 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY),
539 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags),
541 /* The 'don't require kerberos pre-authentication flag does stick */
542 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
543 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH),
544 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags),
546 /* The 'no kerberos PAC required' flag sticks */
547 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
548 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD),
549 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags),
552 TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags,
553 (base_acct_flags | ACB_DISABLED),
554 (base_acct_flags | ACB_DISABLED | user_extra_flags),
555 SAMR_FIELD_ACCT_FLAGS);
558 /* these fail with win2003 - it appears you can't set the primary gid?
559 the set succeeds, but the gid isn't changed. Very weird! */
560 TEST_USERINFO_INT(9, primary_gid, 1, primary_gid, 513);
561 TEST_USERINFO_INT(9, primary_gid, 3, primary_gid, 513);
562 TEST_USERINFO_INT(9, primary_gid, 5, primary_gid, 513);
563 TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
570 generate a random password for password change tests
572 static char *samr_rand_pass_silent(TALLOC_CTX *mem_ctx, int min_len)
574 size_t len = MAX(8, min_len);
575 char *s = generate_random_password(mem_ctx, len, len+6);
579 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
581 char *s = samr_rand_pass_silent(mem_ctx, min_len);
582 printf("Generated password '%s'\n", s);
588 generate a random password for password change tests
590 static DATA_BLOB samr_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
593 DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
594 generate_random_buffer(password.data, password.length);
596 for (i=0; i < len; i++) {
597 if (((uint16_t *)password.data)[i] == 0) {
598 ((uint16_t *)password.data)[i] = 1;
606 generate a random password for password change tests (fixed length)
608 static char *samr_rand_pass_fixed_len(TALLOC_CTX *mem_ctx, int len)
610 char *s = generate_random_password(mem_ctx, len, len);
611 printf("Generated password '%s'\n", s);
615 static bool test_SetUserPass(struct dcerpc_pipe *p, struct torture_context *tctx,
616 struct policy_handle *handle, char **password)
619 struct samr_SetUserInfo s;
620 union samr_UserInfo u;
622 DATA_BLOB session_key;
624 struct dcerpc_binding_handle *b = p->binding_handle;
625 struct samr_GetUserPwInfo pwp;
626 struct samr_PwInfo info;
627 int policy_min_pw_len = 0;
628 pwp.in.user_handle = handle;
629 pwp.out.info = &info;
631 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &pwp),
632 "GetUserPwInfo failed");
633 if (NT_STATUS_IS_OK(pwp.out.result)) {
634 policy_min_pw_len = pwp.out.info->min_password_length;
636 newpass = samr_rand_pass(tctx, policy_min_pw_len);
638 s.in.user_handle = handle;
642 u.info24.password_expired = 0;
644 status = dcerpc_fetch_session_key(p, &session_key);
645 if (!NT_STATUS_IS_OK(status)) {
646 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u - no session key - %s\n",
647 s.in.level, nt_errstr(status));
651 status = init_samr_CryptPassword(newpass,
654 torture_assert_ntstatus_ok(tctx,
656 "init_samr_CryptPassword failed");
658 torture_comment(tctx, "Testing SetUserInfo level 24 (set password)\n");
660 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
661 "SetUserInfo failed");
662 torture_comment(tctx, "(%s:%s) new_password[%s] status[%s]\n",
663 __location__, __FUNCTION__,
664 newpass, nt_errstr(s.out.result));
665 if (!NT_STATUS_IS_OK(s.out.result)) {
666 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u failed - %s\n",
667 s.in.level, nt_errstr(s.out.result));
677 static bool test_SetUserPass_23(struct dcerpc_pipe *p, struct torture_context *tctx,
678 struct policy_handle *handle, uint32_t fields_present,
682 struct samr_SetUserInfo s;
683 union samr_UserInfo u;
685 DATA_BLOB session_key;
686 struct dcerpc_binding_handle *b = p->binding_handle;
688 struct samr_GetUserPwInfo pwp;
689 struct samr_PwInfo info;
690 int policy_min_pw_len = 0;
691 pwp.in.user_handle = handle;
692 pwp.out.info = &info;
694 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &pwp),
695 "GetUserPwInfo failed");
696 if (NT_STATUS_IS_OK(pwp.out.result)) {
697 policy_min_pw_len = pwp.out.info->min_password_length;
699 newpass = samr_rand_pass(tctx, policy_min_pw_len);
701 s.in.user_handle = handle;
707 u.info23.info.fields_present = fields_present;
709 status = dcerpc_fetch_session_key(p, &session_key);
710 if (!NT_STATUS_IS_OK(status)) {
711 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u - no session key - %s\n",
712 s.in.level, nt_errstr(status));
716 status = init_samr_CryptPassword(newpass,
719 torture_assert_ntstatus_ok(tctx,
721 "init_samr_CryptPassword failed");
723 torture_comment(tctx, "Testing SetUserInfo level 23 (set password)\n");
725 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
726 "SetUserInfo failed");
727 torture_comment(tctx, "(%s:%s) new_password[%s] status[%s]\n",
728 __location__, __FUNCTION__,
729 newpass, nt_errstr(s.out.result));
730 if (!NT_STATUS_IS_OK(s.out.result)) {
731 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u failed - %s\n",
732 s.in.level, nt_errstr(s.out.result));
738 status = dcerpc_fetch_session_key(p, &session_key);
739 if (!NT_STATUS_IS_OK(status)) {
740 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u - no session key - %s\n",
741 s.in.level, nt_errstr(status));
745 /* This should break the key nicely */
746 session_key.data[0]++;
748 status = init_samr_CryptPassword(newpass,
751 torture_assert_ntstatus_ok(tctx,
753 "init_samr_CryptPassword failed");
755 /* Reset the session key */
756 session_key.data[0]--;
758 torture_comment(tctx, "Testing SetUserInfo level 23 (set password) with wrong password\n");
760 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
761 "SetUserInfo failed");
762 torture_comment(tctx, "(%s:%s) new_password[%s] status[%s]\n",
763 __location__, __FUNCTION__,
764 newpass, nt_errstr(s.out.result));
765 if (!NT_STATUS_EQUAL(s.out.result, NT_STATUS_WRONG_PASSWORD)) {
766 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
767 s.in.level, nt_errstr(s.out.result));
775 static bool test_SetUserPassEx(struct dcerpc_pipe *p, struct torture_context *tctx,
776 struct policy_handle *handle, bool makeshort,
780 struct samr_SetUserInfo s;
781 union samr_UserInfo u;
783 DATA_BLOB session_key;
785 struct dcerpc_binding_handle *b = p->binding_handle;
786 struct samr_GetUserPwInfo pwp;
787 struct samr_PwInfo info;
788 int policy_min_pw_len = 0;
790 pwp.in.user_handle = handle;
791 pwp.out.info = &info;
793 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &pwp),
794 "GetUserPwInfo failed");
795 if (NT_STATUS_IS_OK(pwp.out.result)) {
796 policy_min_pw_len = pwp.out.info->min_password_length;
798 if (makeshort && policy_min_pw_len) {
799 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len - 1);
801 newpass = samr_rand_pass(tctx, policy_min_pw_len);
804 s.in.user_handle = handle;
808 u.info26.password_expired = 0;
810 status = dcerpc_fetch_session_key(p, &session_key);
811 if (!NT_STATUS_IS_OK(status)) {
812 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u - no session key - %s\n",
813 s.in.level, nt_errstr(status));
817 status = init_samr_CryptPasswordEx(newpass,
820 torture_assert_ntstatus_ok(tctx,
822 "init_samr_CryptPasswordEx failed");
824 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex)\n");
826 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
827 "SetUserInfo failed");
828 torture_comment(tctx, "(%s:%s) new_password[%s] status[%s]\n",
829 __location__, __FUNCTION__,
830 newpass, nt_errstr(s.out.result));
831 if (!NT_STATUS_IS_OK(s.out.result)) {
832 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u failed - %s\n",
833 s.in.level, nt_errstr(s.out.result));
839 /* This should break the key nicely */
840 session_key.data[0]++;
842 status = init_samr_CryptPasswordEx(newpass,
845 torture_assert_ntstatus_ok(tctx,
847 "init_samr_CryptPasswordEx failed");
850 session_key.data[0]--;
852 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
854 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
855 "SetUserInfo failed");
856 torture_comment(tctx, "(%s:%s) new_password[%s] status[%s]\n",
857 __location__, __FUNCTION__,
858 newpass, nt_errstr(s.out.result));
859 if (!NT_STATUS_EQUAL(s.out.result, NT_STATUS_WRONG_PASSWORD)) {
860 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
861 s.in.level, nt_errstr(s.out.result));
870 static bool test_SetUserPass_25(struct dcerpc_pipe *p, struct torture_context *tctx,
871 struct policy_handle *handle, uint32_t fields_present,
875 struct samr_SetUserInfo s;
876 union samr_UserInfo u;
878 DATA_BLOB session_key;
880 struct dcerpc_binding_handle *b = p->binding_handle;
881 struct samr_GetUserPwInfo pwp;
882 struct samr_PwInfo info;
883 int policy_min_pw_len = 0;
885 pwp.in.user_handle = handle;
886 pwp.out.info = &info;
888 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &pwp),
889 "GetUserPwInfo failed");
890 if (NT_STATUS_IS_OK(pwp.out.result)) {
891 policy_min_pw_len = pwp.out.info->min_password_length;
893 newpass = samr_rand_pass(tctx, policy_min_pw_len);
895 s.in.user_handle = handle;
901 u.info25.info.fields_present = fields_present;
903 status = dcerpc_fetch_session_key(p, &session_key);
904 if (!NT_STATUS_IS_OK(status)) {
905 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u - no session key - %s\n",
906 s.in.level, nt_errstr(status));
910 status = init_samr_CryptPasswordEx(newpass,
913 torture_assert_ntstatus_ok(tctx,
915 "init_samr_CryptPasswordEx failed");
917 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex)\n");
919 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
920 "SetUserInfo failed");
921 torture_comment(tctx, "(%s:%s) new_password[%s] status[%s]\n",
922 __location__, __FUNCTION__,
923 newpass, nt_errstr(s.out.result));
924 if (!NT_STATUS_IS_OK(s.out.result)) {
925 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u failed - %s\n",
926 s.in.level, nt_errstr(s.out.result));
932 /* This should break the key nicely */
933 session_key.data[0]++;
935 status = init_samr_CryptPasswordEx(newpass,
938 torture_assert_ntstatus_ok(tctx,
940 "init_samr_CryptPasswordEx failed");
943 session_key.data[0]--;
945 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
947 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
948 "SetUserInfo failed");
949 torture_comment(tctx, "(%s:%s) new_password[%s] status[%s]\n",
950 __location__, __FUNCTION__,
951 newpass, nt_errstr(s.out.result));
952 if (!NT_STATUS_EQUAL(s.out.result, NT_STATUS_WRONG_PASSWORD)) {
953 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
954 s.in.level, nt_errstr(s.out.result));
961 static bool test_SetUserPass_18(struct dcerpc_pipe *p, struct torture_context *tctx,
962 struct policy_handle *handle, char **password)
965 struct samr_SetUserInfo s;
966 union samr_UserInfo u;
968 DATA_BLOB session_key;
970 struct dcerpc_binding_handle *b = p->binding_handle;
971 struct samr_GetUserPwInfo pwp;
972 struct samr_PwInfo info;
973 int policy_min_pw_len = 0;
974 uint8_t lm_hash[16], nt_hash[16];
976 pwp.in.user_handle = handle;
977 pwp.out.info = &info;
979 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &pwp),
980 "GetUserPwInfo failed");
981 if (NT_STATUS_IS_OK(pwp.out.result)) {
982 policy_min_pw_len = pwp.out.info->min_password_length;
984 newpass = samr_rand_pass(tctx, policy_min_pw_len);
986 s.in.user_handle = handle;
992 u.info18.nt_pwd_active = true;
993 u.info18.lm_pwd_active = true;
995 E_md4hash(newpass, nt_hash);
996 E_deshash(newpass, lm_hash);
998 status = dcerpc_fetch_session_key(p, &session_key);
999 if (!NT_STATUS_IS_OK(status)) {
1000 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u - no session key - %s\n",
1001 s.in.level, nt_errstr(status));
1007 in = data_blob_const(nt_hash, 16);
1008 out = data_blob_talloc_zero(tctx, 16);
1009 sess_crypt_blob(&out, &in, &session_key, true);
1010 memcpy(u.info18.nt_pwd.hash, out.data, out.length);
1014 in = data_blob_const(lm_hash, 16);
1015 out = data_blob_talloc_zero(tctx, 16);
1016 sess_crypt_blob(&out, &in, &session_key, true);
1017 memcpy(u.info18.lm_pwd.hash, out.data, out.length);
1020 torture_comment(tctx, "Testing SetUserInfo level 18 (set password hash)\n");
1022 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
1023 "SetUserInfo failed");
1024 if (!NT_STATUS_IS_OK(s.out.result)) {
1025 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u failed - %s\n",
1026 s.in.level, nt_errstr(s.out.result));
1029 *password = newpass;
1035 static bool test_SetUserPass_21(struct dcerpc_pipe *p, struct torture_context *tctx,
1036 struct policy_handle *handle, uint32_t fields_present,
1040 struct samr_SetUserInfo s;
1041 union samr_UserInfo u;
1043 DATA_BLOB session_key;
1045 struct dcerpc_binding_handle *b = p->binding_handle;
1046 struct samr_GetUserPwInfo pwp;
1047 struct samr_PwInfo info;
1048 int policy_min_pw_len = 0;
1049 uint8_t lm_hash[16], nt_hash[16];
1051 pwp.in.user_handle = handle;
1052 pwp.out.info = &info;
1054 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &pwp),
1055 "GetUserPwInfo failed");
1056 if (NT_STATUS_IS_OK(pwp.out.result)) {
1057 policy_min_pw_len = pwp.out.info->min_password_length;
1059 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1061 s.in.user_handle = handle;
1065 E_md4hash(newpass, nt_hash);
1066 E_deshash(newpass, lm_hash);
1070 u.info21.fields_present = fields_present;
1072 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1073 u.info21.lm_owf_password.length = 16;
1074 u.info21.lm_owf_password.size = 16;
1075 u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
1076 u.info21.lm_password_set = true;
1079 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1080 u.info21.nt_owf_password.length = 16;
1081 u.info21.nt_owf_password.size = 16;
1082 u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
1083 u.info21.nt_password_set = true;
1086 status = dcerpc_fetch_session_key(p, &session_key);
1087 if (!NT_STATUS_IS_OK(status)) {
1088 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u - no session key - %s\n",
1089 s.in.level, nt_errstr(status));
1093 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1095 in = data_blob_const(u.info21.lm_owf_password.array,
1096 u.info21.lm_owf_password.length);
1097 out = data_blob_talloc_zero(tctx, 16);
1098 sess_crypt_blob(&out, &in, &session_key, true);
1099 u.info21.lm_owf_password.array = (uint16_t *)out.data;
1102 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1104 in = data_blob_const(u.info21.nt_owf_password.array,
1105 u.info21.nt_owf_password.length);
1106 out = data_blob_talloc_zero(tctx, 16);
1107 sess_crypt_blob(&out, &in, &session_key, true);
1108 u.info21.nt_owf_password.array = (uint16_t *)out.data;
1111 torture_comment(tctx, "Testing SetUserInfo level 21 (set password hash)\n");
1113 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
1114 "SetUserInfo failed");
1115 if (!NT_STATUS_IS_OK(s.out.result)) {
1116 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u failed - %s\n",
1117 s.in.level, nt_errstr(s.out.result));
1120 *password = newpass;
1123 /* try invalid length */
1124 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1126 u.info21.nt_owf_password.length++;
1128 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
1129 "SetUserInfo failed");
1130 if (!NT_STATUS_EQUAL(s.out.result, NT_STATUS_INVALID_PARAMETER)) {
1131 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1132 s.in.level, nt_errstr(s.out.result));
1137 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1139 u.info21.lm_owf_password.length++;
1141 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
1142 "SetUserInfo failed");
1143 if (!NT_STATUS_EQUAL(s.out.result, NT_STATUS_INVALID_PARAMETER)) {
1144 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1145 s.in.level, nt_errstr(s.out.result));
1153 static bool test_SetUserPass_level_ex(struct dcerpc_pipe *p,
1154 struct torture_context *tctx,
1155 struct policy_handle *handle,
1157 uint32_t fields_present,
1158 char **password, uint8_t password_expired,
1160 bool *matched_expected_error)
1163 NTSTATUS expected_error = NT_STATUS_OK;
1164 struct samr_SetUserInfo s;
1165 struct samr_SetUserInfo2 s2;
1166 union samr_UserInfo u;
1168 DATA_BLOB session_key;
1170 struct dcerpc_binding_handle *b = p->binding_handle;
1171 struct samr_GetUserPwInfo pwp;
1172 struct samr_PwInfo info;
1173 int policy_min_pw_len = 0;
1174 const char *comment = NULL;
1175 uint8_t lm_hash[16], nt_hash[16];
1177 pwp.in.user_handle = handle;
1178 pwp.out.info = &info;
1180 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &pwp),
1181 "GetUserPwInfo failed");
1182 if (NT_STATUS_IS_OK(pwp.out.result)) {
1183 policy_min_pw_len = pwp.out.info->min_password_length;
1185 newpass = samr_rand_pass_silent(tctx, policy_min_pw_len);
1188 s2.in.user_handle = handle;
1190 s2.in.level = level;
1192 s.in.user_handle = handle;
1197 if (fields_present & SAMR_FIELD_COMMENT) {
1198 comment = talloc_asprintf(tctx, "comment: %ld\n", (long int) time(NULL));
1205 E_md4hash(newpass, nt_hash);
1206 E_deshash(newpass, lm_hash);
1208 u.info18.nt_pwd_active = true;
1209 u.info18.lm_pwd_active = true;
1210 u.info18.password_expired = password_expired;
1212 memcpy(u.info18.lm_pwd.hash, lm_hash, 16);
1213 memcpy(u.info18.nt_pwd.hash, nt_hash, 16);
1217 E_md4hash(newpass, nt_hash);
1218 E_deshash(newpass, lm_hash);
1220 u.info21.fields_present = fields_present;
1221 u.info21.password_expired = password_expired;
1222 u.info21.comment.string = comment;
1224 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1225 u.info21.lm_owf_password.length = 16;
1226 u.info21.lm_owf_password.size = 16;
1227 u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
1228 u.info21.lm_password_set = true;
1231 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1232 u.info21.nt_owf_password.length = 16;
1233 u.info21.nt_owf_password.size = 16;
1234 u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
1235 u.info21.nt_password_set = true;
1240 u.info23.info.fields_present = fields_present;
1241 u.info23.info.password_expired = password_expired;
1242 u.info23.info.comment.string = comment;
1246 u.info24.password_expired = password_expired;
1250 u.info25.info.fields_present = fields_present;
1251 u.info25.info.password_expired = password_expired;
1252 u.info25.info.comment.string = comment;
1256 u.info26.password_expired = password_expired;
1261 status = dcerpc_fetch_session_key(p, &session_key);
1262 if (!NT_STATUS_IS_OK(status)) {
1263 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u - no session key - %s\n",
1264 s.in.level, nt_errstr(status));
1272 in = data_blob_const(u.info18.nt_pwd.hash, 16);
1273 out = data_blob_talloc_zero(tctx, 16);
1274 sess_crypt_blob(&out, &in, &session_key, true);
1275 memcpy(u.info18.nt_pwd.hash, out.data, out.length);
1279 in = data_blob_const(u.info18.lm_pwd.hash, 16);
1280 out = data_blob_talloc_zero(tctx, 16);
1281 sess_crypt_blob(&out, &in, &session_key, true);
1282 memcpy(u.info18.lm_pwd.hash, out.data, out.length);
1287 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1289 in = data_blob_const(u.info21.lm_owf_password.array,
1290 u.info21.lm_owf_password.length);
1291 out = data_blob_talloc_zero(tctx, 16);
1292 sess_crypt_blob(&out, &in, &session_key, true);
1293 u.info21.lm_owf_password.array = (uint16_t *)out.data;
1295 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1297 in = data_blob_const(u.info21.nt_owf_password.array,
1298 u.info21.nt_owf_password.length);
1299 out = data_blob_talloc_zero(tctx, 16);
1300 sess_crypt_blob(&out, &in, &session_key, true);
1301 u.info21.nt_owf_password.array = (uint16_t *)out.data;
1305 status = init_samr_CryptPassword(newpass,
1307 &u.info23.password);
1308 torture_assert_ntstatus_ok(tctx,
1310 "init_samr_CryptPassword failed");
1313 status = init_samr_CryptPassword(newpass,
1315 &u.info24.password);
1316 torture_assert_ntstatus_ok(tctx,
1318 "init_samr_CryptPassword failed");
1321 status = init_samr_CryptPasswordEx(newpass,
1323 &u.info25.password);
1324 torture_assert_ntstatus_ok(tctx,
1326 "init_samr_CryptPasswordEx failed");
1329 status = init_samr_CryptPasswordEx(newpass,
1331 &u.info26.password);
1332 torture_assert_ntstatus_ok(tctx,
1334 "init_samr_CryptPasswordEx failed");
1339 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo2_r(b, tctx, &s2),
1340 "SetUserInfo2 failed");
1341 torture_comment(tctx, "(%s:%s) new_password[%s] status[%s]\n",
1342 __location__, __FUNCTION__,
1343 newpass, nt_errstr(s2.out.result));
1344 status = s2.out.result;
1346 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
1347 "SetUserInfo failed");
1348 torture_comment(tctx, "(%s:%s) new_password[%s] status[%s]\n",
1349 __location__, __FUNCTION__,
1350 newpass, nt_errstr(s.out.result));
1351 status = s.out.result;
1354 if (!NT_STATUS_IS_OK(status)) {
1355 if (fields_present == 0) {
1356 expected_error = NT_STATUS_INVALID_PARAMETER;
1358 if (fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
1359 expected_error = NT_STATUS_ACCESS_DENIED;
1363 if (!NT_STATUS_IS_OK(expected_error)) {
1365 torture_assert_ntstatus_equal(tctx,
1367 expected_error, "SetUserInfo2 failed");
1369 torture_assert_ntstatus_equal(tctx,
1371 expected_error, "SetUserInfo failed");
1373 *matched_expected_error = true;
1377 if (!NT_STATUS_IS_OK(status)) {
1378 torture_result(tctx, TORTURE_FAIL, "SetUserInfo%s level %u failed - %s\n",
1379 use_setinfo2 ? "2":"", level, nt_errstr(status));
1382 *password = newpass;
1388 static bool test_SetAliasInfo(struct dcerpc_binding_handle *b,
1389 struct torture_context *tctx,
1390 struct policy_handle *handle)
1392 struct samr_SetAliasInfo r;
1393 struct samr_QueryAliasInfo q;
1394 union samr_AliasInfo *info;
1395 uint16_t levels[] = {2, 3};
1399 /* Ignoring switch level 1, as that includes the number of members for the alias
1400 * and setting this to a wrong value might have negative consequences
1403 for (i=0;i<ARRAY_SIZE(levels);i++) {
1404 torture_comment(tctx, "Testing SetAliasInfo level %u\n", levels[i]);
1406 r.in.alias_handle = handle;
1407 r.in.level = levels[i];
1408 r.in.info = talloc(tctx, union samr_AliasInfo);
1409 switch (r.in.level) {
1410 case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
1411 case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
1412 "Test Description, should test I18N as well"); break;
1413 case ALIASINFOALL: torture_comment(tctx, "ALIASINFOALL ignored\n"); break;
1416 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetAliasInfo_r(b, tctx, &r),
1417 "SetAliasInfo failed");
1418 if (!NT_STATUS_IS_OK(r.out.result)) {
1419 torture_result(tctx, TORTURE_FAIL, "SetAliasInfo level %u failed - %s\n",
1420 levels[i], nt_errstr(r.out.result));
1424 q.in.alias_handle = handle;
1425 q.in.level = levels[i];
1428 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryAliasInfo_r(b, tctx, &q),
1429 "QueryAliasInfo failed");
1430 if (!NT_STATUS_IS_OK(q.out.result)) {
1431 torture_result(tctx, TORTURE_FAIL, "QueryAliasInfo level %u failed - %s\n",
1432 levels[i], nt_errstr(q.out.result));
1440 static bool test_GetGroupsForUser(struct dcerpc_binding_handle *b,
1441 struct torture_context *tctx,
1442 struct policy_handle *user_handle)
1444 struct samr_GetGroupsForUser r;
1445 struct samr_RidWithAttributeArray *rids = NULL;
1447 torture_comment(tctx, "Testing GetGroupsForUser\n");
1449 r.in.user_handle = user_handle;
1452 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetGroupsForUser_r(b, tctx, &r),
1453 "GetGroupsForUser failed");
1454 torture_assert_ntstatus_ok(tctx, r.out.result, "GetGroupsForUser failed");
1460 static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1461 struct lsa_String *domain_name)
1463 struct samr_GetDomPwInfo r;
1464 struct samr_PwInfo info;
1465 struct dcerpc_binding_handle *b = p->binding_handle;
1467 r.in.domain_name = domain_name;
1470 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1472 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDomPwInfo_r(b, tctx, &r),
1473 "GetDomPwInfo failed");
1474 torture_assert_ntstatus_ok(tctx, r.out.result, "GetDomPwInfo failed");
1476 r.in.domain_name->string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1477 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1479 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDomPwInfo_r(b, tctx, &r),
1480 "GetDomPwInfo failed");
1481 torture_assert_ntstatus_ok(tctx, r.out.result, "GetDomPwInfo failed");
1483 r.in.domain_name->string = "\\\\__NONAME__";
1484 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1486 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDomPwInfo_r(b, tctx, &r),
1487 "GetDomPwInfo failed");
1488 torture_assert_ntstatus_ok(tctx, r.out.result, "GetDomPwInfo failed");
1490 r.in.domain_name->string = "\\\\Builtin";
1491 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1493 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDomPwInfo_r(b, tctx, &r),
1494 "GetDomPwInfo failed");
1495 torture_assert_ntstatus_ok(tctx, r.out.result, "GetDomPwInfo failed");
1500 static bool test_GetUserPwInfo(struct dcerpc_binding_handle *b,
1501 struct torture_context *tctx,
1502 struct policy_handle *handle)
1504 struct samr_GetUserPwInfo r;
1505 struct samr_PwInfo info;
1507 torture_comment(tctx, "Testing GetUserPwInfo\n");
1509 r.in.user_handle = handle;
1512 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &r),
1513 "GetUserPwInfo failed");
1514 torture_assert_ntstatus_ok(tctx, r.out.result, "GetUserPwInfo");
1519 static NTSTATUS test_LookupName(struct dcerpc_binding_handle *b,
1520 struct torture_context *tctx,
1521 struct policy_handle *domain_handle, const char *name,
1525 struct samr_LookupNames n;
1526 struct lsa_String sname[2];
1527 struct samr_Ids rids, types;
1529 init_lsa_String(&sname[0], name);
1531 n.in.domain_handle = domain_handle;
1535 n.out.types = &types;
1536 status = dcerpc_samr_LookupNames_r(b, tctx, &n);
1537 if (!NT_STATUS_IS_OK(status)) {
1540 if (NT_STATUS_IS_OK(n.out.result)) {
1541 *rid = n.out.rids->ids[0];
1543 return n.out.result;
1546 init_lsa_String(&sname[1], "xxNONAMExx");
1548 status = dcerpc_samr_LookupNames_r(b, tctx, &n);
1549 if (!NT_STATUS_IS_OK(status)) {
1552 if (!NT_STATUS_EQUAL(n.out.result, STATUS_SOME_UNMAPPED)) {
1553 torture_result(tctx, TORTURE_FAIL, "LookupNames[2] failed - %s\n", nt_errstr(n.out.result));
1554 if (NT_STATUS_IS_OK(n.out.result)) {
1555 return NT_STATUS_UNSUCCESSFUL;
1557 return n.out.result;
1561 status = dcerpc_samr_LookupNames_r(b, tctx, &n);
1562 if (!NT_STATUS_IS_OK(status)) {
1565 if (!NT_STATUS_IS_OK(n.out.result)) {
1566 torture_result(tctx, TORTURE_FAIL, "LookupNames[0] failed - %s\n", nt_errstr(status));
1567 return n.out.result;
1570 init_lsa_String(&sname[0], "xxNONAMExx");
1572 status = dcerpc_samr_LookupNames_r(b, tctx, &n);
1573 if (!NT_STATUS_IS_OK(status)) {
1576 if (!NT_STATUS_EQUAL(n.out.result, NT_STATUS_NONE_MAPPED)) {
1577 torture_result(tctx, TORTURE_FAIL, "LookupNames[1 bad name] failed - %s\n", nt_errstr(n.out.result));
1578 if (NT_STATUS_IS_OK(n.out.result)) {
1579 return NT_STATUS_UNSUCCESSFUL;
1581 return n.out.result;
1584 init_lsa_String(&sname[0], "xxNONAMExx");
1585 init_lsa_String(&sname[1], "xxNONAME2xx");
1587 status = dcerpc_samr_LookupNames_r(b, tctx, &n);
1588 if (!NT_STATUS_IS_OK(status)) {
1591 if (!NT_STATUS_EQUAL(n.out.result, NT_STATUS_NONE_MAPPED)) {
1592 torture_result(tctx, TORTURE_FAIL, "LookupNames[2 bad names] failed - %s\n", nt_errstr(n.out.result));
1593 if (NT_STATUS_IS_OK(n.out.result)) {
1594 return NT_STATUS_UNSUCCESSFUL;
1596 return n.out.result;
1599 return NT_STATUS_OK;
1602 static NTSTATUS test_OpenUser_byname(struct dcerpc_binding_handle *b,
1603 struct torture_context *tctx,
1604 struct policy_handle *domain_handle,
1605 const char *name, struct policy_handle *user_handle)
1608 struct samr_OpenUser r;
1611 status = test_LookupName(b, tctx, domain_handle, name, &rid);
1612 if (!NT_STATUS_IS_OK(status)) {
1616 r.in.domain_handle = domain_handle;
1617 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1619 r.out.user_handle = user_handle;
1620 status = dcerpc_samr_OpenUser_r(b, tctx, &r);
1621 if (!NT_STATUS_IS_OK(status)) {
1624 if (!NT_STATUS_IS_OK(r.out.result)) {
1625 torture_result(tctx, TORTURE_FAIL, "OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(r.out.result));
1628 return r.out.result;
1632 static bool test_ChangePasswordNT3(struct dcerpc_pipe *p,
1633 struct torture_context *tctx,
1634 struct policy_handle *handle)
1637 struct samr_ChangePasswordUser r;
1639 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1640 struct policy_handle user_handle;
1641 char *oldpass = "test";
1642 char *newpass = "test2";
1643 uint8_t old_nt_hash[16], new_nt_hash[16];
1644 uint8_t old_lm_hash[16], new_lm_hash[16];
1646 status = test_OpenUser_byname(p, tctx, handle, "testuser", &user_handle);
1647 if (!NT_STATUS_IS_OK(status)) {
1651 torture_comment(tctx, "Testing ChangePasswordUser for user 'testuser'\n");
1653 torture_comment(tctx, "old password: %s\n", oldpass);
1654 torture_comment(tctx, "new password: %s\n", newpass);
1656 E_md4hash(oldpass, old_nt_hash);
1657 E_md4hash(newpass, new_nt_hash);
1658 E_deshash(oldpass, old_lm_hash);
1659 E_deshash(newpass, new_lm_hash);
1661 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1662 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1663 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1664 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1665 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1666 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1668 r.in.handle = &user_handle;
1669 r.in.lm_present = 1;
1670 r.in.old_lm_crypted = &hash1;
1671 r.in.new_lm_crypted = &hash2;
1672 r.in.nt_present = 1;
1673 r.in.old_nt_crypted = &hash3;
1674 r.in.new_nt_crypted = &hash4;
1675 r.in.cross1_present = 1;
1676 r.in.nt_cross = &hash5;
1677 r.in.cross2_present = 1;
1678 r.in.lm_cross = &hash6;
1680 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1681 "ChangePasswordUser failed");
1682 if (!NT_STATUS_IS_OK(r.out.result)) {
1683 torture_result(tctx, TORTURE_FAIL, "ChangePasswordUser failed - %s\n", nt_errstr(r.out.result));
1687 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
1695 static bool test_ChangePasswordUser(struct dcerpc_binding_handle *b,
1696 struct torture_context *tctx,
1697 const char *acct_name,
1698 struct policy_handle *handle, char **password)
1701 struct samr_ChangePasswordUser r;
1703 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1704 struct policy_handle user_handle;
1706 uint8_t old_nt_hash[16], new_nt_hash[16];
1707 uint8_t old_lm_hash[16], new_lm_hash[16];
1708 bool changed = true;
1711 struct samr_GetUserPwInfo pwp;
1712 struct samr_PwInfo info;
1713 int policy_min_pw_len = 0;
1715 status = test_OpenUser_byname(b, tctx, handle, acct_name, &user_handle);
1716 if (!NT_STATUS_IS_OK(status)) {
1719 pwp.in.user_handle = &user_handle;
1720 pwp.out.info = &info;
1722 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &pwp),
1723 "GetUserPwInfo failed");
1724 if (NT_STATUS_IS_OK(pwp.out.result)) {
1725 policy_min_pw_len = pwp.out.info->min_password_length;
1727 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1729 torture_comment(tctx, "Testing ChangePasswordUser\n");
1731 torture_assert(tctx, *password != NULL,
1732 "Failing ChangePasswordUser as old password was NULL. Previous test failed?");
1734 oldpass = *password;
1736 E_md4hash(oldpass, old_nt_hash);
1737 E_md4hash(newpass, new_nt_hash);
1738 E_deshash(oldpass, old_lm_hash);
1739 E_deshash(newpass, new_lm_hash);
1741 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1742 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1743 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1744 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1745 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1746 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1748 r.in.user_handle = &user_handle;
1749 r.in.lm_present = 1;
1750 /* Break the NT hash */
1752 r.in.old_lm_crypted = &hash1;
1753 r.in.new_lm_crypted = &hash2;
1754 r.in.nt_present = 1;
1755 r.in.old_nt_crypted = &hash3;
1756 r.in.new_nt_crypted = &hash4;
1757 r.in.cross1_present = 1;
1758 r.in.nt_cross = &hash5;
1759 r.in.cross2_present = 1;
1760 r.in.lm_cross = &hash6;
1762 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1763 "ChangePasswordUser failed");
1764 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
1765 __location__, __FUNCTION__,
1766 oldpass, newpass, nt_errstr(r.out.result));
1768 /* Do not proceed if this call has been removed */
1769 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_IMPLEMENTED)) {
1770 torture_skip(tctx, "ValidatePassword not supported by server\n");
1773 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
1774 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_WRONG_PASSWORD,
1775 "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash");
1778 /* Unbreak the NT hash */
1781 r.in.user_handle = &user_handle;
1782 r.in.lm_present = 1;
1783 r.in.old_lm_crypted = &hash1;
1784 r.in.new_lm_crypted = &hash2;
1785 /* Break the LM hash */
1787 r.in.nt_present = 1;
1788 r.in.old_nt_crypted = &hash3;
1789 r.in.new_nt_crypted = &hash4;
1790 r.in.cross1_present = 1;
1791 r.in.nt_cross = &hash5;
1792 r.in.cross2_present = 1;
1793 r.in.lm_cross = &hash6;
1795 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1796 "ChangePasswordUser failed");
1797 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
1798 __location__, __FUNCTION__,
1799 oldpass, newpass, nt_errstr(r.out.result));
1800 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
1801 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_WRONG_PASSWORD,
1802 "expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash");
1805 /* Unbreak the NT hash */
1808 r.in.user_handle = &user_handle;
1809 r.in.lm_present = 1;
1810 r.in.old_lm_crypted = &hash1;
1811 r.in.new_lm_crypted = &hash2;
1812 r.in.nt_present = 1;
1813 r.in.old_nt_crypted = &hash3;
1814 r.in.new_nt_crypted = &hash4;
1815 r.in.cross1_present = 1;
1816 r.in.nt_cross = &hash5;
1817 r.in.cross2_present = 1;
1818 /* Break the LM cross */
1820 r.in.lm_cross = &hash6;
1822 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1823 "ChangePasswordUser failed");
1824 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
1825 __location__, __FUNCTION__,
1826 oldpass, newpass, nt_errstr(r.out.result));
1827 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD) &&
1828 !NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION))
1830 torture_result(tctx, TORTURE_FAIL, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD or NT_STATUS_PASSWORD_RESTRICTION because we broke the LM cross-hash, got %s\n", nt_errstr(r.out.result));
1834 /* Unbreak the LM cross */
1837 r.in.user_handle = &user_handle;
1838 r.in.lm_present = 1;
1839 r.in.old_lm_crypted = &hash1;
1840 r.in.new_lm_crypted = &hash2;
1841 r.in.nt_present = 1;
1842 r.in.old_nt_crypted = &hash3;
1843 r.in.new_nt_crypted = &hash4;
1844 r.in.cross1_present = 1;
1845 /* Break the NT cross */
1847 r.in.nt_cross = &hash5;
1848 r.in.cross2_present = 1;
1849 r.in.lm_cross = &hash6;
1851 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1852 "ChangePasswordUser failed");
1853 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
1854 __location__, __FUNCTION__,
1855 oldpass, newpass, nt_errstr(r.out.result));
1856 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD) &&
1857 !NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION))
1859 torture_result(tctx, TORTURE_FAIL, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD or NT_STATUS_PASSWORD_RESTRICTION because we broke the NT cross-hash, got %s\n", nt_errstr(r.out.result));
1863 /* Unbreak the NT cross */
1867 /* Reset the hashes to not broken values */
1868 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1869 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1870 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1871 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1872 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1873 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1875 r.in.user_handle = &user_handle;
1876 r.in.lm_present = 1;
1877 r.in.old_lm_crypted = &hash1;
1878 r.in.new_lm_crypted = &hash2;
1879 r.in.nt_present = 1;
1880 r.in.old_nt_crypted = &hash3;
1881 r.in.new_nt_crypted = &hash4;
1882 r.in.cross1_present = 1;
1883 r.in.nt_cross = &hash5;
1884 r.in.cross2_present = 0;
1885 r.in.lm_cross = NULL;
1887 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1888 "ChangePasswordUser failed");
1889 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
1890 __location__, __FUNCTION__,
1891 oldpass, newpass, nt_errstr(r.out.result));
1892 if (NT_STATUS_IS_OK(r.out.result)) {
1894 *password = newpass;
1895 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, r.out.result)) {
1896 torture_result(tctx, TORTURE_FAIL, "ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(r.out.result));
1901 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1903 E_md4hash(oldpass, old_nt_hash);
1904 E_md4hash(newpass, new_nt_hash);
1905 E_deshash(oldpass, old_lm_hash);
1906 E_deshash(newpass, new_lm_hash);
1909 /* Reset the hashes to not broken values */
1910 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1911 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1912 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1913 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1914 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1915 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1917 r.in.user_handle = &user_handle;
1918 r.in.lm_present = 1;
1919 r.in.old_lm_crypted = &hash1;
1920 r.in.new_lm_crypted = &hash2;
1921 r.in.nt_present = 1;
1922 r.in.old_nt_crypted = &hash3;
1923 r.in.new_nt_crypted = &hash4;
1924 r.in.cross1_present = 0;
1925 r.in.nt_cross = NULL;
1926 r.in.cross2_present = 1;
1927 r.in.lm_cross = &hash6;
1929 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1930 "ChangePasswordUser failed");
1931 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
1932 __location__, __FUNCTION__,
1933 oldpass, newpass, nt_errstr(r.out.result));
1934 if (NT_STATUS_IS_OK(r.out.result)) {
1936 *password = newpass;
1937 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, r.out.result)) {
1938 torture_result(tctx, TORTURE_FAIL, "ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(r.out.result));
1943 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1945 E_md4hash(oldpass, old_nt_hash);
1946 E_md4hash(newpass, new_nt_hash);
1947 E_deshash(oldpass, old_lm_hash);
1948 E_deshash(newpass, new_lm_hash);
1951 /* Reset the hashes to not broken values */
1952 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1953 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1954 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1955 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1956 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1957 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1959 r.in.user_handle = &user_handle;
1960 r.in.lm_present = 1;
1961 r.in.old_lm_crypted = &hash1;
1962 r.in.new_lm_crypted = &hash2;
1963 r.in.nt_present = 1;
1964 r.in.old_nt_crypted = &hash3;
1965 r.in.new_nt_crypted = &hash4;
1966 r.in.cross1_present = 1;
1967 r.in.nt_cross = &hash5;
1968 r.in.cross2_present = 1;
1969 r.in.lm_cross = &hash6;
1971 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1972 "ChangePasswordUser failed");
1973 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
1974 __location__, __FUNCTION__,
1975 oldpass, newpass, nt_errstr(r.out.result));
1976 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
1977 torture_comment(tctx, "ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(r.out.result));
1978 } else if (!NT_STATUS_IS_OK(r.out.result)) {
1979 torture_result(tctx, TORTURE_FAIL, "ChangePasswordUser failed - %s\n", nt_errstr(r.out.result));
1983 *password = newpass;
1986 r.in.user_handle = &user_handle;
1987 r.in.lm_present = 1;
1988 r.in.old_lm_crypted = &hash1;
1989 r.in.new_lm_crypted = &hash2;
1990 r.in.nt_present = 1;
1991 r.in.old_nt_crypted = &hash3;
1992 r.in.new_nt_crypted = &hash4;
1993 r.in.cross1_present = 1;
1994 r.in.nt_cross = &hash5;
1995 r.in.cross2_present = 1;
1996 r.in.lm_cross = &hash6;
1999 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
2000 "ChangePasswordUser failed");
2001 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2002 __location__, __FUNCTION__,
2003 oldpass, newpass, nt_errstr(r.out.result));
2004 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
2005 torture_comment(tctx, "ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(r.out.result));
2006 } else if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD)) {
2007 torture_result(tctx, TORTURE_FAIL, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(r.out.result));
2013 if (!test_samr_handle_Close(b, tctx, &user_handle)) {
2021 static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p,
2022 struct torture_context *tctx,
2023 const char *acct_name,
2024 struct policy_handle *handle, char **password)
2026 struct samr_OemChangePasswordUser2 r;
2028 struct samr_Password lm_verifier;
2029 struct samr_CryptPassword lm_pass;
2030 struct lsa_AsciiString server, account, account_bad;
2033 struct dcerpc_binding_handle *b = p->binding_handle;
2034 uint8_t old_lm_hash[16], new_lm_hash[16];
2035 gnutls_cipher_hd_t cipher_hnd = NULL;
2036 gnutls_datum_t session_key = {
2037 .data = old_lm_hash,
2041 struct samr_GetDomPwInfo dom_pw_info;
2042 struct samr_PwInfo info;
2043 int policy_min_pw_len = 0;
2045 struct lsa_String domain_name;
2047 domain_name.string = "";
2048 dom_pw_info.in.domain_name = &domain_name;
2049 dom_pw_info.out.info = &info;
2051 torture_comment(tctx, "Testing OemChangePasswordUser2\n");
2053 torture_assert(tctx, *password != NULL,
2054 "Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?");
2056 oldpass = *password;
2058 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDomPwInfo_r(b, tctx, &dom_pw_info),
2059 "GetDomPwInfo failed");
2060 if (NT_STATUS_IS_OK(dom_pw_info.out.result)) {
2061 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
2064 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2066 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2067 account.string = acct_name;
2069 E_deshash(oldpass, old_lm_hash);
2070 E_deshash(newpass, new_lm_hash);
2072 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
2074 gnutls_cipher_init(&cipher_hnd,
2075 GNUTLS_CIPHER_ARCFOUR_128,
2078 gnutls_cipher_encrypt(cipher_hnd, lm_pass.data, 516);
2079 gnutls_cipher_deinit(cipher_hnd);
2080 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
2082 r.in.server = &server;
2083 r.in.account = &account;
2084 r.in.password = &lm_pass;
2085 r.in.hash = &lm_verifier;
2087 /* Break the verification */
2088 lm_verifier.hash[0]++;
2090 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
2091 "OemChangePasswordUser2 failed");
2092 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2093 __location__, __FUNCTION__,
2094 oldpass, newpass, nt_errstr(r.out.result));
2096 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)
2097 && !NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD)) {
2098 torture_result(tctx, TORTURE_FAIL, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
2099 nt_errstr(r.out.result));
2103 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
2104 /* Break the old password */
2106 gnutls_cipher_init(&cipher_hnd,
2107 GNUTLS_CIPHER_ARCFOUR_128,
2110 gnutls_cipher_encrypt(cipher_hnd, lm_pass.data, 516);
2111 gnutls_cipher_deinit(cipher_hnd);
2112 /* unbreak it for the next operation */
2114 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
2116 r.in.server = &server;
2117 r.in.account = &account;
2118 r.in.password = &lm_pass;
2119 r.in.hash = &lm_verifier;
2121 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
2122 "OemChangePasswordUser2 failed");
2123 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2124 __location__, __FUNCTION__,
2125 oldpass, newpass, nt_errstr(r.out.result));
2127 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)
2128 && !NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD)) {
2129 torture_result(tctx, TORTURE_FAIL, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
2130 nt_errstr(r.out.result));
2134 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
2135 gnutls_cipher_init(&cipher_hnd,
2136 GNUTLS_CIPHER_ARCFOUR_128,
2139 gnutls_cipher_encrypt(cipher_hnd, lm_pass.data, 516);
2140 gnutls_cipher_deinit(cipher_hnd);
2142 r.in.server = &server;
2143 r.in.account = &account;
2144 r.in.password = &lm_pass;
2147 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
2148 "OemChangePasswordUser2 failed");
2149 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2150 __location__, __FUNCTION__,
2151 oldpass, newpass, nt_errstr(r.out.result));
2153 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)
2154 && !NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
2155 torture_result(tctx, TORTURE_FAIL, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
2156 nt_errstr(r.out.result));
2160 /* This shouldn't be a valid name */
2161 account_bad.string = TEST_ACCOUNT_NAME "XX";
2162 r.in.account = &account_bad;
2164 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
2165 "OemChangePasswordUser2 failed");
2166 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2167 __location__, __FUNCTION__,
2168 oldpass, newpass, nt_errstr(r.out.result));
2170 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
2171 torture_result(tctx, TORTURE_FAIL, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
2172 nt_errstr(r.out.result));
2176 /* This shouldn't be a valid name */
2177 account_bad.string = TEST_ACCOUNT_NAME "XX";
2178 r.in.account = &account_bad;
2179 r.in.password = &lm_pass;
2180 r.in.hash = &lm_verifier;
2182 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
2183 "OemChangePasswordUser2 failed");
2184 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2185 __location__, __FUNCTION__,
2186 oldpass, newpass, nt_errstr(r.out.result));
2188 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD)) {
2189 torture_result(tctx, TORTURE_FAIL, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
2190 nt_errstr(r.out.result));
2194 /* This shouldn't be a valid name */
2195 account_bad.string = TEST_ACCOUNT_NAME "XX";
2196 r.in.account = &account_bad;
2197 r.in.password = NULL;
2198 r.in.hash = &lm_verifier;
2200 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
2201 "OemChangePasswordUser2 failed");
2202 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2203 __location__, __FUNCTION__,
2204 oldpass, newpass, nt_errstr(r.out.result));
2206 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
2207 torture_result(tctx, TORTURE_FAIL, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
2208 nt_errstr(r.out.result));
2212 E_deshash(oldpass, old_lm_hash);
2213 E_deshash(newpass, new_lm_hash);
2215 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
2216 gnutls_cipher_init(&cipher_hnd,
2217 GNUTLS_CIPHER_ARCFOUR_128,
2220 gnutls_cipher_encrypt(cipher_hnd, lm_pass.data, 516);
2221 gnutls_cipher_deinit(cipher_hnd);
2222 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
2224 r.in.server = &server;
2225 r.in.account = &account;
2226 r.in.password = &lm_pass;
2227 r.in.hash = &lm_verifier;
2229 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
2230 "OemChangePasswordUser2 failed");
2231 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2232 __location__, __FUNCTION__,
2233 oldpass, newpass, nt_errstr(r.out.result));
2235 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
2236 torture_comment(tctx, "OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(r.out.result));
2237 } else if (!NT_STATUS_IS_OK(r.out.result)) {
2238 torture_result(tctx, TORTURE_FAIL, "OemChangePasswordUser2 failed - %s\n", nt_errstr(r.out.result));
2241 *password = newpass;
2248 static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
2249 const char *acct_name,
2251 char *newpass, bool allow_password_restriction)
2253 struct samr_ChangePasswordUser2 r;
2255 struct lsa_String server, account;
2256 struct samr_CryptPassword nt_pass, lm_pass;
2257 struct samr_Password nt_verifier, lm_verifier;
2259 struct dcerpc_binding_handle *b = p->binding_handle;
2260 uint8_t old_nt_hash[16], new_nt_hash[16];
2261 uint8_t old_lm_hash[16], new_lm_hash[16];
2262 DATA_BLOB old_nt_hash_blob
2263 = data_blob_const(old_nt_hash, sizeof(old_nt_hash));
2264 struct samr_GetDomPwInfo dom_pw_info;
2265 struct samr_PwInfo info;
2267 struct lsa_String domain_name;
2270 domain_name.string = "";
2271 dom_pw_info.in.domain_name = &domain_name;
2272 dom_pw_info.out.info = &info;
2274 torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name);
2276 torture_assert(tctx, *password != NULL,
2277 "Failing ChangePasswordUser2 as old password was NULL. Previous test failed?");
2278 oldpass = *password;
2281 int policy_min_pw_len = 0;
2282 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDomPwInfo_r(b, tctx, &dom_pw_info),
2283 "GetDomPwInfo failed");
2284 if (NT_STATUS_IS_OK(dom_pw_info.out.result)) {
2285 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
2288 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2291 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2292 init_lsa_String(&account, acct_name);
2294 E_md4hash(oldpass, old_nt_hash);
2295 E_md4hash(newpass, new_nt_hash);
2297 E_deshash(oldpass, old_lm_hash);
2298 E_deshash(newpass, new_lm_hash);
2300 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
2301 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2302 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2304 status = init_samr_CryptPassword(newpass,
2307 torture_assert_ntstatus_ok(tctx,
2309 "init_samr_CryptPassword failed");
2311 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2313 r.in.server = &server;
2314 r.in.account = &account;
2315 r.in.nt_password = &nt_pass;
2316 r.in.nt_verifier = &nt_verifier;
2318 r.in.lm_password = &lm_pass;
2319 r.in.lm_verifier = &lm_verifier;
2321 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser2_r(b, tctx, &r),
2322 "ChangePasswordUser2 failed");
2323 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2324 __location__, __FUNCTION__,
2325 oldpass, newpass, nt_errstr(r.out.result));
2327 if (allow_password_restriction && NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
2328 torture_comment(tctx, "ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(r.out.result));
2329 } else if (!NT_STATUS_IS_OK(r.out.result)) {
2330 torture_result(tctx, TORTURE_FAIL, "ChangePasswordUser2 failed - %s\n", nt_errstr(r.out.result));
2333 *password = newpass;
2340 static bool test_ChangePasswordUser2_ntstatus(struct dcerpc_pipe *p, struct torture_context *tctx,
2341 const char *acct_name,
2342 const char *password, NTSTATUS status)
2344 struct samr_ChangePasswordUser2 r;
2345 struct lsa_String server, account;
2346 struct samr_CryptPassword nt_pass, lm_pass;
2347 struct samr_Password nt_verifier, lm_verifier;
2348 const char *oldpass;
2349 struct dcerpc_binding_handle *b = p->binding_handle;
2350 uint8_t old_nt_hash[16], new_nt_hash[16];
2351 uint8_t old_lm_hash[16], new_lm_hash[16];
2353 struct samr_GetDomPwInfo dom_pw_info;
2354 struct samr_PwInfo info;
2356 struct lsa_String domain_name;
2358 int policy_min_pw_len = 0;
2360 domain_name.string = "";
2361 dom_pw_info.in.domain_name = &domain_name;
2362 dom_pw_info.out.info = &info;
2364 torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name);
2368 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDomPwInfo_r(b, tctx, &dom_pw_info),
2369 "GetDomPwInfo failed");
2370 if (NT_STATUS_IS_OK(dom_pw_info.out.result)) {
2371 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
2374 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2376 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2377 init_lsa_String(&account, acct_name);
2379 E_md4hash(oldpass, old_nt_hash);
2380 E_md4hash(newpass, new_nt_hash);
2382 E_deshash(oldpass, old_lm_hash);
2383 E_deshash(newpass, new_lm_hash);
2385 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
2386 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2387 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2389 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2390 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2391 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2393 r.in.server = &server;
2394 r.in.account = &account;
2395 r.in.nt_password = &nt_pass;
2396 r.in.nt_verifier = &nt_verifier;
2398 r.in.lm_password = &lm_pass;
2399 r.in.lm_verifier = &lm_verifier;
2401 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser2_r(b, tctx, &r),
2402 "ChangePasswordUser2 failed");
2403 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2404 __location__, __FUNCTION__,
2405 oldpass, newpass, nt_errstr(r.out.result));
2407 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
2408 torture_comment(tctx, "ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(r.out.result));
2410 torture_assert_ntstatus_equal(tctx, r.out.result, status, "ChangePasswordUser2 returned unexpected value");
2417 bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tctx,
2418 const char *account_string,
2419 int policy_min_pw_len,
2421 const char *newpass,
2422 NTTIME last_password_change,
2423 bool handle_reject_reason)
2425 struct samr_ChangePasswordUser3 r;
2427 struct lsa_String server, account, account_bad;
2428 struct samr_CryptPassword nt_pass, lm_pass;
2429 struct samr_Password nt_verifier, lm_verifier;
2431 struct dcerpc_binding_handle *b = p->binding_handle;
2432 uint8_t old_nt_hash[16], new_nt_hash[16];
2433 uint8_t old_lm_hash[16], new_lm_hash[16];
2435 struct samr_DomInfo1 *dominfo = NULL;
2436 struct userPwdChangeFailureInformation *reject = NULL;
2438 torture_comment(tctx, "Testing ChangePasswordUser3\n");
2440 if (newpass == NULL) {
2442 if (policy_min_pw_len == 0) {
2443 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2445 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len);
2447 } while (check_password_quality(newpass) == false);
2449 torture_comment(tctx, "Using password '%s'\n", newpass);
2452 torture_assert(tctx, *password != NULL,
2453 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2455 oldpass = *password;
2456 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2457 init_lsa_String(&account, account_string);
2459 E_md4hash(oldpass, old_nt_hash);
2460 E_md4hash(newpass, new_nt_hash);
2462 E_deshash(oldpass, old_lm_hash);
2463 E_deshash(newpass, new_lm_hash);
2465 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2466 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2467 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2469 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2470 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2471 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2473 /* Break the verification */
2474 nt_verifier.hash[0]++;
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 = &lm_pass;
2482 r.in.lm_verifier = &lm_verifier;
2483 r.in.password3 = NULL;
2484 r.out.dominfo = &dominfo;
2485 r.out.reject = &reject;
2487 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2488 "ChangePasswordUser3 failed");
2489 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2490 __location__, __FUNCTION__,
2491 oldpass, newpass, nt_errstr(r.out.result));
2492 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION) &&
2493 (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD))) {
2494 torture_result(tctx, TORTURE_FAIL, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
2495 nt_errstr(r.out.result));
2499 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2500 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2501 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2503 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2504 /* Break the NT hash */
2506 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2507 /* Unbreak it again */
2509 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2511 r.in.server = &server;
2512 r.in.account = &account;
2513 r.in.nt_password = &nt_pass;
2514 r.in.nt_verifier = &nt_verifier;
2516 r.in.lm_password = &lm_pass;
2517 r.in.lm_verifier = &lm_verifier;
2518 r.in.password3 = NULL;
2519 r.out.dominfo = &dominfo;
2520 r.out.reject = &reject;
2522 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2523 "ChangePasswordUser3 failed");
2524 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2525 __location__, __FUNCTION__,
2526 oldpass, newpass, nt_errstr(r.out.result));
2527 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION) &&
2528 (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD))) {
2529 torture_result(tctx, TORTURE_FAIL, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
2530 nt_errstr(r.out.result));
2534 /* This shouldn't be a valid name */
2535 init_lsa_String(&account_bad, talloc_asprintf(tctx, "%sXX", account_string));
2537 r.in.account = &account_bad;
2538 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2539 "ChangePasswordUser3 failed");
2540 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2541 __location__, __FUNCTION__,
2542 oldpass, newpass, nt_errstr(r.out.result));
2543 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD)) {
2544 torture_result(tctx, TORTURE_FAIL, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
2545 nt_errstr(r.out.result));
2549 E_md4hash(oldpass, old_nt_hash);
2550 E_md4hash(newpass, new_nt_hash);
2552 E_deshash(oldpass, old_lm_hash);
2553 E_deshash(newpass, new_lm_hash);
2555 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2556 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2557 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2559 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2560 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2561 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2563 r.in.server = &server;
2564 r.in.account = &account;
2565 r.in.nt_password = &nt_pass;
2566 r.in.nt_verifier = &nt_verifier;
2568 r.in.lm_password = &lm_pass;
2569 r.in.lm_verifier = &lm_verifier;
2570 r.in.password3 = NULL;
2571 r.out.dominfo = &dominfo;
2572 r.out.reject = &reject;
2574 unix_to_nt_time(&t, time(NULL));
2576 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2577 "ChangePasswordUser3 failed");
2578 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2579 __location__, __FUNCTION__,
2580 oldpass, newpass, nt_errstr(r.out.result));
2582 torture_comment(tctx, "(%s): dominfo[%s], reject[%s], handle_reject_reason[%s], "
2583 "last_password_change[%s], dominfo->min_password_age[%lld]\n",
2585 (dominfo == NULL)? "NULL" : "present",
2586 reject ? "true" : "false",
2587 handle_reject_reason ? "true" : "false",
2588 null_nttime(last_password_change) ? "null" : "not null",
2589 dominfo ? (long long)dominfo->min_password_age : (long long)0);
2591 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)
2594 && handle_reject_reason
2595 && (!null_nttime(last_password_change) || !dominfo->min_password_age)) {
2596 if (dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
2598 if (reject && (reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR)) {
2599 torture_result(tctx, TORTURE_FAIL, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2600 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2605 /* We tested the order of precendence which is as follows:
2614 if ((dominfo->min_password_age < 0) && !null_nttime(last_password_change) &&
2615 (last_password_change - dominfo->min_password_age > t)) {
2617 if (reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2618 torture_result(tctx, TORTURE_FAIL, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2619 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2623 } else if ((dominfo->min_password_length > 0) &&
2624 (strlen(newpass) < dominfo->min_password_length)) {
2626 if (reject->extendedFailureReason != SAM_PWD_CHANGE_PASSWORD_TOO_SHORT) {
2627 torture_result(tctx, TORTURE_FAIL, "expected SAM_PWD_CHANGE_PASSWORD_TOO_SHORT (%d), got %d\n",
2628 SAM_PWD_CHANGE_PASSWORD_TOO_SHORT, reject->extendedFailureReason);
2632 } else if ((dominfo->password_history_length > 0) &&
2633 strequal(oldpass, newpass)) {
2635 if (reject->extendedFailureReason != SAM_PWD_CHANGE_PWD_IN_HISTORY) {
2636 torture_result(tctx, TORTURE_FAIL, "expected SAM_PWD_CHANGE_PWD_IN_HISTORY (%d), got %d\n",
2637 SAM_PWD_CHANGE_PWD_IN_HISTORY, reject->extendedFailureReason);
2640 } else if (dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
2642 if (reject->extendedFailureReason != SAM_PWD_CHANGE_NOT_COMPLEX) {
2643 torture_result(tctx, TORTURE_FAIL, "expected SAM_PWD_CHANGE_NOT_COMPLEX (%d), got %d\n",
2644 SAM_PWD_CHANGE_NOT_COMPLEX, reject->extendedFailureReason);
2650 if (reject->extendedFailureReason == SAM_PWD_CHANGE_PASSWORD_TOO_SHORT) {
2651 /* retry with adjusted size */
2652 return test_ChangePasswordUser3(p, tctx, account_string,
2653 dominfo->min_password_length,
2654 password, NULL, 0, false);
2658 } else if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
2659 if (reject && reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2660 torture_result(tctx, TORTURE_FAIL, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2661 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2664 /* Perhaps the server has a 'min password age' set? */
2667 torture_assert_ntstatus_ok(tctx, r.out.result, "ChangePasswordUser3");
2669 *password = talloc_strdup(tctx, newpass);
2675 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_context *tctx,
2676 const char *account_string,
2677 struct policy_handle *handle,
2681 struct samr_ChangePasswordUser3 r;
2682 struct samr_SetUserInfo s;
2683 union samr_UserInfo u;
2684 DATA_BLOB session_key;
2685 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
2686 uint8_t confounder[16];
2687 gnutls_hash_hd_t hash_hnd;
2690 struct lsa_String server, account;
2691 struct samr_CryptPassword nt_pass;
2692 struct samr_Password nt_verifier;
2693 DATA_BLOB new_random_pass;
2696 struct dcerpc_binding_handle *b = p->binding_handle;
2697 uint8_t old_nt_hash[16], new_nt_hash[16];
2699 struct samr_DomInfo1 *dominfo = NULL;
2700 struct userPwdChangeFailureInformation *reject = NULL;
2702 new_random_pass = samr_very_rand_pass(tctx, 128);
2704 torture_assert(tctx, *password != NULL,
2705 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2707 oldpass = *password;
2708 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2709 init_lsa_String(&account, account_string);
2711 s.in.user_handle = handle;
2717 u.info25.info.fields_present = SAMR_FIELD_NT_PASSWORD_PRESENT;
2719 set_pw_in_buffer(u.info25.password.data, &new_random_pass);
2721 status = dcerpc_fetch_session_key(p, &session_key);
2722 if (!NT_STATUS_IS_OK(status)) {
2723 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u - no session key - %s\n",
2724 s.in.level, nt_errstr(status));
2728 generate_random_buffer((uint8_t *)confounder, 16);
2730 gnutls_hash_init(&hash_hnd, GNUTLS_DIG_MD5);
2731 gnutls_hash(hash_hnd, confounder, 16);
2732 gnutls_hash(hash_hnd, session_key.data, session_key.length);
2733 gnutls_hash_deinit(hash_hnd, confounded_session_key.data);
2735 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
2736 memcpy(&u.info25.password.data[516], confounder, 16);
2738 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
2740 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
2741 "SetUserInfo failed");
2742 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2743 __location__, __FUNCTION__,
2744 oldpass, "RANDOM", nt_errstr(s.out.result));
2745 if (!NT_STATUS_IS_OK(s.out.result)) {
2746 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u failed - %s\n",
2747 s.in.level, nt_errstr(s.out.result));
2751 torture_comment(tctx, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
2753 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2755 new_random_pass = samr_very_rand_pass(tctx, 128);
2757 mdfour(new_nt_hash, new_random_pass.data, new_random_pass.length);
2759 set_pw_in_buffer(nt_pass.data, &new_random_pass);
2760 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2761 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2763 r.in.server = &server;
2764 r.in.account = &account;
2765 r.in.nt_password = &nt_pass;
2766 r.in.nt_verifier = &nt_verifier;
2768 r.in.lm_password = NULL;
2769 r.in.lm_verifier = NULL;
2770 r.in.password3 = NULL;
2771 r.out.dominfo = &dominfo;
2772 r.out.reject = &reject;
2774 unix_to_nt_time(&t, time(NULL));
2776 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2777 "ChangePasswordUser3 failed");
2778 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2779 __location__, __FUNCTION__,
2780 oldpass, "RANDOM", nt_errstr(r.out.result));
2782 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
2783 if (reject && reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2784 torture_result(tctx, TORTURE_FAIL, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2785 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2788 /* Perhaps the server has a 'min password age' set? */
2790 } else if (!NT_STATUS_IS_OK(r.out.result)) {
2791 torture_result(tctx, TORTURE_FAIL, "ChangePasswordUser3 failed - %s\n", nt_errstr(r.out.result));
2795 newpass = samr_rand_pass(tctx, 128);
2797 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2799 E_md4hash(newpass, new_nt_hash);
2801 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2802 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2803 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2805 r.in.server = &server;
2806 r.in.account = &account;
2807 r.in.nt_password = &nt_pass;
2808 r.in.nt_verifier = &nt_verifier;
2810 r.in.lm_password = NULL;
2811 r.in.lm_verifier = NULL;
2812 r.in.password3 = NULL;
2813 r.out.dominfo = &dominfo;
2814 r.out.reject = &reject;
2816 unix_to_nt_time(&t, time(NULL));
2818 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2819 "ChangePasswordUser3 failed");
2820 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2821 __location__, __FUNCTION__,
2822 oldpass, newpass, nt_errstr(r.out.result));
2824 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
2825 if (reject && reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2826 torture_result(tctx, TORTURE_FAIL, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2827 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2830 /* Perhaps the server has a 'min password age' set? */
2833 torture_assert_ntstatus_ok(tctx, r.out.result, "ChangePasswordUser3 (on second random password)");
2834 *password = talloc_strdup(tctx, newpass);
2841 static bool test_GetMembersInAlias(struct dcerpc_binding_handle *b,
2842 struct torture_context *tctx,
2843 struct policy_handle *alias_handle)
2845 struct samr_GetMembersInAlias r;
2846 struct lsa_SidArray sids;
2848 torture_comment(tctx, "Testing GetMembersInAlias\n");
2850 r.in.alias_handle = alias_handle;
2853 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetMembersInAlias_r(b, tctx, &r),
2854 "GetMembersInAlias failed");
2855 torture_assert_ntstatus_ok(tctx, r.out.result, "GetMembersInAlias failed");
2860 static bool test_AddMemberToAlias(struct dcerpc_binding_handle *b,
2861 struct torture_context *tctx,
2862 struct policy_handle *alias_handle,
2863 const struct dom_sid *domain_sid)
2865 struct samr_AddAliasMember r;
2866 struct samr_DeleteAliasMember d;
2867 struct dom_sid *sid;
2869 sid = dom_sid_add_rid(tctx, domain_sid, 512);
2871 torture_comment(tctx, "Testing AddAliasMember\n");
2872 r.in.alias_handle = alias_handle;
2875 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddAliasMember_r(b, tctx, &r),
2876 "AddAliasMember failed");
2877 torture_assert_ntstatus_ok(tctx, r.out.result, "AddAliasMember failed");
2879 d.in.alias_handle = alias_handle;
2882 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteAliasMember_r(b, tctx, &d),
2883 "DeleteAliasMember failed");
2884 torture_assert_ntstatus_ok(tctx, d.out.result, "DelAliasMember failed");
2889 static bool test_AddMultipleMembersToAlias(struct dcerpc_binding_handle *b,
2890 struct torture_context *tctx,
2891 struct policy_handle *alias_handle)
2893 struct samr_AddMultipleMembersToAlias a;
2894 struct samr_RemoveMultipleMembersFromAlias r;
2895 struct lsa_SidArray sids;
2897 torture_comment(tctx, "Testing AddMultipleMembersToAlias\n");
2898 a.in.alias_handle = alias_handle;
2902 sids.sids = talloc_array(tctx, struct lsa_SidPtr, 3);
2904 sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2905 sids.sids[1].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-2");
2906 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-3");
2908 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddMultipleMembersToAlias_r(b, tctx, &a),
2909 "AddMultipleMembersToAlias failed");
2910 torture_assert_ntstatus_ok(tctx, a.out.result, "AddMultipleMembersToAlias");
2913 torture_comment(tctx, "Testing RemoveMultipleMembersFromAlias\n");
2914 r.in.alias_handle = alias_handle;
2917 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RemoveMultipleMembersFromAlias_r(b, tctx, &r),
2918 "RemoveMultipleMembersFromAlias failed");
2919 torture_assert_ntstatus_ok(tctx, r.out.result, "RemoveMultipleMembersFromAlias failed");
2921 /* strange! removing twice doesn't give any error */
2922 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RemoveMultipleMembersFromAlias_r(b, tctx, &r),
2923 "RemoveMultipleMembersFromAlias failed");
2924 torture_assert_ntstatus_ok(tctx, r.out.result, "RemoveMultipleMembersFromAlias failed");
2926 /* but removing an alias that isn't there does */
2927 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-4");
2929 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RemoveMultipleMembersFromAlias_r(b, tctx, &r),
2930 "RemoveMultipleMembersFromAlias failed");
2931 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND, "RemoveMultipleMembersFromAlias");
2936 static bool test_GetAliasMembership(struct dcerpc_binding_handle *b,
2937 struct torture_context *tctx,
2938 struct policy_handle *domain_handle)
2940 struct samr_GetAliasMembership r;
2941 struct lsa_SidArray sids;
2942 struct samr_Ids rids;
2944 torture_comment(tctx, "Testing GetAliasMembership\n");
2946 r.in.domain_handle = domain_handle;
2951 sids.sids = talloc_zero_array(tctx, struct lsa_SidPtr, sids.num_sids);
2953 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetAliasMembership_r(b, tctx, &r),
2954 "GetAliasMembership failed");
2955 torture_assert_ntstatus_ok(tctx, r.out.result,
2956 "samr_GetAliasMembership failed");
2958 torture_assert_int_equal(tctx, sids.num_sids, rids.count,
2959 "protocol misbehaviour");
2962 sids.sids = talloc_zero_array(tctx, struct lsa_SidPtr, sids.num_sids);
2963 sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2965 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetAliasMembership_r(b, tctx, &r),
2966 "samr_GetAliasMembership failed");
2967 torture_assert_ntstatus_ok(tctx, r.out.result,
2968 "samr_GetAliasMembership failed");
2971 /* only true for w2k8 it seems
2972 * win7, xp, w2k3 will return a 0 length array pointer */
2974 if (rids.ids && (rids.count == 0)) {
2975 torture_fail(tctx, "samr_GetAliasMembership returned 0 count and a rids array");
2978 if (!rids.ids && rids.count) {
2979 torture_fail(tctx, "samr_GetAliasMembership returned non-0 count but no rids");
2985 static bool test_TestPrivateFunctionsUser(struct dcerpc_binding_handle *b,
2986 struct torture_context *tctx,
2987 struct policy_handle *user_handle)
2989 struct samr_TestPrivateFunctionsUser r;
2991 torture_comment(tctx, "Testing TestPrivateFunctionsUser\n");
2993 r.in.user_handle = user_handle;
2995 torture_assert_ntstatus_ok(tctx, dcerpc_samr_TestPrivateFunctionsUser_r(b, tctx, &r),
2996 "TestPrivateFunctionsUser failed");
2997 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsUser");
3002 static bool test_QueryUserInfo_pwdlastset(struct dcerpc_binding_handle *b,
3003 struct torture_context *tctx,
3004 struct policy_handle *handle,
3009 uint16_t levels[] = { /* 3, */ 5, 21 };
3011 /* NTTIME pwdlastset3 = 0; */
3012 NTTIME pwdlastset5 = 0;
3013 NTTIME pwdlastset21 = 0;
3015 torture_comment(tctx, "Testing QueryUserInfo%s level 5 and 21 call ",
3016 use_info2 ? "2":"");
3018 for (i=0; i<ARRAY_SIZE(levels); i++) {
3020 struct samr_QueryUserInfo r;
3021 struct samr_QueryUserInfo2 r2;
3022 union samr_UserInfo *info;
3025 r2.in.user_handle = handle;
3026 r2.in.level = levels[i];
3027 r2.out.info = &info;
3028 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo2_r(b, tctx, &r2),
3029 "QueryUserInfo2 failed");
3030 status = r2.out.result;
3033 r.in.user_handle = handle;
3034 r.in.level = levels[i];
3036 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
3037 "QueryUserInfo failed");
3038 status = r.out.result;
3041 if (!NT_STATUS_IS_OK(status) &&
3042 !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
3043 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo%s level %u failed - %s\n",
3044 use_info2 ? "2":"", levels[i], nt_errstr(status));
3048 switch (levels[i]) {
3050 /* pwdlastset3 = info->info3.last_password_change; */
3053 pwdlastset5 = info->info5.last_password_change;
3056 pwdlastset21 = info->info21.last_password_change;
3062 /* torture_assert_int_equal(tctx, pwdlastset3, pwdlastset5,
3063 "pwdlastset mixup"); */
3064 torture_assert_int_equal(tctx, pwdlastset5, pwdlastset21,
3065 "pwdlastset mixup");
3067 *pwdlastset = pwdlastset21;
3069 torture_comment(tctx, "(pwdlastset: %llu)\n",
3070 (unsigned long long) *pwdlastset);
3075 static bool test_SamLogon(struct torture_context *tctx,
3076 struct dcerpc_pipe *p,
3077 struct cli_credentials *machine_credentials,
3078 struct cli_credentials *test_credentials,
3079 NTSTATUS expected_result,
3083 struct netr_LogonSamLogonEx r;
3084 union netr_LogonLevel logon;
3085 union netr_Validation validation;
3086 uint8_t authoritative;
3087 struct netr_IdentityInfo identity;
3088 struct netr_NetworkInfo ninfo;
3089 struct netr_PasswordInfo pinfo;
3090 DATA_BLOB names_blob, chal, lm_resp, nt_resp;
3091 int flags = CLI_CRED_NTLM_AUTH;
3092 uint32_t samlogon_flags = 0;
3093 struct netlogon_creds_CredentialState *creds;
3094 struct netr_Authenticator a;
3095 struct dcerpc_binding_handle *b = p->binding_handle;
3097 torture_assert(tctx, (creds = cli_credentials_get_netlogon_creds(machine_credentials)), "");
3099 if (lpcfg_client_lanman_auth(tctx->lp_ctx)) {
3100 flags |= CLI_CRED_LANMAN_AUTH;
3103 if (lpcfg_client_ntlmv2_auth(tctx->lp_ctx)) {
3104 flags |= CLI_CRED_NTLMv2_AUTH;
3107 cli_credentials_get_ntlm_username_domain(test_credentials, tctx,
3108 &identity.account_name.string,
3109 &identity.domain_name.string);
3111 identity.parameter_control =
3112 MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT |
3113 MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;
3114 identity.logon_id = 0;
3115 identity.workstation.string = cli_credentials_get_workstation(test_credentials);
3118 netlogon_creds_client_authenticator(creds, &a);
3120 if (!E_deshash(cli_credentials_get_password(test_credentials), pinfo.lmpassword.hash)) {
3121 ZERO_STRUCT(pinfo.lmpassword.hash);
3123 E_md4hash(cli_credentials_get_password(test_credentials), pinfo.ntpassword.hash);
3125 if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
3126 netlogon_creds_aes_encrypt(creds, pinfo.lmpassword.hash, 16);
3127 netlogon_creds_aes_encrypt(creds, pinfo.ntpassword.hash, 16);
3128 } else if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
3129 netlogon_creds_arcfour_crypt(creds, pinfo.lmpassword.hash, 16);
3130 netlogon_creds_arcfour_crypt(creds, pinfo.ntpassword.hash, 16);
3132 netlogon_creds_des_encrypt(creds, &pinfo.lmpassword);
3133 netlogon_creds_des_encrypt(creds, &pinfo.ntpassword);
3136 pinfo.identity_info = identity;
3137 logon.password = &pinfo;
3139 r.in.logon_level = NetlogonInteractiveInformation;
3141 generate_random_buffer(ninfo.challenge,
3142 sizeof(ninfo.challenge));
3143 chal = data_blob_const(ninfo.challenge,
3144 sizeof(ninfo.challenge));
3146 names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(test_credentials),
3147 cli_credentials_get_domain(test_credentials));
3149 status = cli_credentials_get_ntlm_response(test_credentials, tctx,
3152 NULL, /* server_timestamp */
3156 torture_assert_ntstatus_ok(tctx, status, "cli_credentials_get_ntlm_response failed");
3158 ninfo.lm.data = lm_resp.data;
3159 ninfo.lm.length = lm_resp.length;
3161 ninfo.nt.data = nt_resp.data;
3162 ninfo.nt.length = nt_resp.length;
3164 ninfo.identity_info = identity;
3165 logon.network = &ninfo;
3167 r.in.logon_level = NetlogonNetworkInformation;
3170 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3171 r.in.computer_name = cli_credentials_get_workstation(test_credentials);
3172 r.in.logon = &logon;
3173 r.in.flags = &samlogon_flags;
3174 r.out.flags = &samlogon_flags;
3175 r.out.validation = &validation;
3176 r.out.authoritative = &authoritative;
3178 torture_comment(tctx, "Testing LogonSamLogon with name %s\n", identity.account_name.string);
3180 r.in.validation_level = 6;
3182 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogonEx_r(b, tctx, &r),
3183 "netr_LogonSamLogonEx failed");
3184 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_INFO_CLASS)) {
3185 r.in.validation_level = 3;
3186 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogonEx_r(b, tctx, &r),
3187 "netr_LogonSamLogonEx failed");
3189 if (!NT_STATUS_IS_OK(r.out.result)) {
3190 torture_assert_ntstatus_equal(tctx, r.out.result, expected_result, "LogonSamLogonEx failed");
3193 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogonEx failed");
3199 static bool test_SamLogon_with_creds(struct torture_context *tctx,
3200 struct dcerpc_pipe *p,
3201 struct cli_credentials *machine_creds,
3202 const char *acct_name,
3203 const char *password,
3204 NTSTATUS expected_samlogon_result,
3208 struct cli_credentials *test_credentials;
3210 test_credentials = cli_credentials_init(tctx);
3212 cli_credentials_set_workstation(test_credentials,
3213 cli_credentials_get_workstation(machine_creds), CRED_SPECIFIED);
3214 cli_credentials_set_domain(test_credentials,
3215 cli_credentials_get_domain(machine_creds), CRED_SPECIFIED);
3216 cli_credentials_set_username(test_credentials,
3217 acct_name, CRED_SPECIFIED);
3218 cli_credentials_set_password(test_credentials,
3219 password, CRED_SPECIFIED);
3221 torture_comment(tctx, "Testing samlogon (%s) as %s password: %s\n",
3222 interactive ? "interactive" : "network", acct_name, password);
3224 if (!test_SamLogon(tctx, p, machine_creds, test_credentials,
3225 expected_samlogon_result, interactive)) {
3226 torture_result(tctx, TORTURE_FAIL, "new password did not work\n");
3233 static bool test_SetPassword_level(struct dcerpc_pipe *p,
3234 struct dcerpc_pipe *np,
3235 struct torture_context *tctx,
3236 struct policy_handle *handle,
3238 uint32_t fields_present,
3239 uint8_t password_expired,
3240 bool *matched_expected_error,
3242 const char *acct_name,
3244 struct cli_credentials *machine_creds,
3245 bool use_queryinfo2,
3247 NTSTATUS expected_samlogon_result)
3249 const char *fields = NULL;
3251 struct dcerpc_binding_handle *b = p->binding_handle;
3257 fields = talloc_asprintf(tctx, "(fields_present: 0x%08x)",
3264 torture_comment(tctx, "Testing SetUserInfo%s level %d call "
3265 "(password_expired: %d) %s\n",
3266 use_setinfo2 ? "2":"", level, password_expired,
3267 fields ? fields : "");
3269 if (!test_SetUserPass_level_ex(p, tctx, handle, level,
3274 matched_expected_error)) {
3278 if (!test_QueryUserInfo_pwdlastset(b, tctx, handle,
3284 if (*matched_expected_error == true) {
3288 if (!test_SamLogon_with_creds(tctx, np,
3292 expected_samlogon_result,
3300 static bool setup_schannel_netlogon_pipe(struct torture_context *tctx,
3301 struct cli_credentials *credentials,
3302 struct dcerpc_pipe **p)
3304 struct dcerpc_binding *b;
3307 torture_assert_ntstatus_ok(tctx, torture_rpc_binding(tctx, &b),
3308 "failed to get rpc binding");
3310 /* We have to use schannel, otherwise the SamLogonEx fails
3311 * with INTERNAL_ERROR */
3313 status = dcerpc_binding_set_flags(b,
3315 DCERPC_SIGN | DCERPC_SEAL |
3316 DCERPC_SCHANNEL_AUTO,
3317 DCERPC_AUTH_OPTIONS);
3318 torture_assert_ntstatus_ok(tctx, status, "set flags");
3320 torture_assert_ntstatus_ok(tctx,
3321 dcerpc_pipe_connect_b(tctx, p, b, &ndr_table_netlogon,
3322 credentials, tctx->ev, tctx->lp_ctx),
3323 "failed to bind to netlogon");
3328 static bool test_SetPassword_pwdlastset(struct dcerpc_pipe *p,
3329 struct torture_context *tctx,
3330 uint32_t acct_flags,
3331 const char *acct_name,
3332 struct policy_handle *handle,
3334 struct cli_credentials *machine_credentials)
3336 int s = 0, q = 0, f = 0, l = 0, z = 0;
3339 bool set_levels[] = { false, true };
3340 bool query_levels[] = { false, true };
3341 uint32_t levels[] = { 18, 21, 26, 23, 24, 25 }; /* Second half only used when TEST_ALL_LEVELS defined */
3342 uint32_t nonzeros[] = { 1, 24 };
3343 uint32_t fields_present[] = {
3345 SAMR_FIELD_EXPIRED_FLAG,
3346 SAMR_FIELD_LAST_PWD_CHANGE,
3347 SAMR_FIELD_EXPIRED_FLAG | SAMR_FIELD_LAST_PWD_CHANGE,
3349 SAMR_FIELD_NT_PASSWORD_PRESENT,
3350 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
3351 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
3352 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
3353 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
3354 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
3355 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE | SAMR_FIELD_EXPIRED_FLAG
3357 struct dcerpc_pipe *np = NULL;
3359 if (torture_setting_bool(tctx, "samba3", false) ||
3360 torture_setting_bool(tctx, "samba4", false)) {
3362 torture_comment(tctx, "Samba3 has second granularity, setting delay to: %d\n",
3366 torture_assert(tctx, setup_schannel_netlogon_pipe(tctx, machine_credentials, &np), "");
3368 /* set to 1 to enable testing for all possible opcode
3369 (SetUserInfo, SetUserInfo2, QueryUserInfo, QueryUserInfo2)
3372 #define TEST_ALL_LEVELS 1
3373 #define TEST_SET_LEVELS 1
3374 #define TEST_QUERY_LEVELS 1
3376 #ifdef TEST_ALL_LEVELS
3377 for (l=0; l<ARRAY_SIZE(levels); l++) {
3379 for (l=0; l<(ARRAY_SIZE(levels))/2; l++) {
3381 for (z=0; z<ARRAY_SIZE(nonzeros); z++) {
3382 for (f=0; f<ARRAY_SIZE(fields_present); f++) {
3383 #ifdef TEST_SET_LEVELS
3384 for (s=0; s<ARRAY_SIZE(set_levels); s++) {
3386 #ifdef TEST_QUERY_LEVELS
3387 for (q=0; q<ARRAY_SIZE(query_levels); q++) {
3389 NTTIME pwdlastset_old = 0;
3390 NTTIME pwdlastset_new = 0;
3391 bool matched_expected_error = false;
3392 NTSTATUS expected_samlogon_result = NT_STATUS_ACCOUNT_DISABLED;
3394 torture_comment(tctx, "------------------------------\n"
3395 "Testing pwdLastSet attribute for flags: 0x%08x "
3396 "(s: %d (l: %d), q: %d)\n",
3397 acct_flags, s, levels[l], q);
3399 switch (levels[l]) {
3403 if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3404 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT))) {
3405 expected_samlogon_result = NT_STATUS_WRONG_PASSWORD;
3413 /* set a password and force password change (pwdlastset 0) by
3414 * setting the password expired flag to a non-0 value */
3416 if (!test_SetPassword_level(p, np, tctx, handle,
3420 &matched_expected_error,
3424 machine_credentials,
3427 expected_samlogon_result)) {
3431 if (matched_expected_error == true) {
3432 /* skipping on expected failure */
3436 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3437 * set without the SAMR_FIELD_EXPIRED_FLAG */
3439 switch (levels[l]) {
3443 if ((pwdlastset_new != 0) &&
3444 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
3445 torture_comment(tctx, "not considering a non-0 "
3446 "pwdLastSet as a an error as the "
3447 "SAMR_FIELD_EXPIRED_FLAG has not "
3453 if (pwdlastset_new != 0) {
3454 torture_result(tctx, TORTURE_FAIL, "pwdLastSet test failed: "
3455 "expected pwdLastSet 0 but got %llu\n",
3456 (unsigned long long) pwdlastset_old);
3462 switch (levels[l]) {
3466 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3467 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3468 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3469 (pwdlastset_old >= pwdlastset_new)) {
3470 torture_result(tctx, TORTURE_FAIL, "pwdlastset not increasing\n");
3476 pwdlastset_old = pwdlastset_new;
3482 /* set a password, pwdlastset needs to get updated (increased
3483 * value), password_expired value used here is 0 */
3485 if (!test_SetPassword_level(p, np, tctx, handle,
3489 &matched_expected_error,
3493 machine_credentials,
3496 expected_samlogon_result)) {
3500 /* when a password has been changed, pwdlastset must not be 0 afterwards
3501 * and must be larger then the old value */
3503 switch (levels[l]) {
3507 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3508 * password has been changed, old and new pwdlastset
3509 * need to be the same value */
3511 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3512 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3513 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3515 torture_assert_int_equal(tctx, pwdlastset_old,
3516 pwdlastset_new, "pwdlastset must be equal");
3521 if (pwdlastset_old >= pwdlastset_new) {
3522 torture_result(tctx, TORTURE_FAIL, "pwdLastSet test failed: "
3523 "expected last pwdlastset (%llu) < new pwdlastset (%llu)\n",
3524 (unsigned long long) pwdlastset_old,
3525 (unsigned long long) pwdlastset_new);
3528 if (pwdlastset_new == 0) {
3529 torture_result(tctx, TORTURE_FAIL, "pwdLastSet test failed: "
3530 "expected non-0 pwdlastset, got: %llu\n",
3531 (unsigned long long) pwdlastset_new);
3537 switch (levels[l]) {
3541 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3542 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3543 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3544 (pwdlastset_old >= pwdlastset_new)) {
3545 torture_result(tctx, TORTURE_FAIL, "pwdlastset not increasing\n");
3551 pwdlastset_old = pwdlastset_new;
3557 /* set a password, pwdlastset needs to get updated (increased
3558 * value), password_expired value used here is 0 */
3560 if (!test_SetPassword_level(p, np, tctx, handle,
3564 &matched_expected_error,
3568 machine_credentials,
3571 expected_samlogon_result)) {
3575 /* when a password has been changed, pwdlastset must not be 0 afterwards
3576 * and must be larger then the old value */
3578 switch (levels[l]) {
3583 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3584 * password has been changed, old and new pwdlastset
3585 * need to be the same value */
3587 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3588 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3589 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3591 torture_assert_int_equal(tctx, pwdlastset_old,
3592 pwdlastset_new, "pwdlastset must be equal");
3597 if (pwdlastset_old >= pwdlastset_new) {
3598 torture_result(tctx, TORTURE_FAIL, "pwdLastSet test failed: "
3599 "expected last pwdlastset (%llu) < new pwdlastset (%llu)\n",
3600 (unsigned long long) pwdlastset_old,
3601 (unsigned long long) pwdlastset_new);
3604 if (pwdlastset_new == 0) {
3605 torture_result(tctx, TORTURE_FAIL, "pwdLastSet test failed: "
3606 "expected non-0 pwdlastset, got: %llu\n",
3607 (unsigned long long) pwdlastset_new);
3613 switch (levels[l]) {
3617 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3618 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3619 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3620 (pwdlastset_old >= pwdlastset_new)) {
3621 torture_result(tctx, TORTURE_FAIL, "pwdlastset not increasing\n");
3627 pwdlastset_old = pwdlastset_new;
3633 /* set a password and force password change (pwdlastset 0) by
3634 * setting the password expired flag to a non-0 value */
3636 if (!test_SetPassword_level(p, np, tctx, handle,
3640 &matched_expected_error,
3644 machine_credentials,
3647 expected_samlogon_result)) {
3651 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3652 * set without the SAMR_FIELD_EXPIRED_FLAG */
3654 switch (levels[l]) {
3658 if ((pwdlastset_new != 0) &&
3659 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
3660 torture_comment(tctx, "not considering a non-0 "
3661 "pwdLastSet as a an error as the "
3662 "SAMR_FIELD_EXPIRED_FLAG has not "
3667 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3668 * password has been changed, old and new pwdlastset
3669 * need to be the same value */
3671 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3672 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3673 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3675 torture_assert_int_equal(tctx, pwdlastset_old,
3676 pwdlastset_new, "pwdlastset must be equal");
3681 if (pwdlastset_new != 0) {
3682 torture_result(tctx, TORTURE_FAIL, "pwdLastSet test failed: "
3683 "expected pwdLastSet 0, got %llu\n",
3684 (unsigned long long) pwdlastset_old);
3690 switch (levels[l]) {
3694 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3695 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3696 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3697 (pwdlastset_old >= pwdlastset_new)) {
3698 torture_result(tctx, TORTURE_FAIL, "pwdlastset not increasing\n");
3704 /* if the level we are testing does not have a fields_present
3705 * field, skip all fields present tests by setting f to to
3707 switch (levels[l]) {
3711 f = ARRAY_SIZE(fields_present);
3715 #ifdef TEST_QUERY_LEVELS
3718 #ifdef TEST_SET_LEVELS
3721 } /* fields present */
3725 #undef TEST_SET_LEVELS
3726 #undef TEST_QUERY_LEVELS
3733 static bool test_QueryUserInfo_badpwdcount(struct dcerpc_binding_handle *b,
3734 struct torture_context *tctx,
3735 struct policy_handle *handle,
3736 uint32_t *badpwdcount)
3738 union samr_UserInfo *info;
3739 struct samr_QueryUserInfo r;
3741 r.in.user_handle = handle;
3745 torture_comment(tctx, "Testing QueryUserInfo level %d", r.in.level);
3747 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
3748 "failed to query userinfo");
3749 torture_assert_ntstatus_ok(tctx, r.out.result,
3750 "failed to query userinfo");
3752 *badpwdcount = info->info3.bad_password_count;
3754 torture_comment(tctx, " (bad password count: %d)\n", *badpwdcount);
3759 static bool test_SetUserInfo_acct_flags(struct dcerpc_binding_handle *b,
3760 struct torture_context *tctx,
3761 struct policy_handle *user_handle,
3762 uint32_t acct_flags)
3764 struct samr_SetUserInfo r;
3765 union samr_UserInfo user_info;
3767 torture_comment(tctx, "Testing SetUserInfo level 16\n");
3769 user_info.info16.acct_flags = acct_flags;
3771 r.in.user_handle = user_handle;
3773 r.in.info = &user_info;
3775 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &r),
3776 "failed to set account flags");
3777 torture_assert_ntstatus_ok(tctx, r.out.result,
3778 "failed to set account flags");
3783 static bool test_reset_badpwdcount(struct dcerpc_pipe *p,
3784 struct torture_context *tctx,
3785 struct policy_handle *user_handle,
3786 uint32_t acct_flags,
3789 struct dcerpc_binding_handle *b = p->binding_handle;
3791 torture_assert(tctx, test_SetUserPass(p, tctx, user_handle, password),
3792 "failed to set password");
3794 torture_comment(tctx, "Testing SetUserInfo level 16 (enable account)\n");
3796 torture_assert(tctx,
3797 test_SetUserInfo_acct_flags(b, tctx, user_handle,
3798 acct_flags & ~ACB_DISABLED),
3799 "failed to enable user");
3801 torture_assert(tctx, test_SetUserPass(p, tctx, user_handle, password),
3802 "failed to set password");
3807 static bool test_SetDomainInfo(struct dcerpc_binding_handle *b,
3808 struct torture_context *tctx,
3809 struct policy_handle *domain_handle,
3810 enum samr_DomainInfoClass level,
3811 union samr_DomainInfo *info)
3813 struct samr_SetDomainInfo r;
3815 r.in.domain_handle = domain_handle;
3819 torture_assert_ntstatus_ok(tctx,
3820 dcerpc_samr_SetDomainInfo_r(b, tctx, &r),
3821 "failed to set domain info");
3822 torture_assert_ntstatus_ok(tctx, r.out.result,
3823 "failed to set domain info");
3828 static bool test_SetDomainInfo_ntstatus(struct dcerpc_binding_handle *b,
3829 struct torture_context *tctx,
3830 struct policy_handle *domain_handle,
3831 enum samr_DomainInfoClass level,
3832 union samr_DomainInfo *info,
3835 struct samr_SetDomainInfo r;
3837 r.in.domain_handle = domain_handle;
3841 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &r),
3842 "SetDomainInfo failed");
3843 torture_assert_ntstatus_equal(tctx, r.out.result, expected, "");
3848 static bool test_QueryDomainInfo2_level(struct dcerpc_binding_handle *b,
3849 struct torture_context *tctx,
3850 struct policy_handle *domain_handle,
3851 enum samr_DomainInfoClass level,
3852 union samr_DomainInfo **q_info)
3854 struct samr_QueryDomainInfo2 r;
3856 r.in.domain_handle = domain_handle;
3858 r.out.info = q_info;
3860 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo2_r(b, tctx, &r),
3861 "failed to query domain info");
3862 torture_assert_ntstatus_ok(tctx, r.out.result,
3863 "failed to query domain info");
3868 static bool test_Password_badpwdcount(struct dcerpc_pipe *p,
3869 struct dcerpc_pipe *np,
3870 struct torture_context *tctx,
3871 uint32_t acct_flags,
3872 const char *acct_name,
3873 struct policy_handle *domain_handle,
3874 struct policy_handle *user_handle,
3876 struct cli_credentials *machine_credentials,
3877 const char *comment,
3880 NTSTATUS expected_success_status,
3881 struct samr_DomInfo1 *info1,
3882 struct samr_DomInfo12 *info12)
3884 union samr_DomainInfo info;
3887 uint32_t badpwdcount, tmp;
3888 uint32_t password_history_length = 12;
3889 uint32_t lockout_threshold = 15;
3890 uint32_t lockout_seconds = 5;
3891 uint64_t delta_time_factor = 10 * 1000 * 1000;
3892 struct dcerpc_binding_handle *b = p->binding_handle;
3894 if (torture_setting_bool(tctx, "samba3", false)) {
3895 lockout_seconds = 60;
3898 torture_comment(tctx, "\nTesting bad pwd count with: %s\n", comment);
3900 torture_assert(tctx, password_history_length < lockout_threshold,
3901 "password history length needs to be smaller than account lockout threshold for this test");
3906 info.info1 = *info1;
3907 info.info1.password_history_length = password_history_length;
3908 info.info1.min_password_age = 0;
3910 torture_assert(tctx,
3911 test_SetDomainInfo(b, tctx, domain_handle,
3912 DomainPasswordInformation, &info),
3913 "failed to set password history length and min passwd age");
3915 info.info12 = *info12;
3916 info.info12.lockout_threshold = lockout_threshold;
3918 /* set lockout duration of 5 seconds */
3919 info.info12.lockout_duration = ~(lockout_seconds * delta_time_factor);
3920 info.info12.lockout_window = ~(lockout_seconds * delta_time_factor);
3922 torture_assert(tctx,
3923 test_SetDomainInfo(b, tctx, domain_handle,
3924 DomainLockoutInformation, &info),
3925 "failed to set lockout threshold");
3927 /* reset bad pwd count */
3929 torture_assert(tctx,
3930 test_reset_badpwdcount(p, tctx, user_handle, acct_flags, password), "");
3933 /* enable or disable account */
3935 torture_assert(tctx,
3936 test_SetUserInfo_acct_flags(b, tctx, user_handle,
3937 acct_flags | ACB_DISABLED),
3938 "failed to disable user");
3940 torture_assert(tctx,
3941 test_SetUserInfo_acct_flags(b, tctx, user_handle,
3942 acct_flags & ~ACB_DISABLED),
3943 "failed to enable user");
3947 /* setup password history */
3949 passwords = talloc_array(tctx, char *, password_history_length);
3951 for (i=0; i < password_history_length; i++) {
3953 torture_assert(tctx, test_SetUserPass(p, tctx, user_handle, password),
3954 "failed to set password");
3955 passwords[i] = talloc_strdup(tctx, *password);
3957 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3958 acct_name, passwords[i],
3959 expected_success_status, interactive)) {
3960 torture_fail(tctx, "failed to auth with latest password");
3963 torture_assert(tctx,
3964 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
3966 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
3970 /* test with wrong password */
3972 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3973 acct_name, "random_crap",
3974 NT_STATUS_WRONG_PASSWORD, interactive)) {
3975 torture_fail(tctx, "succeeded to authenticate with wrong password");
3978 torture_assert(tctx,
3979 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
3981 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
3984 /* test with latest good password */
3986 if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
3987 passwords[password_history_length-1],
3988 expected_success_status, interactive)) {
3989 torture_fail(tctx, "succeeded to authenticate with wrong password");
3992 torture_assert(tctx,
3993 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
3996 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
3998 /* only enabled accounts get the bad pwd count reset upon
3999 * successful logon */
4000 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
4006 /* test password history */
4008 for (i=0; i < password_history_length; i++) {
4010 torture_comment(tctx, "Testing bad password count behavior with "
4011 "password #%d of #%d\n", i, password_history_length);
4013 /* - network samlogon will succeed auth and not
4014 * increase badpwdcount for 2 last entries
4015 * - interactive samlogon only for the last one */
4017 if (i == password_history_length - 1 ||
4018 (i == password_history_length - 2 && !interactive)) {
4020 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
4021 acct_name, passwords[i],
4022 expected_success_status, interactive)) {
4023 torture_fail(tctx, talloc_asprintf(tctx, "did not successfully to obtain %s for %s login with old password (#%d of #%d in history)",
4024 nt_errstr(expected_success_status),
4025 interactive ? "interactive" : "network", i, password_history_length));
4028 torture_assert(tctx,
4029 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
4032 /* torture_comment(tctx, "expecting bad pwd count to *NOT INCREASE* for pwd history entry %d\n", i); */
4033 torture_assert_int_equal(tctx, badpwdcount, tmp, "unexpected badpwdcount");
4035 /* torture_comment(tctx, "expecting bad pwd count to be 0 for pwd history entry %d\n", i); */
4036 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
4044 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
4045 acct_name, passwords[i],
4046 NT_STATUS_WRONG_PASSWORD, interactive)) {
4047 torture_fail(tctx, talloc_asprintf(tctx, "succeeded to authenticate with old password (#%d of #%d in history)", i, password_history_length));
4050 torture_assert(tctx,
4051 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
4053 /* - network samlogon will fail auth but not increase
4054 * badpwdcount for 3rd last entry
4055 * - interactive samlogon for 3rd and 2nd last entry */
4057 if (i == password_history_length - 3 ||
4058 (i == password_history_length - 2 && interactive)) {
4059 /* torture_comment(tctx, "expecting bad pwd count to *NOT INCREASE * by one for pwd history entry %d\n", i); */
4060 torture_assert_int_equal(tctx, badpwdcount, tmp, "unexpected badpwdcount");
4062 /* torture_comment(tctx, "expecting bad pwd count to increase by one for pwd history entry %d\n", i); */
4063 torture_assert_int_equal(tctx, badpwdcount, tmp + 1, "unexpected badpwdcount");
4072 static bool test_Password_badpwdcount_wrap(struct dcerpc_pipe *p,
4073 struct torture_context *tctx,
4074 uint32_t acct_flags,
4075 const char *acct_name,
4076 struct policy_handle *domain_handle,
4077 struct policy_handle *user_handle,
4079 struct cli_credentials *machine_credentials)
4081 union samr_DomainInfo *q_info, s_info;
4082 struct samr_DomInfo1 info1, _info1;
4083 struct samr_DomInfo12 info12, _info12;
4085 struct dcerpc_binding_handle *b = p->binding_handle;
4086 struct dcerpc_pipe *np;
4090 const char *comment;
4093 NTSTATUS expected_success_status;
4096 .comment = "network logon (disabled account)",
4098 .interactive = false,
4099 .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
4102 .comment = "network logon (enabled account)",
4104 .interactive = false,
4105 .expected_success_status= NT_STATUS_OK
4108 .comment = "interactive logon (disabled account)",
4110 .interactive = true,
4111 .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
4114 .comment = "interactive logon (enabled account)",
4116 .interactive = true,
4117 .expected_success_status= NT_STATUS_OK
4121 torture_assert(tctx, setup_schannel_netlogon_pipe(tctx, machine_credentials, &np), "");
4123 /* backup old policies */
4125 torture_assert(tctx,
4126 test_QueryDomainInfo2_level(b, tctx, domain_handle,
4127 DomainPasswordInformation, &q_info),
4128 "failed to query domain info level 1");
4130 info1 = q_info->info1;
4133 torture_assert(tctx,
4134 test_QueryDomainInfo2_level(b, tctx, domain_handle,
4135 DomainLockoutInformation, &q_info),
4136 "failed to query domain info level 12");
4138 info12 = q_info->info12;
4143 for (i=0; i < ARRAY_SIZE(creds); i++) {
4145 /* skip trust tests for now */
4146 if (acct_flags & ACB_WSTRUST ||
4147 acct_flags & ACB_SVRTRUST ||
4148 acct_flags & ACB_DOMTRUST) {
4152 if (!test_Password_badpwdcount(p, np, tctx, acct_flags, acct_name,
4153 domain_handle, user_handle, password,
4154 machine_credentials,
4157 creds[i].interactive,
4158 creds[i].expected_success_status,
4159 &_info1, &_info12)) {
4160 torture_result(tctx, TORTURE_FAIL, "TEST #%d (%s) failed\n", i, creds[i].comment);
4163 torture_comment(tctx, "TEST #%d (%s) succeeded\n", i, creds[i].comment);
4167 /* restore policies */
4169 s_info.info1 = info1;
4171 torture_assert(tctx,
4172 test_SetDomainInfo(b, tctx, domain_handle,
4173 DomainPasswordInformation, &s_info),
4174 "failed to set password information");
4176 s_info.info12 = info12;
4178 torture_assert(tctx,
4179 test_SetDomainInfo(b, tctx, domain_handle,
4180 DomainLockoutInformation, &s_info),
4181 "failed to set lockout information");
4186 static bool test_QueryUserInfo_lockout(struct dcerpc_binding_handle *b,
4187 struct torture_context *tctx,
4188 struct policy_handle *domain_handle,
4189 const char *acct_name,
4190 uint16_t raw_bad_password_count,
4191 uint16_t effective_bad_password_count,
4192 uint32_t effective_acb_lockout)
4194 struct policy_handle user_handle;
4195 union samr_UserInfo *i;
4196 struct samr_QueryUserInfo r;
4198 NTSTATUS status = test_OpenUser_byname(b, tctx, domain_handle, acct_name, &user_handle);
4199 if (!NT_STATUS_IS_OK(status)) {
4203 r.in.user_handle = &user_handle;
4206 torture_comment(tctx, "Testing QueryUserInfo level %d", r.in.level);
4207 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
4208 "failed to query userinfo");
4209 torture_assert_ntstatus_ok(tctx, r.out.result,
4210 "failed to query userinfo");
4211 torture_comment(tctx, " (acct_flags: 0x%08x) (raw_bad_pwd_count: %u)\n",
4212 i->info3.acct_flags, i->info3.bad_password_count);
4213 torture_assert_int_equal(tctx, i->info3.bad_password_count,
4214 raw_bad_password_count,
4216 torture_assert_int_equal(tctx, i->info3.acct_flags & ACB_AUTOLOCK,
4217 effective_acb_lockout,
4218 "effective acb_lockout");
4221 r.in.user_handle = &user_handle;
4224 torture_comment(tctx, "Testing QueryUserInfo level %d", r.in.level);
4225 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
4226 "failed to query userinfo");
4227 torture_assert_ntstatus_ok(tctx, r.out.result,
4228 "failed to query userinfo");
4229 torture_comment(tctx, " (acct_flags: 0x%08x) (effective_bad_pwd_count: %u)\n",
4230 i->info5.acct_flags, i->info5.bad_password_count);
4231 torture_assert_int_equal(tctx, i->info5.bad_password_count,
4232 effective_bad_password_count,
4233 "effective badpwdcount");
4234 torture_assert_int_equal(tctx, i->info5.acct_flags & ACB_AUTOLOCK,
4235 effective_acb_lockout,
4236 "effective acb_lockout");
4239 r.in.user_handle = &user_handle;
4242 torture_comment(tctx, "Testing QueryUserInfo level %d", r.in.level);
4243 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
4244 "failed to query userinfo");
4245 torture_assert_ntstatus_ok(tctx, r.out.result,
4246 "failed to query userinfo");
4247 torture_comment(tctx, " (acct_flags: 0x%08x)\n",
4248 i->info16.acct_flags);
4249 torture_assert_int_equal(tctx, i->info16.acct_flags & ACB_AUTOLOCK,
4250 effective_acb_lockout,
4251 "effective acb_lockout");
4254 r.in.user_handle = &user_handle;
4257 torture_comment(tctx, "Testing QueryUserInfo level %d", r.in.level);
4258 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
4259 "failed to query userinfo");
4260 torture_assert_ntstatus_ok(tctx, r.out.result,
4261 "failed to query userinfo");
4262 torture_comment(tctx, " (acct_flags: 0x%08x) (effective_bad_pwd_count: %u)\n",
4263 i->info21.acct_flags, i->info21.bad_password_count);
4264 torture_assert_int_equal(tctx, i->info21.bad_password_count,
4265 effective_bad_password_count,
4266 "effective badpwdcount");
4267 torture_assert_int_equal(tctx, i->info21.acct_flags & ACB_AUTOLOCK,
4268 effective_acb_lockout,
4269 "effective acb_lockout");
4272 if (!test_samr_handle_Close(b, tctx, &user_handle)) {
4279 static bool test_Password_lockout(struct dcerpc_pipe *p,
4280 struct dcerpc_pipe *np,
4281 struct torture_context *tctx,
4282 uint32_t acct_flags,
4283 const char *acct_name,
4284 struct policy_handle *domain_handle,
4285 struct policy_handle *user_handle,
4287 struct cli_credentials *machine_credentials,
4288 const char *comment,
4291 uint32_t password_history_length,
4292 NTSTATUS expected_success_status,
4293 struct samr_DomInfo1 *info1,
4294 struct samr_DomInfo12 *info12)
4296 union samr_DomainInfo info;
4297 uint64_t lockout_threshold = 1;
4298 uint32_t lockout_seconds = 5;
4299 uint64_t delta_time_factor = 10 * 1000 * 1000;
4300 struct dcerpc_binding_handle *b = p->binding_handle;
4302 if (torture_setting_bool(tctx, "samba3", false)) {
4303 lockout_seconds = 60;
4306 torture_comment(tctx, "\nTesting account lockout: %s\n", comment);
4310 info.info1 = *info1;
4312 torture_comment(tctx, "setting password history length to %d.\n", password_history_length);
4313 info.info1.password_history_length = password_history_length;
4315 torture_comment(tctx, "setting min password again.\n");
4316 info.info1.min_password_age = 0;
4318 torture_assert(tctx,
4319 test_SetDomainInfo(b, tctx, domain_handle,
4320 DomainPasswordInformation, &info),
4321 "failed to set password history length");
4323 info.info12 = *info12;
4324 info.info12.lockout_threshold = lockout_threshold;
4326 /* set lockout duration < lockout window: should fail */
4327 info.info12.lockout_duration = ~(lockout_seconds * delta_time_factor);
4328 info.info12.lockout_window = ~((lockout_seconds + 1) * delta_time_factor);
4330 torture_assert(tctx,
4331 test_SetDomainInfo_ntstatus(b, tctx, domain_handle,
4332 DomainLockoutInformation, &info,
4333 NT_STATUS_INVALID_PARAMETER),
4334 "setting lockout duration < lockout window gave unexpected result");
4336 info.info12.lockout_duration = 0;
4337 info.info12.lockout_window = 0;
4339 torture_assert(tctx,
4340 test_SetDomainInfo(b, tctx, domain_handle,
4341 DomainLockoutInformation, &info),
4342 "failed to set lockout window and duration to 0");
4345 /* set lockout duration of 5 seconds */
4346 info.info12.lockout_duration = ~(lockout_seconds * delta_time_factor);
4347 info.info12.lockout_window = ~(lockout_seconds * delta_time_factor);
4349 torture_assert(tctx,
4350 test_SetDomainInfo(b, tctx, domain_handle,
4351 DomainLockoutInformation, &info),
4352 "failed to set lockout window and duration to 5 seconds");
4354 /* reset bad pwd count */
4356 torture_assert(tctx,
4357 test_reset_badpwdcount(p, tctx, user_handle, acct_flags, password), "");
4360 /* enable or disable account */
4363 torture_assert(tctx,
4364 test_SetUserInfo_acct_flags(b, tctx, user_handle,
4365 acct_flags | ACB_DISABLED),
4366 "failed to disable user");
4368 torture_assert(tctx,
4369 test_SetUserInfo_acct_flags(b, tctx, user_handle,
4370 acct_flags & ~ACB_DISABLED),
4371 "failed to enable user");
4375 /* test logon with right password */
4377 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
4378 acct_name, *password,
4379 expected_success_status, interactive)) {
4380 torture_fail(tctx, "failed to auth with latest password");
4383 torture_assert(tctx,
4384 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4386 "expected account to not be locked");
4388 /* test with wrong password ==> lockout */
4390 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
4391 acct_name, "random_crap",
4392 NT_STATUS_WRONG_PASSWORD, interactive)) {
4393 torture_fail(tctx, "succeeded to authenticate with wrong password");
4397 * curiously, windows does _not_ return fresh values of
4398 * effective bad_password_count and ACB_AUTOLOCK.
4400 torture_assert(tctx,
4401 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4402 1, 1, ACB_AUTOLOCK),
4403 "expected account to not be locked");
4405 /* test with good password */
4407 if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
4409 NT_STATUS_ACCOUNT_LOCKED_OUT, interactive))
4411 torture_fail(tctx, "authenticate did not return NT_STATUS_ACCOUNT_LOCKED_OUT");
4414 /* bad pwd count should not get updated */
4415 torture_assert(tctx,
4416 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4417 1, 1, ACB_AUTOLOCK),
4418 "expected account to be locked");
4420 torture_assert(tctx,
4421 test_ChangePasswordUser2_ntstatus(p, tctx, acct_name, *password,
4422 NT_STATUS_ACCOUNT_LOCKED_OUT),
4423 "got wrong status from ChangePasswordUser2");
4425 /* bad pwd count should not get updated */
4426 torture_assert(tctx,
4427 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4428 1, 1, ACB_AUTOLOCK),
4429 "expected account to be locked");
4431 torture_assert(tctx,
4432 test_ChangePasswordUser2_ntstatus(p, tctx, acct_name, "random_crap", NT_STATUS_ACCOUNT_LOCKED_OUT),
4433 "got wrong status from ChangePasswordUser2");
4435 /* bad pwd count should not get updated */
4436 torture_assert(tctx,
4437 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4438 1, 1, ACB_AUTOLOCK),
4439 "expected account to be locked");
4441 /* with bad password */
4443 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
4444 acct_name, "random_crap2",
4445 NT_STATUS_ACCOUNT_LOCKED_OUT, interactive))
4447 torture_fail(tctx, "authenticate did not return NT_STATUS_ACCOUNT_LOCKED_OUT");
4450 /* bad pwd count should not get updated */
4451 torture_assert(tctx,
4452 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4453 1, 1, ACB_AUTOLOCK),
4454 "expected account to be locked");
4456 /* let lockout duration expire ==> unlock */
4458 torture_comment(tctx, "let lockout duration expire...\n");
4459 sleep(lockout_seconds + 1);
4461 torture_assert(tctx,
4462 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4464 "expected account to not be locked");
4466 if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
4468 expected_success_status, interactive))
4470 torture_fail(tctx, "failed to authenticate after lockout expired");
4473 if (NT_STATUS_IS_OK(expected_success_status)) {
4474 torture_assert(tctx,
4475 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4477 "expected account to not be locked");
4479 torture_assert(tctx,
4480 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4482 "expected account to not be locked");
4485 torture_assert(tctx,
4486 test_ChangePasswordUser2_ntstatus(p, tctx, acct_name, "random_crap", NT_STATUS_WRONG_PASSWORD),
4487 "got wrong status from ChangePasswordUser2");
4489 torture_assert(tctx,
4490 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4491 1, 1, ACB_AUTOLOCK),
4492 "expected account to be locked");
4494 torture_assert(tctx,
4495 test_ChangePasswordUser2_ntstatus(p, tctx, acct_name, *password, NT_STATUS_ACCOUNT_LOCKED_OUT),
4496 "got wrong status from ChangePasswordUser2");
4498 torture_assert(tctx,
4499 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4500 1, 1, ACB_AUTOLOCK),
4501 "expected account to be locked");
4503 torture_assert(tctx,
4504 test_ChangePasswordUser2_ntstatus(p, tctx, acct_name, "random_crap", NT_STATUS_ACCOUNT_LOCKED_OUT),
4505 "got wrong status from ChangePasswordUser2");
4507 torture_assert(tctx,
4508 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4509 1, 1, ACB_AUTOLOCK),
4510 "expected account to be locked");
4512 /* let lockout duration expire ==> unlock */
4514 torture_comment(tctx, "let lockout duration expire...\n");
4515 sleep(lockout_seconds + 1);
4517 torture_assert(tctx,
4518 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4520 "expected account to not be locked");
4522 if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
4524 expected_success_status, interactive))
4526 torture_fail(tctx, "failed to authenticate after lockout expired");
4529 if (NT_STATUS_IS_OK(expected_success_status)) {
4530 torture_assert(tctx,
4531 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4533 "expected account to not be locked");
4535 torture_assert(tctx,
4536 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4538 "expected account to not be locked");
4541 /* Testing ChangePasswordUser behaviour with 3 attempts */
4542 info.info12.lockout_threshold = 3;
4544 torture_assert(tctx,
4545 test_SetDomainInfo(b, tctx, domain_handle,
4546 DomainLockoutInformation, &info),
4547 "failed to set lockout threshold to 3");
4549 if (NT_STATUS_IS_OK(expected_success_status)) {
4550 torture_assert(tctx,
4551 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4553 "expected account to not be locked");
4555 torture_assert(tctx,
4556 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4558 "expected account to not be locked");
4561 torture_assert(tctx,
4562 test_ChangePasswordUser2_ntstatus(p, tctx, acct_name, "random_crap", NT_STATUS_WRONG_PASSWORD),
4563 "got wrong status from ChangePasswordUser2");
4565 /* bad pwd count will get updated */
4566 torture_assert(tctx,
4567 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4569 "expected account to not be locked");
4571 torture_assert(tctx,
4572 test_ChangePasswordUser2_ntstatus(p, tctx, acct_name, "random_crap", NT_STATUS_WRONG_PASSWORD),
4573 "got wrong status from ChangePasswordUser2");
4575 /* bad pwd count will get updated */
4576 torture_assert(tctx,
4577 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4579 "expected account to not be locked");
4581 torture_assert(tctx,
4582 test_ChangePasswordUser2_ntstatus(p, tctx, acct_name, "random_crap", NT_STATUS_WRONG_PASSWORD),
4583 "got wrong status from ChangePasswordUser2");
4585 /* bad pwd count should get updated */
4586 torture_assert(tctx,
4587 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4588 3, 3, ACB_AUTOLOCK),
4589 "expected account to be locked");
4591 torture_assert(tctx,
4592 test_ChangePasswordUser2_ntstatus(p, tctx, acct_name, *password, NT_STATUS_ACCOUNT_LOCKED_OUT),
4593 "got wrong status from ChangePasswordUser2");
4595 /* bad pwd count should not get updated */
4596 torture_assert(tctx,
4597 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4598 3, 3, ACB_AUTOLOCK),
4599 "expected account to be locked");
4601 /* let lockout duration expire ==> unlock */
4603 torture_comment(tctx, "let lockout duration expire...\n");
4604 sleep(lockout_seconds + 1);
4606 torture_assert(tctx,
4607 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4609 "expected account to not be locked");
4611 torture_assert(tctx,
4612 test_ChangePasswordUser2(p, tctx, acct_name, password, NULL, false),
4613 "got wrong status from ChangePasswordUser2");
4615 torture_assert(tctx,
4616 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4618 "expected account to not be locked");
4620 /* Used to reset the badPwdCount for the other tests */
4621 if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
4623 expected_success_status, interactive))
4625 torture_fail(tctx, "failed to authenticate after lockout expired");
4628 if (NT_STATUS_IS_OK(expected_success_status)) {
4629 torture_assert(tctx,
4630 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4632 "expected account to not be locked");
4634 torture_assert(tctx,
4635 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4637 "expected account to not be locked");
4643 static bool test_Password_lockout_wrap(struct dcerpc_pipe *p,
4644 struct torture_context *tctx,
4645 uint32_t acct_flags,
4646 const char *acct_name,
4647 struct policy_handle *domain_handle,
4648 struct policy_handle *user_handle,
4650 struct cli_credentials *machine_credentials)
4652 union samr_DomainInfo *q_info, s_info;
4653 struct samr_DomInfo1 info1, _info1;
4654 struct samr_DomInfo12 info12, _info12;
4656 struct dcerpc_binding_handle *b = p->binding_handle;
4657 struct dcerpc_pipe *np;
4661 const char *comment;
4664 uint32_t password_history_length;
4665 NTSTATUS expected_success_status;
4668 .comment = "network logon (disabled account)",
4670 .interactive = false,
4671 .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
4674 .comment = "network logon (enabled account)",
4676 .interactive = false,
4677 .expected_success_status= NT_STATUS_OK
4680 .comment = "network logon (enabled account, history len = 1)",
4682 .interactive = false,
4683 .expected_success_status= NT_STATUS_OK,
4684 .password_history_length = 1
4687 .comment = "interactive logon (disabled account)",
4689 .interactive = true,
4690 .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
4693 .comment = "interactive logon (enabled account)",
4695 .interactive = true,
4696 .expected_success_status= NT_STATUS_OK
4699 .comment = "interactive logon (enabled account, history len = 1)",
4701 .interactive = true,
4702 .expected_success_status= NT_STATUS_OK,
4703 .password_history_length = 1
4707 torture_assert(tctx, setup_schannel_netlogon_pipe(tctx, machine_credentials, &np), "");
4709 /* backup old policies */
4711 torture_assert(tctx,
4712 test_QueryDomainInfo2_level(b, tctx, domain_handle,
4713 DomainPasswordInformation, &q_info),
4714 "failed to query domain info level 1");
4716 info1 = q_info->info1;
4719 torture_assert(tctx,
4720 test_QueryDomainInfo2_level(b, tctx, domain_handle,
4721 DomainLockoutInformation, &q_info),
4722 "failed to query domain info level 12");
4724 info12 = q_info->info12;
4729 for (i=0; i < ARRAY_SIZE(creds); i++) {
4731 /* skip trust tests for now */
4732 if (acct_flags & ACB_WSTRUST ||
4733 acct_flags & ACB_SVRTRUST ||
4734 acct_flags & ACB_DOMTRUST) {
4738 test_passed = test_Password_lockout(p, np, tctx, acct_flags, acct_name,
4739 domain_handle, user_handle, password,
4740 machine_credentials,
4743 creds[i].interactive,
4744 creds[i].password_history_length,
4745 creds[i].expected_success_status,
4749 torture_result(tctx, TORTURE_FAIL, "TEST #%d (%s) failed\n", i, creds[i].comment);
4752 torture_comment(tctx, "TEST #%d (%s) succeeded\n", i, creds[i].comment);
4756 /* restore policies */
4758 s_info.info1 = info1;
4760 torture_assert(tctx,
4761 test_SetDomainInfo(b, tctx, domain_handle,
4762 DomainPasswordInformation, &s_info),
4763 "failed to set password information");
4765 s_info.info12 = info12;
4767 torture_assert(tctx,
4768 test_SetDomainInfo(b, tctx, domain_handle,
4769 DomainLockoutInformation, &s_info),
4770 "failed to set lockout information");
4775 static bool test_DeleteUser_with_privs(struct dcerpc_pipe *p,
4776 struct dcerpc_pipe *lp,
4777 struct torture_context *tctx,
4778 struct policy_handle *domain_handle,
4779 struct policy_handle *lsa_handle,
4780 struct policy_handle *user_handle,
4781 const struct dom_sid *domain_sid,
4783 struct cli_credentials *machine_credentials)
4786 struct dcerpc_binding_handle *b = p->binding_handle;
4787 struct dcerpc_binding_handle *lb = lp->binding_handle;
4789 struct policy_handle lsa_acct_handle;
4790 struct dom_sid *user_sid;
4792 user_sid = dom_sid_add_rid(tctx, domain_sid, rid);
4795 struct lsa_EnumAccountRights r;
4796 struct lsa_RightSet rights;
4798 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4800 r.in.handle = lsa_handle;
4801 r.in.sid = user_sid;
4802 r.out.rights = &rights;
4804 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
4805 "lsa_EnumAccountRights failed");
4806 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4807 "Expected enum rights for account to fail");
4811 struct lsa_RightSet rights;
4812 struct lsa_StringLarge names[2];
4813 struct lsa_AddAccountRights r;
4815 torture_comment(tctx, "Testing LSA AddAccountRights\n");
4817 init_lsa_StringLarge(&names[0], "SeMachineAccountPrivilege");
4818 init_lsa_StringLarge(&names[1], NULL);
4821 rights.names = names;
4823 r.in.handle = lsa_handle;
4824 r.in.sid = user_sid;
4825 r.in.rights = &rights;
4827 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_AddAccountRights_r(lb, tctx, &r),
4828 "lsa_AddAccountRights failed");
4829 torture_assert_ntstatus_ok(tctx, r.out.result,
4830 "Failed to add privileges");
4834 struct lsa_RightSet rights;
4835 struct lsa_StringLarge names[2];
4836 struct lsa_AddAccountRights r;
4838 torture_comment(tctx, "Testing LSA AddAccountRights 1\n");
4840 init_lsa_StringLarge(&names[0], "SeInteractiveLogonRight");
4841 init_lsa_StringLarge(&names[1], NULL);
4844 rights.names = names;
4846 r.in.handle = lsa_handle;
4847 r.in.sid = user_sid;
4848 r.in.rights = &rights;
4850 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_AddAccountRights_r(lb, tctx, &r),
4851 "lsa_AddAccountRights 1 failed");
4853 if (torture_setting_bool(tctx, "nt4_dc", false)) {
4855 * The NT4 DC doesn't implement Rights.
4857 torture_assert_ntstatus_equal(tctx, r.out.result,
4858 NT_STATUS_NO_SUCH_PRIVILEGE,
4859 "Add rights failed with incorrect error");
4861 torture_assert_ntstatus_ok(tctx, r.out.result,
4862 "Failed to add rights");
4869 struct lsa_EnumAccounts r;
4870 uint32_t resume_handle = 0;
4871 struct lsa_SidArray lsa_sid_array;
4873 bool found_sid = false;
4875 torture_comment(tctx, "Testing LSA EnumAccounts\n");
4877 r.in.handle = lsa_handle;
4878 r.in.num_entries = 0x1000;
4879 r.in.resume_handle = &resume_handle;
4880 r.out.sids = &lsa_sid_array;
4881 r.out.resume_handle = &resume_handle;
4883 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(lb, tctx, &r),
4884 "lsa_EnumAccounts failed");
4885 torture_assert_ntstatus_ok(tctx, r.out.result,
4886 "Failed to enum accounts");
4888 for (i=0; i < lsa_sid_array.num_sids; i++) {
4889 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
4894 torture_assert(tctx, found_sid,
4895 "failed to list privileged account");
4899 struct lsa_EnumAccountRights r;
4900 struct lsa_RightSet user_rights;
4901 uint32_t expected_count = 2;
4903 if (torture_setting_bool(tctx, "nt4_dc", false)) {
4905 * NT4 DC doesn't store rights.
4910 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4912 r.in.handle = lsa_handle;
4913 r.in.sid = user_sid;
4914 r.out.rights = &user_rights;
4916 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
4917 "lsa_EnumAccountRights failed");
4918 torture_assert_ntstatus_ok(tctx, r.out.result,
4919 "Failed to enum rights for account");
4921 if (user_rights.count < expected_count) {
4922 torture_result(tctx, TORTURE_FAIL, "failed to find newly added rights");
4928 struct lsa_OpenAccount r;
4930 torture_comment(tctx, "Testing LSA OpenAccount\n");
4932 r.in.handle = lsa_handle;
4933 r.in.sid = user_sid;
4934 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4935 r.out.acct_handle = &lsa_acct_handle;
4937 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenAccount_r(lb, tctx, &r),
4938 "lsa_OpenAccount failed");
4939 torture_assert_ntstatus_ok(tctx, r.out.result,
4940 "Failed to open lsa account");
4944 struct lsa_GetSystemAccessAccount r;
4945 uint32_t access_mask;
4947 torture_comment(tctx, "Testing LSA GetSystemAccessAccount\n");
4949 r.in.handle = &lsa_acct_handle;
4950 r.out.access_mask = &access_mask;
4952 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetSystemAccessAccount_r(lb, tctx, &r),
4953 "lsa_GetSystemAccessAccount failed");
4954 torture_assert_ntstatus_ok(tctx, r.out.result,
4955 "Failed to get lsa system access account");
4961 torture_comment(tctx, "Testing LSA Close\n");
4963 r.in.handle = &lsa_acct_handle;
4964 r.out.handle = &lsa_acct_handle;
4966 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_Close_r(lb, tctx, &r),
4967 "lsa_Close failed");
4968 torture_assert_ntstatus_ok(tctx, r.out.result,
4969 "Failed to close lsa");
4973 struct samr_DeleteUser r;
4975 torture_comment(tctx, "Testing SAMR DeleteUser\n");
4977 r.in.user_handle = user_handle;
4978 r.out.user_handle = user_handle;
4980 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, tctx, &r),
4981 "DeleteUser failed");
4982 torture_assert_ntstatus_ok(tctx, r.out.result,
4983 "DeleteUser failed");
4987 struct lsa_EnumAccounts r;
4988 uint32_t resume_handle = 0;
4989 struct lsa_SidArray lsa_sid_array;
4991 bool found_sid = false;
4993 torture_comment(tctx, "Testing LSA EnumAccounts\n");
4995 r.in.handle = lsa_handle;
4996 r.in.num_entries = 0x1000;
4997 r.in.resume_handle = &resume_handle;
4998 r.out.sids = &lsa_sid_array;
4999 r.out.resume_handle = &resume_handle;
5001 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(lb, tctx, &r),
5002 "lsa_EnumAccounts failed");
5003 torture_assert_ntstatus_ok(tctx, r.out.result,
5004 "Failed to enum accounts");
5006 for (i=0; i < lsa_sid_array.num_sids; i++) {
5007 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
5012 torture_assert(tctx, found_sid,
5013 "failed to list privileged account");
5017 struct lsa_EnumAccountRights r;
5018 struct lsa_RightSet user_rights;
5020 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
5022 r.in.handle = lsa_handle;
5023 r.in.sid = user_sid;
5024 r.out.rights = &user_rights;
5026 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
5027 "lsa_EnumAccountRights failed");
5028 torture_assert_ntstatus_ok(tctx, r.out.result,
5029 "Failed to enum rights for account");
5031 if (user_rights.count < 1) {
5032 torture_result(tctx, TORTURE_FAIL, "failed to find newly added rights");
5038 struct lsa_OpenAccount r;
5040 torture_comment(tctx, "Testing LSA OpenAccount\n");
5042 r.in.handle = lsa_handle;
5043 r.in.sid = user_sid;
5044 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5045 r.out.acct_handle = &lsa_acct_handle;
5047 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenAccount_r(lb, tctx, &r),
5048 "lsa_OpenAccount failed");
5049 torture_assert_ntstatus_ok(tctx, r.out.result,
5050 "Failed to open lsa account");
5054 struct lsa_GetSystemAccessAccount r;
5055 uint32_t access_mask;
5057 torture_comment(tctx, "Testing LSA GetSystemAccessAccount\n");
5059 r.in.handle = &lsa_acct_handle;
5060 r.out.access_mask = &access_mask;
5062 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetSystemAccessAccount_r(lb, tctx, &r),
5063 "lsa_GetSystemAccessAccount failed");
5064 torture_assert_ntstatus_ok(tctx, r.out.result,
5065 "Failed to get lsa system access account");
5069 struct lsa_DeleteObject r;
5071 torture_comment(tctx, "Testing LSA DeleteObject\n");
5073 r.in.handle = &lsa_acct_handle;
5074 r.out.handle = &lsa_acct_handle;
5076 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_DeleteObject_r(lb, tctx, &r),
5077 "lsa_DeleteObject failed");
5078 torture_assert_ntstatus_ok(tctx, r.out.result,
5079 "Failed to delete object");
5083 struct lsa_EnumAccounts r;
5084 uint32_t resume_handle = 0;
5085 struct lsa_SidArray lsa_sid_array;
5087 bool found_sid = false;
5089 torture_comment(tctx, "Testing LSA EnumAccounts\n");
5091 r.in.handle = lsa_handle;
5092 r.in.num_entries = 0x1000;
5093 r.in.resume_handle = &resume_handle;
5094 r.out.sids = &lsa_sid_array;
5095 r.out.resume_handle = &resume_handle;
5097 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(lb, tctx, &r),
5098 "lsa_EnumAccounts failed");
5099 torture_assert_ntstatus_ok(tctx, r.out.result,
5100 "Failed to enum accounts");
5102 for (i=0; i < lsa_sid_array.num_sids; i++) {
5103 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
5108 torture_assert(tctx, !found_sid,
5109 "should not have listed privileged account");
5113 struct lsa_EnumAccountRights r;
5114 struct lsa_RightSet user_rights;
5116 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
5118 r.in.handle = lsa_handle;
5119 r.in.sid = user_sid;
5120 r.out.rights = &user_rights;
5122 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
5123 "lsa_EnumAccountRights failed");
5124 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND,
5125 "Failed to enum rights for account");
5131 static bool test_user_ops(struct dcerpc_pipe *p,
5132 struct torture_context *tctx,
5133 struct policy_handle *user_handle,
5134 struct policy_handle *domain_handle,
5135 const struct dom_sid *domain_sid,
5136 uint32_t base_acct_flags,
5137 const char *base_acct_name, enum torture_samr_choice which_ops,
5138 struct cli_credentials *machine_credentials)
5140 char *password = NULL;
5141 struct samr_QueryUserInfo q;
5142 union samr_UserInfo *info;
5144 struct dcerpc_binding_handle *b = p->binding_handle;
5149 const uint32_t password_fields[] = {
5150 SAMR_FIELD_NT_PASSWORD_PRESENT,
5151 SAMR_FIELD_LM_PASSWORD_PRESENT,
5152 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
5156 status = test_LookupName(b, tctx, domain_handle, base_acct_name, &rid);
5157 if (!NT_STATUS_IS_OK(status)) {
5161 switch (which_ops) {
5162 case TORTURE_SAMR_USER_ATTRIBUTES:
5163 if (!test_QuerySecurity(b, tctx, user_handle)) {
5167 if (!test_QueryUserInfo(b, tctx, user_handle)) {
5171 if (!test_QueryUserInfo2(b, tctx, user_handle)) {
5175 if (!test_SetUserInfo(b, tctx, user_handle, base_acct_flags,
5180 if (!test_GetUserPwInfo(b, tctx, user_handle)) {
5184 if (!test_TestPrivateFunctionsUser(b, tctx, user_handle)) {
5188 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
5192 case TORTURE_SAMR_PASSWORDS:
5193 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
5194 char simple_pass[9];
5195 char *v = generate_random_str(tctx, 1);
5197 ZERO_STRUCT(simple_pass);
5198 memset(simple_pass, *v, sizeof(simple_pass) - 1);
5200 torture_comment(tctx, "Testing machine account password policy rules\n");
5202 /* Workstation trust accounts don't seem to need to honour password quality policy */
5203 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
5207 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
5211 /* reset again, to allow another 'user' password change */
5212 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
5216 /* Try a 'short' password */
5217 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
5221 /* Try a compleatly random password */
5222 if (!test_ChangePasswordRandomBytes(p, tctx, base_acct_name, user_handle, &password)) {
5227 for (i = 0; password_fields[i]; i++) {
5228 if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
5232 /* check it was set right */
5233 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
5238 for (i = 0; password_fields[i]; i++) {
5239 if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
5243 /* check it was set right */
5244 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
5249 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
5253 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
5257 if (!test_SetUserPass_18(p, tctx, user_handle, &password)) {
5261 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
5265 for (i = 0; password_fields[i]; i++) {
5267 if (password_fields[i] == SAMR_FIELD_LM_PASSWORD_PRESENT) {
5268 /* we need to skip as that would break
5269 * the ChangePasswordUser3 verify */
5273 if (!test_SetUserPass_21(p, tctx, user_handle, password_fields[i], &password)) {
5277 /* check it was set right */
5278 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
5283 q.in.user_handle = user_handle;
5287 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
5288 "QueryUserInfo failed");
5289 if (!NT_STATUS_IS_OK(q.out.result)) {
5290 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level %u failed - %s\n",
5291 q.in.level, nt_errstr(q.out.result));
5294 uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
5295 if ((info->info5.acct_flags) != expected_flags) {
5297 if (!torture_setting_bool(tctx, "samba3", false)) {
5298 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
5299 info->info5.acct_flags,
5304 if (info->info5.rid != rid) {
5305 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
5306 info->info5.rid, rid);
5313 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
5315 /* test last password change timestamp behaviour */
5316 torture_assert(tctx, test_SetPassword_pwdlastset(p, tctx, base_acct_flags,
5318 user_handle, &password,
5319 machine_credentials),
5320 "pwdLastSet test failed\n");
5323 case TORTURE_SAMR_PASSWORDS_BADPWDCOUNT:
5325 /* test bad pwd count change behaviour */
5326 torture_assert(tctx, test_Password_badpwdcount_wrap(p, tctx, base_acct_flags,
5329 user_handle, &password,
5330 machine_credentials),
5331 "badPwdCount test failed\n");
5334 case TORTURE_SAMR_PASSWORDS_LOCKOUT:
5336 torture_assert(tctx, test_Password_lockout_wrap(p, tctx, base_acct_flags,
5339 user_handle, &password,
5340 machine_credentials),
5341 "Lockout test failed");
5345 case TORTURE_SAMR_USER_PRIVILEGES: {
5347 struct dcerpc_pipe *lp;
5348 struct policy_handle *lsa_handle;
5349 struct dcerpc_binding_handle *lb;
5351 status = torture_rpc_connection(tctx, &lp, &ndr_table_lsarpc);
5352 torture_assert_ntstatus_ok(tctx, status, "Failed to open LSA pipe");
5353 lb = lp->binding_handle;
5355 if (!test_lsa_OpenPolicy2(lb, tctx, &lsa_handle)) {
5359 if (!test_DeleteUser_with_privs(p, lp, tctx,
5360 domain_handle, lsa_handle, user_handle,
5362 machine_credentials)) {
5366 if (!test_lsa_Close(lb, tctx, lsa_handle)) {
5371 torture_result(tctx, TORTURE_FAIL, "privileged user delete test failed\n");
5376 case TORTURE_SAMR_OTHER:
5377 case TORTURE_SAMR_MANY_ACCOUNTS:
5378 case TORTURE_SAMR_MANY_GROUPS:
5379 case TORTURE_SAMR_MANY_ALIASES:
5380 /* We just need the account to exist */
5386 static bool test_alias_ops(struct dcerpc_binding_handle *b,
5387 struct torture_context *tctx,
5388 struct policy_handle *alias_handle,
5389 const struct dom_sid *domain_sid)
5393 if (!torture_setting_bool(tctx, "samba3", false)) {
5394 if (!test_QuerySecurity(b, tctx, alias_handle)) {
5399 if (!test_QueryAliasInfo(b, tctx, alias_handle)) {
5403 if (!test_SetAliasInfo(b, tctx, alias_handle)) {
5407 if (!test_AddMemberToAlias(b, tctx, alias_handle, domain_sid)) {
5411 if (torture_setting_bool(tctx, "samba3", false) ||
5412 torture_setting_bool(tctx, "samba4", false)) {
5413 torture_comment(tctx, "skipping MultipleMembers Alias tests against Samba\n");
5417 if (!test_AddMultipleMembersToAlias(b, tctx, alias_handle)) {
5425 static bool test_DeleteUser(struct dcerpc_binding_handle *b,
5426 struct torture_context *tctx,
5427 struct policy_handle *user_handle)
5429 struct samr_DeleteUser d;
5430 torture_comment(tctx, "Testing DeleteUser\n");
5432 d.in.user_handle = user_handle;
5433 d.out.user_handle = user_handle;
5435 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, tctx, &d),
5436 "DeleteUser failed");
5437 torture_assert_ntstatus_ok(tctx, d.out.result, "DeleteUser");
5442 bool test_DeleteUser_byname(struct dcerpc_binding_handle *b,
5443 struct torture_context *tctx,
5444 struct policy_handle *handle, const char *name)
5447 struct samr_DeleteUser d;
5448 struct policy_handle user_handle;
5451 status = test_LookupName(b, tctx, handle, name, &rid);
5452 if (!NT_STATUS_IS_OK(status)) {
5456 status = test_OpenUser_byname(b, tctx, handle, name, &user_handle);
5457 if (!NT_STATUS_IS_OK(status)) {
5461 d.in.user_handle = &user_handle;
5462 d.out.user_handle = &user_handle;
5463 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, tctx, &d),
5464 "DeleteUser failed");
5465 if (!NT_STATUS_IS_OK(d.out.result)) {
5466 status = d.out.result;
5473 torture_result(tctx, TORTURE_FAIL, "DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
5478 static bool test_DeleteGroup_byname(struct dcerpc_binding_handle *b,
5479 struct torture_context *tctx,
5480 struct policy_handle *handle, const char *name)
5483 struct samr_OpenGroup r;
5484 struct samr_DeleteDomainGroup d;
5485 struct policy_handle group_handle;
5488 status = test_LookupName(b, tctx, handle, name, &rid);
5489 if (!NT_STATUS_IS_OK(status)) {
5493 r.in.domain_handle = handle;
5494 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5496 r.out.group_handle = &group_handle;
5497 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenGroup_r(b, tctx, &r),
5498 "OpenGroup failed");
5499 if (!NT_STATUS_IS_OK(r.out.result)) {
5500 status = r.out.result;
5504 d.in.group_handle = &group_handle;
5505 d.out.group_handle = &group_handle;
5506 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomainGroup_r(b, tctx, &d),
5507 "DeleteDomainGroup failed");
5508 if (!NT_STATUS_IS_OK(d.out.result)) {
5509 status = d.out.result;
5516 torture_result(tctx, TORTURE_FAIL, "DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
5521 static bool test_DeleteAlias_byname(struct dcerpc_binding_handle *b,
5522 struct torture_context *tctx,
5523 struct policy_handle *domain_handle,
5527 struct samr_OpenAlias r;
5528 struct samr_DeleteDomAlias d;
5529 struct policy_handle alias_handle;
5532 torture_comment(tctx, "Testing DeleteAlias_byname\n");
5534 status = test_LookupName(b, tctx, domain_handle, name, &rid);
5535 if (!NT_STATUS_IS_OK(status)) {
5539 r.in.domain_handle = domain_handle;
5540 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5542 r.out.alias_handle = &alias_handle;
5543 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenAlias_r(b, tctx, &r),
5544 "OpenAlias failed");
5545 if (!NT_STATUS_IS_OK(r.out.result)) {
5546 status = r.out.result;
5550 d.in.alias_handle = &alias_handle;
5551 d.out.alias_handle = &alias_handle;
5552 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomAlias_r(b, tctx, &d),
5553 "DeleteDomAlias failed");
5554 if (!NT_STATUS_IS_OK(d.out.result)) {
5555 status = d.out.result;
5562 torture_result(tctx, TORTURE_FAIL, "DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
5566 static bool test_DeleteAlias(struct dcerpc_binding_handle *b,
5567 struct torture_context *tctx,
5568 struct policy_handle *alias_handle)
5570 struct samr_DeleteDomAlias d;
5573 torture_comment(tctx, "Testing DeleteAlias\n");
5575 d.in.alias_handle = alias_handle;
5576 d.out.alias_handle = alias_handle;
5578 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomAlias_r(b, tctx, &d),
5579 "DeleteDomAlias failed");
5580 if (!NT_STATUS_IS_OK(d.out.result)) {
5581 torture_result(tctx, TORTURE_FAIL, "DeleteAlias failed - %s\n", nt_errstr(d.out.result));
5588 static bool test_CreateAlias(struct dcerpc_binding_handle *b,
5589 struct torture_context *tctx,
5590 struct policy_handle *domain_handle,
5591 const char *alias_name,
5592 struct policy_handle *alias_handle,
5593 const struct dom_sid *domain_sid,
5596 struct samr_CreateDomAlias r;
5597 struct lsa_String name;
5601 init_lsa_String(&name, alias_name);
5602 r.in.domain_handle = domain_handle;
5603 r.in.alias_name = &name;
5604 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5605 r.out.alias_handle = alias_handle;
5608 torture_comment(tctx, "Testing CreateAlias (%s)\n", r.in.alias_name->string);
5610 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomAlias_r(b, tctx, &r),
5611 "CreateDomAlias failed");
5613 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5614 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED)) {
5615 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.alias_name->string);
5618 torture_result(tctx, TORTURE_FAIL, "Server should have refused create of '%s', got %s instead\n", r.in.alias_name->string,
5619 nt_errstr(r.out.result));
5624 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ALIAS_EXISTS)) {
5625 if (!test_DeleteAlias_byname(b, tctx, domain_handle, r.in.alias_name->string)) {
5628 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomAlias_r(b, tctx, &r),
5629 "CreateDomAlias failed");
5632 if (!NT_STATUS_IS_OK(r.out.result)) {
5633 torture_result(tctx, TORTURE_FAIL, "CreateAlias failed - %s\n", nt_errstr(r.out.result));
5641 if (!test_alias_ops(b, tctx, alias_handle, domain_sid)) {
5648 static bool test_ChangePassword(struct dcerpc_pipe *p,
5649 struct torture_context *tctx,
5650 const char *acct_name,
5651 struct policy_handle *domain_handle, char **password)
5654 struct dcerpc_binding_handle *b = p->binding_handle;
5660 if (!test_ChangePasswordUser(b, tctx, acct_name, domain_handle, password)) {
5664 if (!test_ChangePasswordUser2(p, tctx, acct_name, password, 0, true)) {
5668 if (!test_OemChangePasswordUser2(p, tctx, acct_name, domain_handle, password)) {
5672 /* test what happens when setting the old password again */
5673 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, *password, 0, true)) {
5678 char simple_pass[9];
5679 char *v = generate_random_str(tctx, 1);
5681 ZERO_STRUCT(simple_pass);
5682 memset(simple_pass, *v, sizeof(simple_pass) - 1);
5684 /* test what happens when picking a simple password */
5685 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, simple_pass, 0, true)) {
5690 /* set samr_SetDomainInfo level 1 with min_length 5 */
5692 struct samr_QueryDomainInfo r;
5693 union samr_DomainInfo *info = NULL;
5694 struct samr_SetDomainInfo s;
5695 uint16_t len_old, len;
5696 uint32_t pwd_prop_old;
5697 int64_t min_pwd_age_old;
5701 r.in.domain_handle = domain_handle;
5705 torture_comment(tctx, "Testing samr_QueryDomainInfo level 1\n");
5706 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &r),
5707 "QueryDomainInfo failed");
5708 if (!NT_STATUS_IS_OK(r.out.result)) {
5712 s.in.domain_handle = domain_handle;
5716 /* remember the old min length, so we can reset it */
5717 len_old = s.in.info->info1.min_password_length;
5718 s.in.info->info1.min_password_length = len;
5719 pwd_prop_old = s.in.info->info1.password_properties;
5720 /* turn off password complexity checks for this test */
5721 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
5723 min_pwd_age_old = s.in.info->info1.min_password_age;
5724 s.in.info->info1.min_password_age = 0;
5726 torture_comment(tctx, "Testing samr_SetDomainInfo level 1\n");
5727 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
5728 "SetDomainInfo failed");
5729 if (!NT_STATUS_IS_OK(s.out.result)) {
5733 torture_comment(tctx, "calling test_ChangePasswordUser3 with too short password\n");
5735 if (!test_ChangePasswordUser3(p, tctx, acct_name, len - 1, password, NULL, 0, true)) {
5739 s.in.info->info1.min_password_length = len_old;
5740 s.in.info->info1.password_properties = pwd_prop_old;
5741 s.in.info->info1.min_password_age = min_pwd_age_old;
5743 torture_comment(tctx, "Testing samr_SetDomainInfo level 1\n");
5744 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
5745 "SetDomainInfo failed");
5746 if (!NT_STATUS_IS_OK(s.out.result)) {
5753 struct samr_OpenUser r;
5754 struct samr_QueryUserInfo q;
5755 union samr_UserInfo *info;
5756 struct samr_LookupNames n;
5757 struct policy_handle user_handle;
5758 struct samr_Ids rids, types;
5760 n.in.domain_handle = domain_handle;
5762 n.in.names = talloc_array(tctx, struct lsa_String, 1);
5763 n.in.names[0].string = acct_name;
5765 n.out.types = &types;
5767 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupNames_r(b, tctx, &n),
5768 "LookupNames failed");
5769 if (!NT_STATUS_IS_OK(n.out.result)) {
5770 torture_result(tctx, TORTURE_FAIL, "LookupNames failed - %s\n", nt_errstr(n.out.result));
5774 r.in.domain_handle = domain_handle;
5775 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5776 r.in.rid = n.out.rids->ids[0];
5777 r.out.user_handle = &user_handle;
5779 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
5781 if (!NT_STATUS_IS_OK(r.out.result)) {
5782 torture_result(tctx, TORTURE_FAIL, "OpenUser(%u) failed - %s\n", n.out.rids->ids[0], nt_errstr(r.out.result));
5786 q.in.user_handle = &user_handle;
5790 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
5791 "QueryUserInfo failed");
5792 if (!NT_STATUS_IS_OK(q.out.result)) {
5793 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo failed - %s\n", nt_errstr(q.out.result));
5797 torture_comment(tctx, "calling test_ChangePasswordUser3 with too early password change\n");
5799 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL,
5800 info->info5.last_password_change, true)) {
5805 /* we change passwords twice - this has the effect of verifying
5806 they were changed correctly for the final call */
5807 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
5811 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
5818 static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
5819 struct policy_handle *domain_handle,
5820 const char *user_name,
5821 struct policy_handle *user_handle_out,
5822 struct dom_sid *domain_sid,
5823 enum torture_samr_choice which_ops,
5824 struct cli_credentials *machine_credentials,
5828 TALLOC_CTX *user_ctx;
5830 struct samr_CreateUser r;
5831 struct samr_QueryUserInfo q;
5832 union samr_UserInfo *info;
5833 struct samr_DeleteUser d;
5836 /* This call creates a 'normal' account - check that it really does */
5837 const uint32_t acct_flags = ACB_NORMAL;
5838 struct lsa_String name;
5840 struct dcerpc_binding_handle *b = p->binding_handle;
5842 struct policy_handle user_handle;
5843 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
5844 init_lsa_String(&name, user_name);
5846 r.in.domain_handle = domain_handle;
5847 r.in.account_name = &name;
5848 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5849 r.out.user_handle = &user_handle;
5852 torture_comment(tctx, "Testing CreateUser(%s)\n", r.in.account_name->string);
5854 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser_r(b, user_ctx, &r),
5855 "CreateUser failed");
5857 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5858 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
5859 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.account_name->string);
5862 torture_result(tctx, TORTURE_FAIL, "Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
5863 nt_errstr(r.out.result));
5868 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_USER_EXISTS)) {
5869 if (!test_DeleteUser_byname(b, tctx, domain_handle, r.in.account_name->string)) {
5870 talloc_free(user_ctx);
5873 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser_r(b, user_ctx, &r),
5874 "CreateUser failed");
5877 if (!NT_STATUS_IS_OK(r.out.result)) {
5878 talloc_free(user_ctx);
5879 torture_result(tctx, TORTURE_FAIL, "CreateUser failed - %s\n", nt_errstr(r.out.result));
5884 if (user_handle_out) {
5885 *user_handle_out = user_handle;
5891 q.in.user_handle = &user_handle;
5895 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, user_ctx, &q),
5896 "QueryUserInfo failed");
5897 if (!NT_STATUS_IS_OK(q.out.result)) {
5898 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level %u failed - %s\n",
5899 q.in.level, nt_errstr(q.out.result));
5902 if ((info->info16.acct_flags & acct_flags) != acct_flags) {
5903 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
5904 info->info16.acct_flags,
5910 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
5911 domain_sid, acct_flags, name.string, which_ops,
5912 machine_credentials)) {
5916 if (user_handle_out) {
5917 *user_handle_out = user_handle;
5919 torture_comment(tctx, "Testing DeleteUser (createuser test)\n");
5921 d.in.user_handle = &user_handle;
5922 d.out.user_handle = &user_handle;
5924 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, user_ctx, &d),
5925 "DeleteUser failed");
5926 if (!NT_STATUS_IS_OK(d.out.result)) {
5927 torture_result(tctx, TORTURE_FAIL, "DeleteUser failed - %s\n", nt_errstr(d.out.result));
5934 talloc_free(user_ctx);
5940 static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
5941 struct policy_handle *domain_handle,
5942 struct dom_sid *domain_sid,
5943 enum torture_samr_choice which_ops,
5944 struct cli_credentials *machine_credentials)
5946 struct samr_CreateUser2 r;
5947 struct samr_QueryUserInfo q;
5948 union samr_UserInfo *info;
5949 struct samr_DeleteUser d;
5950 struct policy_handle user_handle;
5952 struct lsa_String name;
5955 struct dcerpc_binding_handle *b = p->binding_handle;
5958 uint32_t acct_flags;
5959 const char *account_name;
5961 } account_types[] = {
5962 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
5963 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5964 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5965 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
5966 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5967 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5968 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
5969 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5970 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5971 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_ACCESS_DENIED },
5972 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
5973 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
5974 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5975 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5976 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
5979 for (i = 0; account_types[i].account_name; i++) {
5980 TALLOC_CTX *user_ctx;
5981 uint32_t acct_flags = account_types[i].acct_flags;
5982 uint32_t access_granted;
5983 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
5984 init_lsa_String(&name, account_types[i].account_name);
5986 r.in.domain_handle = domain_handle;
5987 r.in.account_name = &name;
5988 r.in.acct_flags = acct_flags;
5989 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5990 r.out.user_handle = &user_handle;
5991 r.out.access_granted = &access_granted;
5994 torture_comment(tctx, "Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
5996 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser2_r(b, user_ctx, &r),
5997 "CreateUser2 failed");
5999 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
6000 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
6001 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.account_name->string);
6004 torture_result(tctx, TORTURE_FAIL, "Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
6005 nt_errstr(r.out.result));
6011 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_USER_EXISTS)) {
6012 if (!test_DeleteUser_byname(b, tctx, domain_handle, r.in.account_name->string)) {
6013 talloc_free(user_ctx);
6017 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser2_r(b, user_ctx, &r),
6018 "CreateUser2 failed");
6021 if (!NT_STATUS_EQUAL(r.out.result, account_types[i].nt_status)) {
6022 torture_result(tctx, TORTURE_FAIL, "CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
6023 nt_errstr(r.out.result), nt_errstr(account_types[i].nt_status));
6027 if (NT_STATUS_IS_OK(r.out.result)) {
6028 q.in.user_handle = &user_handle;
6032 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, user_ctx, &q),
6033 "QueryUserInfo failed");
6034 if (!NT_STATUS_IS_OK(q.out.result)) {
6035 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level %u failed - %s\n",
6036 q.in.level, nt_errstr(q.out.result));
6039 uint32_t expected_flags = (acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
6040 if (acct_flags == ACB_NORMAL) {
6041 expected_flags |= ACB_PW_EXPIRED;
6043 if ((info->info5.acct_flags) != expected_flags) {
6044 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
6045 info->info5.acct_flags,
6049 switch (acct_flags) {
6051 if (info->info5.primary_gid != DOMAIN_RID_DCS) {
6052 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level 5: DC should have had Primary Group %d, got %d\n",
6053 DOMAIN_RID_DCS, info->info5.primary_gid);
6058 if (info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
6059 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
6060 DOMAIN_RID_DOMAIN_MEMBERS, info->info5.primary_gid);
6065 if (info->info5.primary_gid != DOMAIN_RID_USERS) {
6066 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level 5: Users should have had Primary Group %d, got %d\n",
6067 DOMAIN_RID_USERS, info->info5.primary_gid);
6074 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
6075 domain_sid, acct_flags, name.string, which_ops,
6076 machine_credentials)) {
6080 if (!ndr_policy_handle_empty(&user_handle)) {
6081 torture_comment(tctx, "Testing DeleteUser (createuser2 test)\n");
6083 d.in.user_handle = &user_handle;
6084 d.out.user_handle = &user_handle;
6086 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, user_ctx, &d),
6087 "DeleteUser failed");
6088 if (!NT_STATUS_IS_OK(d.out.result)) {
6089 torture_result(tctx, TORTURE_FAIL, "DeleteUser failed - %s\n", nt_errstr(d.out.result));
6094 talloc_free(user_ctx);
6100 static bool test_QueryAliasInfo(struct dcerpc_binding_handle *b,
6101 struct torture_context *tctx,
6102 struct policy_handle *handle)
6104 struct samr_QueryAliasInfo r;
6105 union samr_AliasInfo *info;
6106 uint16_t levels[] = {1, 2, 3};
6110 for (i=0;i<ARRAY_SIZE(levels);i++) {
6111 torture_comment(tctx, "Testing QueryAliasInfo level %u\n", levels[i]);
6113 r.in.alias_handle = handle;
6114 r.in.level = levels[i];
6117 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryAliasInfo_r(b, tctx, &r),
6118 "QueryAliasInfo failed");
6119 if (!NT_STATUS_IS_OK(r.out.result)) {
6120 torture_result(tctx, TORTURE_FAIL, "QueryAliasInfo level %u failed - %s\n",
6121 levels[i], nt_errstr(r.out.result));
6129 static bool test_QueryGroupInfo(struct dcerpc_binding_handle *b,
6130 struct torture_context *tctx,
6131 struct policy_handle *handle)
6133 struct samr_QueryGroupInfo r;
6134 union samr_GroupInfo *info;
6135 uint16_t levels[] = {1, 2, 3, 4, 5};
6139 for (i=0;i<ARRAY_SIZE(levels);i++) {
6140 torture_comment(tctx, "Testing QueryGroupInfo level %u\n", levels[i]);
6142 r.in.group_handle = handle;
6143 r.in.level = levels[i];
6146 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupInfo_r(b, tctx, &r),
6147 "QueryGroupInfo failed");
6148 if (!NT_STATUS_IS_OK(r.out.result)) {
6149 torture_result(tctx, TORTURE_FAIL, "QueryGroupInfo level %u failed - %s\n",
6150 levels[i], nt_errstr(r.out.result));
6158 static bool test_QueryGroupMember(struct dcerpc_binding_handle *b,
6159 struct torture_context *tctx,
6160 struct policy_handle *handle)
6162 struct samr_QueryGroupMember r;
6163 struct samr_RidAttrArray *rids = NULL;
6166 torture_comment(tctx, "Testing QueryGroupMember\n");
6168 r.in.group_handle = handle;
6171 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupMember_r(b, tctx, &r),
6172 "QueryGroupMember failed");
6173 if (!NT_STATUS_IS_OK(r.out.result)) {
6174 torture_result(tctx, TORTURE_FAIL, "QueryGroupMember failed - %s\n", nt_errstr(r.out.result));
6182 static bool test_SetGroupInfo(struct dcerpc_binding_handle *b,
6183 struct torture_context *tctx,
6184 struct policy_handle *handle)
6186 struct samr_QueryGroupInfo r;
6187 union samr_GroupInfo *info;
6188 struct samr_SetGroupInfo s;
6189 uint16_t levels[] = {1, 2, 3, 4};
6190 uint16_t set_ok[] = {0, 1, 1, 1};
6194 for (i=0;i<ARRAY_SIZE(levels);i++) {
6195 torture_comment(tctx, "Testing QueryGroupInfo level %u\n", levels[i]);
6197 r.in.group_handle = handle;
6198 r.in.level = levels[i];
6201 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupInfo_r(b, tctx, &r),
6202 "QueryGroupInfo failed");
6203 if (!NT_STATUS_IS_OK(r.out.result)) {
6204 torture_result(tctx, TORTURE_FAIL, "QueryGroupInfo level %u failed - %s\n",
6205 levels[i], nt_errstr(r.out.result));
6209 torture_comment(tctx, "Testing SetGroupInfo level %u\n", levels[i]);
6211 s.in.group_handle = handle;
6212 s.in.level = levels[i];
6213 s.in.info = *r.out.info;
6216 /* disabled this, as it changes the name only from the point of view of samr,
6217 but leaves the name from the point of view of w2k3 internals (and ldap). This means
6218 the name is still reserved, so creating the old name fails, but deleting by the old name
6220 if (s.in.level == 2) {
6221 init_lsa_String(&s.in.info->string, "NewName");
6225 if (s.in.level == 4) {
6226 init_lsa_String(&s.in.info->description, "test description");
6229 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetGroupInfo_r(b, tctx, &s),
6230 "SetGroupInfo failed");
6232 if (!NT_STATUS_IS_OK(s.out.result)) {
6233 torture_result(tctx, TORTURE_FAIL, "SetGroupInfo level %u failed - %s\n",
6234 r.in.level, nt_errstr(s.out.result));
6239 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, s.out.result)) {
6240 torture_result(tctx, TORTURE_FAIL, "SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
6241 r.in.level, nt_errstr(s.out.result));
6251 static bool test_QueryUserInfo(struct dcerpc_binding_handle *b,
6252 struct torture_context *tctx,
6253 struct policy_handle *handle)
6255 struct samr_QueryUserInfo r;
6256 union samr_UserInfo *info;
6257 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
6258 11, 12, 13, 14, 16, 17, 20, 21};
6262 for (i=0;i<ARRAY_SIZE(levels);i++) {
6263 torture_comment(tctx, "Testing QueryUserInfo level %u\n", levels[i]);
6265 r.in.user_handle = handle;
6266 r.in.level = levels[i];
6269 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
6270 "QueryUserInfo failed");
6271 if (!NT_STATUS_IS_OK(r.out.result)) {
6272 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level %u failed - %s\n",
6273 levels[i], nt_errstr(r.out.result));
6281 static bool test_QueryUserInfo2(struct dcerpc_binding_handle *b,
6282 struct torture_context *tctx,
6283 struct policy_handle *handle)
6285 struct samr_QueryUserInfo2 r;
6286 union samr_UserInfo *info;
6287 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
6288 11, 12, 13, 14, 16, 17, 20, 21};
6292 for (i=0;i<ARRAY_SIZE(levels);i++) {
6293 torture_comment(tctx, "Testing QueryUserInfo2 level %u\n", levels[i]);
6295 r.in.user_handle = handle;
6296 r.in.level = levels[i];
6299 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo2_r(b, tctx, &r),
6300 "QueryUserInfo2 failed");
6301 if (!NT_STATUS_IS_OK(r.out.result)) {
6302 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo2 level %u failed - %s\n",
6303 levels[i], nt_errstr(r.out.result));
6311 static bool test_OpenUser(struct dcerpc_binding_handle *b,
6312 struct torture_context *tctx,
6313 struct policy_handle *handle, uint32_t rid)
6315 struct samr_OpenUser r;
6316 struct policy_handle user_handle;
6319 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
6321 r.in.domain_handle = handle;
6322 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6324 r.out.user_handle = &user_handle;
6326 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
6328 if (!NT_STATUS_IS_OK(r.out.result)) {
6329 torture_result(tctx, TORTURE_FAIL, "OpenUser(%u) failed - %s\n", rid, nt_errstr(r.out.result));
6333 if (!test_QuerySecurity(b, tctx, &user_handle)) {
6337 if (!test_QueryUserInfo(b, tctx, &user_handle)) {
6341 if (!test_QueryUserInfo2(b, tctx, &user_handle)) {
6345 if (!test_GetUserPwInfo(b, tctx, &user_handle)) {
6349 if (!test_GetGroupsForUser(b, tctx, &user_handle)) {
6353 if (!test_samr_handle_Close(b, tctx, &user_handle)) {
6360 static bool test_OpenGroup(struct dcerpc_binding_handle *b,
6361 struct torture_context *tctx,
6362 struct policy_handle *handle, uint32_t rid)
6364 struct samr_OpenGroup r;
6365 struct policy_handle group_handle;
6368 torture_comment(tctx, "Testing OpenGroup(%u)\n", rid);
6370 r.in.domain_handle = handle;
6371 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6373 r.out.group_handle = &group_handle;
6375 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenGroup_r(b, tctx, &r),
6376 "OpenGroup failed");
6377 if (!NT_STATUS_IS_OK(r.out.result)) {
6378 torture_result(tctx, TORTURE_FAIL, "OpenGroup(%u) failed - %s\n", rid, nt_errstr(r.out.result));
6382 if (!torture_setting_bool(tctx, "samba3", false)) {
6383 if (!test_QuerySecurity(b, tctx, &group_handle)) {
6388 if (!test_QueryGroupInfo(b, tctx, &group_handle)) {
6392 if (!test_QueryGroupMember(b, tctx, &group_handle)) {
6396 if (!test_samr_handle_Close(b, tctx, &group_handle)) {
6403 static bool test_OpenAlias(struct dcerpc_binding_handle *b,
6404 struct torture_context *tctx,
6405 struct policy_handle *handle, uint32_t rid)
6407 struct samr_OpenAlias r;
6408 struct policy_handle alias_handle;
6411 torture_comment(tctx, "Testing OpenAlias(%u)\n", rid);
6413 r.in.domain_handle = handle;
6414 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6416 r.out.alias_handle = &alias_handle;
6418 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenAlias_r(b, tctx, &r),
6419 "OpenAlias failed");
6420 if (!NT_STATUS_IS_OK(r.out.result)) {
6421 torture_result(tctx, TORTURE_FAIL, "OpenAlias(%u) failed - %s\n", rid, nt_errstr(r.out.result));
6425 if (!torture_setting_bool(tctx, "samba3", false)) {
6426 if (!test_QuerySecurity(b, tctx, &alias_handle)) {
6431 if (!test_QueryAliasInfo(b, tctx, &alias_handle)) {
6435 if (!test_GetMembersInAlias(b, tctx, &alias_handle)) {
6439 if (!test_samr_handle_Close(b, tctx, &alias_handle)) {
6446 static bool check_mask(struct dcerpc_binding_handle *b,
6447 struct torture_context *tctx,
6448 struct policy_handle *handle, uint32_t rid,
6449 uint32_t acct_flag_mask)
6451 struct samr_OpenUser r;
6452 struct samr_QueryUserInfo q;
6453 union samr_UserInfo *info;
6454 struct policy_handle user_handle;
6457 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
6459 r.in.domain_handle = handle;
6460 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6462 r.out.user_handle = &user_handle;
6464 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
6466 if (!NT_STATUS_IS_OK(r.out.result)) {
6467 torture_result(tctx, TORTURE_FAIL, "OpenUser(%u) failed - %s\n", rid, nt_errstr(r.out.result));
6471 q.in.user_handle = &user_handle;
6475 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
6476 "QueryUserInfo failed");
6477 if (!NT_STATUS_IS_OK(q.out.result)) {
6478 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level 16 failed - %s\n",
6479 nt_errstr(q.out.result));
6482 if ((acct_flag_mask & info->info16.acct_flags) == 0) {
6483 torture_result(tctx, TORTURE_FAIL, "Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
6484 acct_flag_mask, info->info16.acct_flags, rid);
6489 if (!test_samr_handle_Close(b, tctx, &user_handle)) {
6496 static bool test_EnumDomainUsers_all(struct dcerpc_binding_handle *b,
6497 struct torture_context *tctx,
6498 struct policy_handle *handle)
6500 struct samr_EnumDomainUsers r;
6501 uint32_t mask, resume_handle=0;
6504 struct samr_LookupNames n;
6505 struct samr_LookupRids lr ;
6506 struct lsa_Strings names;
6507 struct samr_Ids rids, types;
6508 struct samr_SamArray *sam = NULL;
6509 uint32_t num_entries = 0;
6511 uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
6512 ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
6513 ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
6516 torture_comment(tctx, "Testing EnumDomainUsers\n");
6518 for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
6519 r.in.domain_handle = handle;
6520 r.in.resume_handle = &resume_handle;
6521 r.in.acct_flags = mask = masks[mask_idx];
6522 r.in.max_size = (uint32_t)-1;
6523 r.out.resume_handle = &resume_handle;
6524 r.out.num_entries = &num_entries;
6527 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainUsers_r(b, tctx, &r),
6528 "EnumDomainUsers failed");
6529 if (!NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) &&
6530 !NT_STATUS_IS_OK(r.out.result)) {
6531 torture_result(tctx, TORTURE_FAIL, "EnumDomainUsers failed - %s\n", nt_errstr(r.out.result));
6535 torture_assert(tctx, sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
6537 if (sam->count == 0) {
6541 for (i=0;i<sam->count;i++) {
6543 if (!check_mask(b, tctx, handle, sam->entries[i].idx, mask)) {
6546 } else if (!test_OpenUser(b, tctx, handle, sam->entries[i].idx)) {
6552 torture_comment(tctx, "Testing LookupNames\n");
6553 n.in.domain_handle = handle;
6554 n.in.num_names = sam->count;
6555 n.in.names = talloc_array(tctx, struct lsa_String, sam->count);
6557 n.out.types = &types;
6558 for (i=0;i<sam->count;i++) {
6559 n.in.names[i].string = sam->entries[i].name.string;
6561 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupNames_r(b, tctx, &n),
6562 "LookupNames failed");
6563 if (!NT_STATUS_IS_OK(n.out.result)) {
6564 torture_result(tctx, TORTURE_FAIL, "LookupNames failed - %s\n", nt_errstr(n.out.result));
6569 torture_comment(tctx, "Testing LookupRids\n");
6570 lr.in.domain_handle = handle;
6571 lr.in.num_rids = sam->count;
6572 lr.in.rids = talloc_array(tctx, uint32_t, sam->count);
6573 lr.out.names = &names;
6574 lr.out.types = &types;
6575 for (i=0;i<sam->count;i++) {
6576 lr.in.rids[i] = sam->entries[i].idx;
6578 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupRids_r(b, tctx, &lr),
6579 "LookupRids failed");
6580 torture_assert_ntstatus_ok(tctx, lr.out.result, "LookupRids");
6586 try blasting the server with a bunch of sync requests
6588 static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, struct torture_context *tctx,
6589 struct policy_handle *handle)
6591 struct samr_EnumDomainUsers r;
6592 uint32_t resume_handle=0;
6594 #define ASYNC_COUNT 100
6595 struct tevent_req *req[ASYNC_COUNT];
6597 if (!torture_setting_bool(tctx, "dangerous", false)) {
6598 torture_skip(tctx, "samr async test disabled - enable dangerous tests to use\n");
6601 torture_comment(tctx, "Testing EnumDomainUsers_async\n");
6603 r.in.domain_handle = handle;
6604 r.in.resume_handle = &resume_handle;
6605 r.in.acct_flags = 0;
6606 r.in.max_size = (uint32_t)-1;
6607 r.out.resume_handle = &resume_handle;
6609 for (i=0;i<ASYNC_COUNT;i++) {
6610 req[i] = dcerpc_samr_EnumDomainUsers_r_send(tctx, tctx->ev, p->binding_handle, &r);
6613 for (i=0;i<ASYNC_COUNT;i++) {
6614 tevent_req_poll(req[i], tctx->ev);
6615 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainUsers_r_recv(req[i], tctx),
6616 talloc_asprintf(tctx, "EnumDomainUsers[%d] failed - %s\n",
6617 i, nt_errstr(r.out.result)));
6620 torture_comment(tctx, "%d async requests OK\n", i);
6625 static bool test_EnumDomainGroups_all(struct dcerpc_binding_handle *b,
6626 struct torture_context *tctx,
6627 struct policy_handle *handle)
6629 struct samr_EnumDomainGroups r;
6630 uint32_t resume_handle=0;
6631 struct samr_SamArray *sam = NULL;
6632 uint32_t num_entries = 0;
6635 bool universal_group_found = false;
6637 torture_comment(tctx, "Testing EnumDomainGroups\n");
6639 r.in.domain_handle = handle;
6640 r.in.resume_handle = &resume_handle;
6641 r.in.max_size = (uint32_t)-1;
6642 r.out.resume_handle = &resume_handle;
6643 r.out.num_entries = &num_entries;
6646 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainGroups_r(b, tctx, &r),
6647 "EnumDomainGroups failed");
6648 if (!NT_STATUS_IS_OK(r.out.result)) {
6649 torture_result(tctx, TORTURE_FAIL, "EnumDomainGroups failed - %s\n", nt_errstr(r.out.result));
6657 for (i=0;i<sam->count;i++) {
6658 if (!test_OpenGroup(b, tctx, handle, sam->entries[i].idx)) {
6661 if ((ret == true) && (strcasecmp(sam->entries[i].name.string,
6662 "Enterprise Admins") == 0)) {
6663 universal_group_found = true;
6667 /* when we are running this on s4 we should get back at least the
6668 * "Enterprise Admins" universal group. If we don't get a group entry
6669 * at all we probably are performing the test on the builtin domain.
6670 * So ignore this case. */
6671 if (torture_setting_bool(tctx, "samba4", false)) {
6672 if ((sam->count > 0) && (!universal_group_found)) {
6680 static bool test_EnumDomainAliases_all(struct dcerpc_binding_handle *b,
6681 struct torture_context *tctx,
6682 struct policy_handle *handle)
6684 struct samr_EnumDomainAliases r;
6685 uint32_t resume_handle=0;
6686 struct samr_SamArray *sam = NULL;
6687 uint32_t num_entries = 0;
6691 torture_comment(tctx, "Testing EnumDomainAliases\n");
6693 r.in.domain_handle = handle;
6694 r.in.resume_handle = &resume_handle;
6695 r.in.max_size = (uint32_t)-1;
6697 r.out.num_entries = &num_entries;
6698 r.out.resume_handle = &resume_handle;
6700 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainAliases_r(b, tctx, &r),
6701 "EnumDomainAliases failed");
6702 if (!NT_STATUS_IS_OK(r.out.result)) {
6703 torture_result(tctx, TORTURE_FAIL, "EnumDomainAliases failed - %s\n", nt_errstr(r.out.result));
6711 for (i=0;i<sam->count;i++) {
6712 if (!test_OpenAlias(b, tctx, handle, sam->entries[i].idx)) {
6720 static bool test_GetDisplayEnumerationIndex(struct dcerpc_binding_handle *b,
6721 struct torture_context *tctx,
6722 struct policy_handle *handle)
6724 struct samr_GetDisplayEnumerationIndex r;
6726 uint16_t levels[] = {1, 2, 3, 4, 5};
6727 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
6728 struct lsa_String name;
6732 for (i=0;i<ARRAY_SIZE(levels);i++) {
6733 torture_comment(tctx, "Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
6735 init_lsa_String(&name, TEST_ACCOUNT_NAME);
6737 r.in.domain_handle = handle;
6738 r.in.level = levels[i];
6742 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex_r(b, tctx, &r),
6743 "GetDisplayEnumerationIndex failed");
6746 !NT_STATUS_IS_OK(r.out.result) &&
6747 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
6748 torture_result(tctx, TORTURE_FAIL, "GetDisplayEnumerationIndex level %u failed - %s\n",
6749 levels[i], nt_errstr(r.out.result));
6753 init_lsa_String(&name, "zzzzzzzz");
6755 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex_r(b, tctx, &r),
6756 "GetDisplayEnumerationIndex failed");
6758 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
6759 torture_result(tctx, TORTURE_FAIL, "GetDisplayEnumerationIndex level %u failed - %s\n",
6760 levels[i], nt_errstr(r.out.result));
6768 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_binding_handle *b,
6769 struct torture_context *tctx,
6770 struct policy_handle *handle)
6772 struct samr_GetDisplayEnumerationIndex2 r;
6774 uint16_t levels[] = {1, 2, 3, 4, 5};
6775 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
6776 struct lsa_String name;
6780 for (i=0;i<ARRAY_SIZE(levels);i++) {
6781 torture_comment(tctx, "Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
6783 init_lsa_String(&name, TEST_ACCOUNT_NAME);
6785 r.in.domain_handle = handle;
6786 r.in.level = levels[i];
6790 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex2_r(b, tctx, &r),
6791 "GetDisplayEnumerationIndex2 failed");
6793 !NT_STATUS_IS_OK(r.out.result) &&
6794 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
6795 torture_result(tctx, TORTURE_FAIL, "GetDisplayEnumerationIndex2 level %u failed - %s\n",
6796 levels[i], nt_errstr(r.out.result));
6800 init_lsa_String(&name, "zzzzzzzz");
6802 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex2_r(b, tctx, &r),
6803 "GetDisplayEnumerationIndex2 failed");
6804 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
6805 torture_result(tctx, TORTURE_FAIL, "GetDisplayEnumerationIndex2 level %u failed - %s\n",
6806 levels[i], nt_errstr(r.out.result));
6814 #define STRING_EQUAL_QUERY(s1, s2, user) \
6815 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
6816 /* odd, but valid */ \
6817 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
6818 torture_result(tctx, TORTURE_FAIL, "%s mismatch for %s: %s != %s (%s)\n", \
6819 #s1, user.string, s1.string, s2.string, __location__); \
6822 #define INT_EQUAL_QUERY(s1, s2, user) \
6824 torture_result(tctx, TORTURE_FAIL, "%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
6825 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
6829 static bool test_each_DisplayInfo_user(struct dcerpc_binding_handle *b,
6830 struct torture_context *tctx,
6831 struct samr_QueryDisplayInfo *querydisplayinfo,
6832 bool *seen_testuser)
6834 struct samr_OpenUser r;
6835 struct samr_QueryUserInfo q;
6836 union samr_UserInfo *info;
6837 struct policy_handle user_handle;
6839 r.in.domain_handle = querydisplayinfo->in.domain_handle;
6840 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6841 for (i = 0; ; i++) {
6842 switch (querydisplayinfo->in.level) {
6844 if (i >= querydisplayinfo->out.info->info1.count) {
6847 r.in.rid = querydisplayinfo->out.info->info1.entries[i].rid;
6850 if (i >= querydisplayinfo->out.info->info2.count) {
6853 r.in.rid = querydisplayinfo->out.info->info2.entries[i].rid;
6859 /* Not interested in validating just the account name */
6863 r.out.user_handle = &user_handle;
6865 switch (querydisplayinfo->in.level) {
6868 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
6870 if (!NT_STATUS_IS_OK(r.out.result)) {
6871 torture_result(tctx, TORTURE_FAIL, "OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(r.out.result));
6876 q.in.user_handle = &user_handle;
6879 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
6880 "QueryUserInfo failed");
6881 if (!NT_STATUS_IS_OK(r.out.result)) {
6882 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(r.out.result));
6886 switch (querydisplayinfo->in.level) {
6888 if (seen_testuser && strcmp(info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
6889 *seen_testuser = true;
6891 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].full_name,
6892 info->info21.full_name, info->info21.account_name);
6893 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].account_name,
6894 info->info21.account_name, info->info21.account_name);
6895 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].description,
6896 info->info21.description, info->info21.account_name);
6897 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].rid,
6898 info->info21.rid, info->info21.account_name);
6899 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].acct_flags,
6900 info->info21.acct_flags, info->info21.account_name);
6904 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].account_name,
6905 info->info21.account_name, info->info21.account_name);
6906 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].description,
6907 info->info21.description, info->info21.account_name);
6908 INT_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].rid,
6909 info->info21.rid, info->info21.account_name);
6910 INT_EQUAL_QUERY((querydisplayinfo->out.info->info2.entries[i].acct_flags & ~ACB_NORMAL),
6911 info->info21.acct_flags, info->info21.account_name);
6913 if (!(querydisplayinfo->out.info->info2.entries[i].acct_flags & ACB_NORMAL)) {
6914 torture_result(tctx, TORTURE_FAIL, "Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
6915 info->info21.account_name.string);
6918 if (!(info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
6919 torture_result(tctx, TORTURE_FAIL, "Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
6920 info->info21.account_name.string,
6921 querydisplayinfo->out.info->info2.entries[i].acct_flags,
6922 info->info21.acct_flags);
6929 if (!test_samr_handle_Close(b, tctx, &user_handle)) {
6936 static bool test_QueryDisplayInfo(struct dcerpc_binding_handle *b,
6937 struct torture_context *tctx,
6938 struct policy_handle *handle)
6940 struct samr_QueryDisplayInfo r;
6941 struct samr_QueryDomainInfo dom_info;
6942 union samr_DomainInfo *info = NULL;
6944 uint16_t levels[] = {1, 2, 3, 4, 5};
6946 bool seen_testuser = false;
6947 uint32_t total_size;
6948 uint32_t returned_size;
6949 union samr_DispInfo disp_info;
6952 for (i=0;i<ARRAY_SIZE(levels);i++) {
6953 torture_comment(tctx, "Testing QueryDisplayInfo level %u\n", levels[i]);
6956 r.out.result = STATUS_MORE_ENTRIES;
6957 while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES)) {
6958 r.in.domain_handle = handle;
6959 r.in.level = levels[i];
6960 r.in.max_entries = 2;
6961 r.in.buf_size = (uint32_t)-1;
6962 r.out.total_size = &total_size;
6963 r.out.returned_size = &returned_size;
6964 r.out.info = &disp_info;
6966 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &r),
6967 "QueryDisplayInfo failed");
6968 if (!NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(r.out.result)) {
6969 torture_result(tctx, TORTURE_FAIL, "QueryDisplayInfo level %u failed - %s\n",
6970 levels[i], nt_errstr(r.out.result));
6973 switch (r.in.level) {
6975 if (!test_each_DisplayInfo_user(b, tctx, &r, &seen_testuser)) {
6978 r.in.start_idx += r.out.info->info1.count;
6981 if (!test_each_DisplayInfo_user(b, tctx, &r, NULL)) {
6984 r.in.start_idx += r.out.info->info2.count;
6987 r.in.start_idx += r.out.info->info3.count;
6990 r.in.start_idx += r.out.info->info4.count;
6993 r.in.start_idx += r.out.info->info5.count;
6997 dom_info.in.domain_handle = handle;
6998 dom_info.in.level = 2;
6999 dom_info.out.info = &info;
7001 /* Check number of users returned is correct */
7002 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &dom_info),
7003 "QueryDomainInfo failed");
7004 if (!NT_STATUS_IS_OK(dom_info.out.result)) {
7005 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo level %u failed - %s\n",
7006 r.in.level, nt_errstr(dom_info.out.result));
7010 switch (r.in.level) {
7013 if (info->general.num_users < r.in.start_idx) {
7014 /* On AD deployments this numbers don't match
7015 * since QueryDisplayInfo returns universal and
7016 * global groups, QueryDomainInfo only global
7018 if (torture_setting_bool(tctx, "samba3", false)) {
7019 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
7020 r.in.start_idx, info->general.num_groups,
7021 info->general.domain_name.string);
7025 if (!seen_testuser) {
7026 struct policy_handle user_handle;
7027 if (NT_STATUS_IS_OK(test_OpenUser_byname(b, tctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
7028 torture_result(tctx, TORTURE_FAIL, "Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
7029 info->general.domain_name.string);
7031 test_samr_handle_Close(b, tctx, &user_handle);
7037 if (info->general.num_groups != r.in.start_idx) {
7038 /* On AD deployments this numbers don't match
7039 * since QueryDisplayInfo returns universal and
7040 * global groups, QueryDomainInfo only global
7042 if (torture_setting_bool(tctx, "samba3", false)) {
7043 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
7044 r.in.start_idx, info->general.num_groups,
7045 info->general.domain_name.string);
7058 static bool test_QueryDisplayInfo2(struct dcerpc_binding_handle *b,
7059 struct torture_context *tctx,
7060 struct policy_handle *handle)
7062 struct samr_QueryDisplayInfo2 r;
7064 uint16_t levels[] = {1, 2, 3, 4, 5};
7066 uint32_t total_size;
7067 uint32_t returned_size;
7068 union samr_DispInfo info;
7070 for (i=0;i<ARRAY_SIZE(levels);i++) {
7071 torture_comment(tctx, "Testing QueryDisplayInfo2 level %u\n", levels[i]);
7073 r.in.domain_handle = handle;
7074 r.in.level = levels[i];
7076 r.in.max_entries = 1000;
7077 r.in.buf_size = (uint32_t)-1;
7078 r.out.total_size = &total_size;
7079 r.out.returned_size = &returned_size;
7082 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo2_r(b, tctx, &r),
7083 "QueryDisplayInfo2 failed");
7084 if (!NT_STATUS_IS_OK(r.out.result)) {
7085 torture_result(tctx, TORTURE_FAIL, "QueryDisplayInfo2 level %u failed - %s\n",
7086 levels[i], nt_errstr(r.out.result));
7094 static bool test_QueryDisplayInfo3(struct dcerpc_binding_handle *b,
7095 struct torture_context *tctx,
7096 struct policy_handle *handle)
7098 struct samr_QueryDisplayInfo3 r;
7100 uint16_t levels[] = {1, 2, 3, 4, 5};
7102 uint32_t total_size;
7103 uint32_t returned_size;
7104 union samr_DispInfo info;
7106 for (i=0;i<ARRAY_SIZE(levels);i++) {
7107 torture_comment(tctx, "Testing QueryDisplayInfo3 level %u\n", levels[i]);
7109 r.in.domain_handle = handle;
7110 r.in.level = levels[i];
7112 r.in.max_entries = 1000;
7113 r.in.buf_size = (uint32_t)-1;
7114 r.out.total_size = &total_size;
7115 r.out.returned_size = &returned_size;
7118 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo3_r(b, tctx, &r),
7119 "QueryDisplayInfo3 failed");
7120 if (!NT_STATUS_IS_OK(r.out.result)) {
7121 torture_result(tctx, TORTURE_FAIL, "QueryDisplayInfo3 level %u failed - %s\n",
7122 levels[i], nt_errstr(r.out.result));
7131 static bool test_QueryDisplayInfo_continue(struct dcerpc_binding_handle *b,
7132 struct torture_context *tctx,
7133 struct policy_handle *handle)
7135 struct samr_QueryDisplayInfo r;
7137 uint32_t total_size;
7138 uint32_t returned_size;
7139 union samr_DispInfo info;
7141 torture_comment(tctx, "Testing QueryDisplayInfo continuation\n");
7143 r.in.domain_handle = handle;
7146 r.in.max_entries = 1;
7147 r.in.buf_size = (uint32_t)-1;
7148 r.out.total_size = &total_size;
7149 r.out.returned_size = &returned_size;
7153 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &r),
7154 "QueryDisplayInfo failed");
7155 if (NT_STATUS_IS_OK(r.out.result) && *r.out.returned_size != 0) {
7156 if (r.out.info->info1.entries[0].idx != r.in.start_idx + 1) {
7157 torture_result(tctx, TORTURE_FAIL, "expected idx %d but got %d\n",
7159 r.out.info->info1.entries[0].idx);
7163 if (!NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) &&
7164 !NT_STATUS_IS_OK(r.out.result)) {
7165 torture_result(tctx, TORTURE_FAIL, "QueryDisplayInfo level %u failed - %s\n",
7166 r.in.level, nt_errstr(r.out.result));
7171 } while ((NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) ||
7172 NT_STATUS_IS_OK(r.out.result)) &&
7173 *r.out.returned_size != 0);
7178 static bool test_QueryDomainInfo(struct dcerpc_pipe *p,
7179 struct torture_context *tctx,
7180 struct policy_handle *handle)
7182 struct samr_QueryDomainInfo r;
7183 union samr_DomainInfo *info = NULL;
7184 struct samr_SetDomainInfo s;
7185 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
7186 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
7189 struct dcerpc_binding_handle *b = p->binding_handle;
7190 const char *domain_comment = talloc_asprintf(tctx,
7191 "Tortured by Samba4 RPC-SAMR: %s",
7192 timestring(tctx, time(NULL)));
7194 s.in.domain_handle = handle;
7196 s.in.info = talloc(tctx, union samr_DomainInfo);
7198 s.in.info->oem.oem_information.string = domain_comment;
7199 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
7200 "SetDomainInfo failed");
7201 if (!NT_STATUS_IS_OK(s.out.result)) {
7202 torture_result(tctx, TORTURE_FAIL, "SetDomainInfo level %u (set comment) failed - %s\n",
7203 s.in.level, nt_errstr(s.out.result));
7207 for (i=0;i<ARRAY_SIZE(levels);i++) {
7208 torture_comment(tctx, "Testing QueryDomainInfo level %u\n", levels[i]);
7210 r.in.domain_handle = handle;
7211 r.in.level = levels[i];
7214 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &r),
7215 "QueryDomainInfo failed");
7216 if (!NT_STATUS_IS_OK(r.out.result)) {
7217 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo level %u failed - %s\n",
7218 r.in.level, nt_errstr(r.out.result));
7223 switch (levels[i]) {
7225 if (strcmp(info->general.oem_information.string, domain_comment) != 0) {
7226 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
7227 levels[i], info->general.oem_information.string, domain_comment);
7228 if (!torture_setting_bool(tctx, "samba3", false)) {
7232 if (!info->general.primary.string) {
7233 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo level %u returned no PDC name\n",
7236 } else if (info->general.role == SAMR_ROLE_DOMAIN_PDC) {
7237 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), info->general.primary.string) != 0) {
7238 if (torture_setting_bool(tctx, "samba3", false)) {
7239 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
7240 levels[i], info->general.primary.string, dcerpc_server_name(p));
7246 if (strcmp(info->oem.oem_information.string, domain_comment) != 0) {
7247 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
7248 levels[i], info->oem.oem_information.string, domain_comment);
7249 if (!torture_setting_bool(tctx, "samba3", false)) {
7255 if (!info->info6.primary.string) {
7256 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo level %u returned no PDC name\n",
7262 if (strcmp(info->general2.general.oem_information.string, domain_comment) != 0) {
7263 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
7264 levels[i], info->general2.general.oem_information.string, domain_comment);
7265 if (!torture_setting_bool(tctx, "samba3", false)) {
7272 torture_comment(tctx, "Testing SetDomainInfo level %u\n", levels[i]);
7274 s.in.domain_handle = handle;
7275 s.in.level = levels[i];
7278 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
7279 "SetDomainInfo failed");
7281 if (!NT_STATUS_IS_OK(s.out.result)) {
7282 torture_result(tctx, TORTURE_FAIL, "SetDomainInfo level %u failed - %s\n",
7283 r.in.level, nt_errstr(s.out.result));
7288 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, s.out.result)) {
7289 torture_result(tctx, TORTURE_FAIL, "SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
7290 r.in.level, nt_errstr(s.out.result));
7296 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &r),
7297 "QueryDomainInfo failed");
7298 if (!NT_STATUS_IS_OK(r.out.result)) {
7299 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo level %u failed - %s\n",
7300 r.in.level, nt_errstr(r.out.result));
7310 static bool test_QueryDomainInfo2(struct dcerpc_binding_handle *b,
7311 struct torture_context *tctx,
7312 struct policy_handle *handle)
7314 struct samr_QueryDomainInfo2 r;
7315 union samr_DomainInfo *info = NULL;
7316 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
7320 for (i=0;i<ARRAY_SIZE(levels);i++) {
7321 torture_comment(tctx, "Testing QueryDomainInfo2 level %u\n", levels[i]);
7323 r.in.domain_handle = handle;
7324 r.in.level = levels[i];
7327 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo2_r(b, tctx, &r),
7328 "QueryDomainInfo2 failed");
7329 if (!NT_STATUS_IS_OK(r.out.result)) {
7330 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo2 level %u failed - %s\n",
7331 r.in.level, nt_errstr(r.out.result));
7340 /* Test whether querydispinfo level 5 and enumdomgroups return the same
7341 set of group names. */
7342 static bool test_GroupList(struct dcerpc_binding_handle *b,
7343 struct torture_context *tctx,
7344 struct dom_sid *domain_sid,
7345 struct policy_handle *handle)
7347 struct samr_EnumDomainGroups q1;
7348 struct samr_QueryDisplayInfo q2;
7350 uint32_t resume_handle=0;
7351 struct samr_SamArray *sam = NULL;
7352 uint32_t num_entries = 0;
7355 uint32_t total_size;
7356 uint32_t returned_size;
7357 union samr_DispInfo info;
7359 size_t num_names = 0;
7360 const char **names = NULL;
7362 bool builtin_domain = dom_sid_compare(domain_sid,
7363 &global_sid_Builtin) == 0;
7365 torture_comment(tctx, "Testing coherency of querydispinfo vs enumdomgroups\n");
7367 q1.in.domain_handle = handle;
7368 q1.in.resume_handle = &resume_handle;
7370 q1.out.resume_handle = &resume_handle;
7371 q1.out.num_entries = &num_entries;
7374 status = STATUS_MORE_ENTRIES;
7375 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
7376 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainGroups_r(b, tctx, &q1),
7377 "EnumDomainGroups failed");
7378 status = q1.out.result;
7380 if (!NT_STATUS_IS_OK(status) &&
7381 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
7384 for (i=0; i<*q1.out.num_entries; i++) {
7385 add_string_to_array(tctx,
7386 sam->entries[i].name.string,
7387 &names, &num_names);
7391 torture_assert_ntstatus_ok(tctx, status, "EnumDomainGroups");
7393 torture_assert(tctx, sam, "EnumDomainGroups failed to return sam");
7395 if (builtin_domain) {
7396 torture_assert(tctx, num_names == 0,
7397 "EnumDomainGroups shouldn't return any group in the builtin domain!");
7400 q2.in.domain_handle = handle;
7402 q2.in.start_idx = 0;
7403 q2.in.max_entries = 5;
7404 q2.in.buf_size = (uint32_t)-1;
7405 q2.out.total_size = &total_size;
7406 q2.out.returned_size = &returned_size;
7407 q2.out.info = &info;
7409 status = STATUS_MORE_ENTRIES;
7410 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
7411 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &q2),
7412 "QueryDisplayInfo failed");
7413 status = q2.out.result;
7414 if (!NT_STATUS_IS_OK(status) &&
7415 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
7418 for (i=0; i<q2.out.info->info5.count; i++) {
7420 const char *name = q2.out.info->info5.entries[i].account_name.string;
7422 for (j=0; j<num_names; j++) {
7423 if (names[j] == NULL)
7425 if (strequal(names[j], name)) {
7432 if ((!found) && (!builtin_domain)) {
7433 torture_result(tctx, TORTURE_FAIL, "QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
7438 q2.in.start_idx += q2.out.info->info5.count;
7441 if (!NT_STATUS_IS_OK(status)) {
7442 torture_result(tctx, TORTURE_FAIL, "QueryDisplayInfo level 5 failed - %s\n",
7447 if (builtin_domain) {
7448 torture_assert(tctx, q2.in.start_idx != 0,
7449 "QueryDisplayInfo should return all domain groups also on the builtin domain handle!");
7452 for (i=0; i<num_names; i++) {
7453 if (names[i] != NULL) {
7454 torture_result(tctx, TORTURE_FAIL, "EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
7463 static bool test_DeleteDomainGroup(struct dcerpc_binding_handle *b,
7464 struct torture_context *tctx,
7465 struct policy_handle *group_handle)
7467 struct samr_DeleteDomainGroup d;
7469 torture_comment(tctx, "Testing DeleteDomainGroup\n");
7471 d.in.group_handle = group_handle;
7472 d.out.group_handle = group_handle;
7474 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomainGroup_r(b, tctx, &d),
7475 "DeleteDomainGroup failed");
7476 torture_assert_ntstatus_ok(tctx, d.out.result, "DeleteDomainGroup");
7481 static bool test_TestPrivateFunctionsDomain(struct dcerpc_binding_handle *b,
7482 struct torture_context *tctx,
7483 struct policy_handle *domain_handle)
7485 struct samr_TestPrivateFunctionsDomain r;
7488 torture_comment(tctx, "Testing TestPrivateFunctionsDomain\n");
7490 r.in.domain_handle = domain_handle;
7492 torture_assert_ntstatus_ok(tctx, dcerpc_samr_TestPrivateFunctionsDomain_r(b, tctx, &r),
7493 "TestPrivateFunctionsDomain failed");
7494 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsDomain");
7499 static bool test_RidToSid(struct dcerpc_binding_handle *b,
7500 struct torture_context *tctx,
7501 struct dom_sid *domain_sid,
7502 struct policy_handle *domain_handle)
7504 struct samr_RidToSid r;
7506 struct dom_sid *calc_sid, *out_sid;
7507 int rids[] = { 0, 42, 512, 10200 };
7510 for (i=0;i<ARRAY_SIZE(rids);i++) {
7511 torture_comment(tctx, "Testing RidToSid\n");
7513 calc_sid = dom_sid_dup(tctx, domain_sid);
7514 r.in.domain_handle = domain_handle;
7516 r.out.sid = &out_sid;
7518 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RidToSid_r(b, tctx, &r),
7520 if (!NT_STATUS_IS_OK(r.out.result)) {
7521 torture_result(tctx, TORTURE_FAIL, "RidToSid for %d failed - %s\n", rids[i], nt_errstr(r.out.result));
7524 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
7526 if (!dom_sid_equal(calc_sid, out_sid)) {
7527 torture_result(tctx, TORTURE_FAIL, "RidToSid for %d failed - got %s, expected %s\n", rids[i],
7528 dom_sid_string(tctx, out_sid),
7529 dom_sid_string(tctx, calc_sid));
7538 static bool test_GetBootKeyInformation(struct dcerpc_binding_handle *b,
7539 struct torture_context *tctx,
7540 struct policy_handle *domain_handle)
7542 struct samr_GetBootKeyInformation r;
7544 uint32_t unknown = 0;
7547 torture_comment(tctx, "Testing GetBootKeyInformation\n");
7549 r.in.domain_handle = domain_handle;
7550 r.out.unknown = &unknown;
7552 status = dcerpc_samr_GetBootKeyInformation_r(b, tctx, &r);
7553 if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_OK(r.out.result)) {
7554 status = r.out.result;
7556 if (!NT_STATUS_IS_OK(status)) {
7557 /* w2k3 seems to fail this sometimes and pass it sometimes */
7558 torture_comment(tctx, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
7564 static bool test_AddGroupMember(struct dcerpc_binding_handle *b,
7565 struct torture_context *tctx,
7566 struct policy_handle *domain_handle,
7567 struct policy_handle *group_handle)
7570 struct samr_AddGroupMember r;
7571 struct samr_DeleteGroupMember d;
7572 struct samr_QueryGroupMember q;
7573 struct samr_RidAttrArray *rids = NULL;
7574 struct samr_SetMemberAttributesOfGroup s;
7576 bool found_member = false;
7579 status = test_LookupName(b, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
7580 torture_assert_ntstatus_ok(tctx, status, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME);
7582 r.in.group_handle = group_handle;
7584 r.in.flags = 0; /* ??? */
7586 torture_comment(tctx, "Testing AddGroupMember, QueryGroupMember and DeleteGroupMember\n");
7588 d.in.group_handle = group_handle;
7591 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteGroupMember_r(b, tctx, &d),
7592 "DeleteGroupMember failed");
7593 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_NOT_IN_GROUP, d.out.result, "DeleteGroupMember");
7595 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddGroupMember_r(b, tctx, &r),
7596 "AddGroupMember failed");
7597 torture_assert_ntstatus_ok(tctx, r.out.result, "AddGroupMember");
7599 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddGroupMember_r(b, tctx, &r),
7600 "AddGroupMember failed");
7601 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_IN_GROUP, r.out.result, "AddGroupMember");
7603 if (torture_setting_bool(tctx, "samba4", false) ||
7604 torture_setting_bool(tctx, "samba3", false)) {
7605 torture_comment(tctx, "skipping SetMemberAttributesOfGroup test against Samba\n");
7607 /* this one is quite strange. I am using random inputs in the
7608 hope of triggering an error that might give us a clue */
7610 s.in.group_handle = group_handle;
7611 s.in.unknown1 = random();
7612 s.in.unknown2 = random();
7614 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetMemberAttributesOfGroup_r(b, tctx, &s),
7615 "SetMemberAttributesOfGroup failed");
7616 torture_assert_ntstatus_ok(tctx, s.out.result, "SetMemberAttributesOfGroup");
7619 q.in.group_handle = group_handle;
7622 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupMember_r(b, tctx, &q),
7623 "QueryGroupMember failed");
7624 torture_assert_ntstatus_ok(tctx, q.out.result, "QueryGroupMember");
7625 torture_assert(tctx, rids, "QueryGroupMember did not fill in rids structure");
7627 for (i=0; i < rids->count; i++) {
7628 if (rids->rids[i] == rid) {
7629 found_member = true;
7633 torture_assert(tctx, found_member, "QueryGroupMember did not list newly added member");
7635 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteGroupMember_r(b, tctx, &d),
7636 "DeleteGroupMember failed");
7637 torture_assert_ntstatus_ok(tctx, d.out.result, "DeleteGroupMember");
7640 found_member = false;
7642 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupMember_r(b, tctx, &q),
7643 "QueryGroupMember failed");
7644 torture_assert_ntstatus_ok(tctx, q.out.result, "QueryGroupMember");
7645 torture_assert(tctx, rids, "QueryGroupMember did not fill in rids structure");
7647 for (i=0; i < rids->count; i++) {
7648 if (rids->rids[i] == rid) {
7649 found_member = true;
7653 torture_assert(tctx, !found_member, "QueryGroupMember does still list removed member");
7655 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddGroupMember_r(b, tctx, &r),
7656 "AddGroupMember failed");
7657 torture_assert_ntstatus_ok(tctx, r.out.result, "AddGroupMember");
7663 static bool test_CreateDomainGroup(struct dcerpc_binding_handle *b,
7664 struct torture_context *tctx,
7665 struct policy_handle *domain_handle,
7666 const char *group_name,
7667 struct policy_handle *group_handle,
7668 struct dom_sid *domain_sid,
7671 struct samr_CreateDomainGroup r;
7673 struct lsa_String name;
7676 init_lsa_String(&name, group_name);
7678 r.in.domain_handle = domain_handle;
7680 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7681 r.out.group_handle = group_handle;
7684 torture_comment(tctx, "Testing CreateDomainGroup(%s)\n", r.in.name->string);
7686 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomainGroup_r(b, tctx, &r),
7687 "CreateDomainGroup failed");
7689 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
7690 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED)) {
7691 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.name->string);
7694 torture_result(tctx, TORTURE_FAIL, "Server should have refused create of '%s', got %s instead\n", r.in.name->string,
7695 nt_errstr(r.out.result));
7700 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_GROUP_EXISTS)) {
7701 if (!test_DeleteGroup_byname(b, tctx, domain_handle, r.in.name->string)) {
7702 torture_result(tctx, TORTURE_FAIL, "CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
7703 nt_errstr(r.out.result));
7706 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomainGroup_r(b, tctx, &r),
7707 "CreateDomainGroup failed");
7709 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_USER_EXISTS)) {
7710 if (!test_DeleteUser_byname(b, tctx, domain_handle, r.in.name->string)) {
7712 torture_result(tctx, TORTURE_FAIL, "CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
7713 nt_errstr(r.out.result));
7716 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomainGroup_r(b, tctx, &r),
7717 "CreateDomainGroup failed");
7719 torture_assert_ntstatus_ok(tctx, r.out.result, "CreateDomainGroup");
7725 if (!test_AddGroupMember(b, tctx, domain_handle, group_handle)) {
7726 torture_result(tctx, TORTURE_FAIL, "CreateDomainGroup failed - %s\n", nt_errstr(r.out.result));
7730 if (!test_SetGroupInfo(b, tctx, group_handle)) {
7739 its not totally clear what this does. It seems to accept any sid you like.
7741 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_binding_handle *b,
7742 struct torture_context *tctx,
7743 struct policy_handle *domain_handle)
7745 struct samr_RemoveMemberFromForeignDomain r;
7747 r.in.domain_handle = domain_handle;
7748 r.in.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-12-34-56-78");
7750 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RemoveMemberFromForeignDomain_r(b, tctx, &r),
7751 "RemoveMemberFromForeignDomain failed");
7752 torture_assert_ntstatus_ok(tctx, r.out.result, "RemoveMemberFromForeignDomain");
7757 static bool test_EnumDomainUsers(struct dcerpc_binding_handle *b,
7758 struct torture_context *tctx,
7759 struct policy_handle *domain_handle,
7760 uint32_t *total_num_entries_p)
7763 struct samr_EnumDomainUsers r;
7764 uint32_t resume_handle = 0;
7765 uint32_t num_entries = 0;
7766 uint32_t total_num_entries = 0;
7767 struct samr_SamArray *sam;
7769 r.in.domain_handle = domain_handle;
7770 r.in.acct_flags = 0;
7771 r.in.max_size = (uint32_t)-1;
7772 r.in.resume_handle = &resume_handle;
7775 r.out.num_entries = &num_entries;
7776 r.out.resume_handle = &resume_handle;
7778 torture_comment(tctx, "Testing EnumDomainUsers\n");
7781 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainUsers_r(b, tctx, &r),
7782 "EnumDomainUsers failed");
7783 if (NT_STATUS_IS_ERR(r.out.result)) {
7784 torture_assert_ntstatus_ok(tctx, r.out.result,
7785 "failed to enumerate users");
7787 status = r.out.result;
7789 total_num_entries += num_entries;
7790 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7792 if (total_num_entries_p) {
7793 *total_num_entries_p = total_num_entries;
7799 static bool test_EnumDomainGroups(struct dcerpc_binding_handle *b,
7800 struct torture_context *tctx,
7801 struct policy_handle *domain_handle,
7802 uint32_t *total_num_entries_p)
7805 struct samr_EnumDomainGroups r;
7806 uint32_t resume_handle = 0;
7807 uint32_t num_entries = 0;
7808 uint32_t total_num_entries = 0;
7809 struct samr_SamArray *sam;
7811 r.in.domain_handle = domain_handle;
7812 r.in.max_size = (uint32_t)-1;
7813 r.in.resume_handle = &resume_handle;
7816 r.out.num_entries = &num_entries;
7817 r.out.resume_handle = &resume_handle;
7819 torture_comment(tctx, "Testing EnumDomainGroups\n");
7822 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainGroups_r(b, tctx, &r),
7823 "EnumDomainGroups failed");
7824 if (NT_STATUS_IS_ERR(r.out.result)) {
7825 torture_assert_ntstatus_ok(tctx, r.out.result,
7826 "failed to enumerate groups");
7828 status = r.out.result;
7830 total_num_entries += num_entries;
7831 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7833 if (total_num_entries_p) {
7834 *total_num_entries_p = total_num_entries;
7840 static bool test_EnumDomainAliases(struct dcerpc_binding_handle *b,
7841 struct torture_context *tctx,
7842 struct policy_handle *domain_handle,
7843 uint32_t *total_num_entries_p)
7846 struct samr_EnumDomainAliases r;
7847 uint32_t resume_handle = 0;
7848 uint32_t num_entries = 0;
7849 uint32_t total_num_entries = 0;
7850 struct samr_SamArray *sam;
7852 r.in.domain_handle = domain_handle;
7853 r.in.max_size = (uint32_t)-1;
7854 r.in.resume_handle = &resume_handle;
7857 r.out.num_entries = &num_entries;
7858 r.out.resume_handle = &resume_handle;
7860 torture_comment(tctx, "Testing EnumDomainAliases\n");
7863 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainAliases_r(b, tctx, &r),
7864 "EnumDomainAliases failed");
7865 if (NT_STATUS_IS_ERR(r.out.result)) {
7866 torture_assert_ntstatus_ok(tctx, r.out.result,
7867 "failed to enumerate aliases");
7869 status = r.out.result;
7871 total_num_entries += num_entries;
7872 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7874 if (total_num_entries_p) {
7875 *total_num_entries_p = total_num_entries;
7881 static bool test_QueryDisplayInfo_level(struct dcerpc_binding_handle *b,
7882 struct torture_context *tctx,
7883 struct policy_handle *handle,
7885 uint32_t *total_num_entries_p)
7888 struct samr_QueryDisplayInfo r;
7889 uint32_t total_num_entries = 0;
7891 r.in.domain_handle = handle;
7894 r.in.max_entries = (uint32_t)-1;
7895 r.in.buf_size = (uint32_t)-1;
7897 torture_comment(tctx, "Testing QueryDisplayInfo\n");
7900 uint32_t total_size;
7901 uint32_t returned_size;
7902 union samr_DispInfo info;
7904 r.out.total_size = &total_size;
7905 r.out.returned_size = &returned_size;
7908 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &r),
7909 "failed to query displayinfo");
7910 if (NT_STATUS_IS_ERR(r.out.result)) {
7911 torture_assert_ntstatus_ok(tctx, r.out.result,
7912 "failed to query displayinfo");
7914 status = r.out.result;
7916 if (*r.out.returned_size == 0) {
7920 switch (r.in.level) {
7922 total_num_entries += info.info1.count;
7923 r.in.start_idx += info.info1.entries[info.info1.count - 1].idx + 1;
7926 total_num_entries += info.info2.count;
7927 r.in.start_idx += info.info2.entries[info.info2.count - 1].idx + 1;
7930 total_num_entries += info.info3.count;
7931 r.in.start_idx += info.info3.entries[info.info3.count - 1].idx + 1;
7934 total_num_entries += info.info4.count;
7935 r.in.start_idx += info.info4.entries[info.info4.count - 1].idx + 1;
7938 total_num_entries += info.info5.count;
7939 r.in.start_idx += info.info5.entries[info.info5.count - 1].idx + 1;
7945 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7947 if (total_num_entries_p) {
7948 *total_num_entries_p = total_num_entries;
7954 static bool test_ManyObjects(struct dcerpc_pipe *p,
7955 struct torture_context *tctx,
7956 struct policy_handle *domain_handle,
7957 struct dom_sid *domain_sid,
7958 struct torture_samr_context *ctx)
7960 uint32_t num_total = ctx->num_objects_large_dc;
7961 uint32_t num_enum = 0;
7962 uint32_t num_disp = 0;
7963 uint32_t num_created = 0;
7964 uint32_t num_anounced = 0;
7966 struct dcerpc_binding_handle *b = p->binding_handle;
7968 struct policy_handle *handles = talloc_zero_array(tctx, struct policy_handle, num_total);
7973 struct samr_QueryDomainInfo2 r;
7974 union samr_DomainInfo *info;
7975 r.in.domain_handle = domain_handle;
7979 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo2_r(b, tctx, &r),
7980 "QueryDomainInfo2 failed");
7981 torture_assert_ntstatus_ok(tctx, r.out.result,
7982 "failed to query domain info");
7984 switch (ctx->choice) {
7985 case TORTURE_SAMR_MANY_ACCOUNTS:
7986 num_anounced = info->general.num_users;
7988 case TORTURE_SAMR_MANY_GROUPS:
7989 num_anounced = info->general.num_groups;
7991 case TORTURE_SAMR_MANY_ALIASES:
7992 num_anounced = info->general.num_aliases;
8001 for (i=0; i < num_total; i++) {
8003 const char *name = NULL;
8005 switch (ctx->choice) {
8006 case TORTURE_SAMR_MANY_ACCOUNTS:
8007 name = talloc_asprintf(tctx, "%s%04d", TEST_ACCOUNT_NAME, i);
8008 torture_assert(tctx,
8009 test_CreateUser(p, tctx, domain_handle, name, &handles[i], domain_sid, 0, NULL, false),
8010 "failed to create user");
8012 case TORTURE_SAMR_MANY_GROUPS:
8013 name = talloc_asprintf(tctx, "%s%04d", TEST_GROUPNAME, i);
8014 torture_assert(tctx,
8015 test_CreateDomainGroup(b, tctx, domain_handle, name, &handles[i], domain_sid, false),
8016 "failed to create group");
8018 case TORTURE_SAMR_MANY_ALIASES:
8019 name = talloc_asprintf(tctx, "%s%04d", TEST_ALIASNAME, i);
8020 torture_assert(tctx,
8021 test_CreateAlias(b, tctx, domain_handle, name, &handles[i], domain_sid, false),
8022 "failed to create alias");
8027 if (!ndr_policy_handle_empty(&handles[i])) {
8034 switch (ctx->choice) {
8035 case TORTURE_SAMR_MANY_ACCOUNTS:
8036 torture_assert(tctx,
8037 test_EnumDomainUsers(b, tctx, domain_handle, &num_enum),
8038 "failed to enum users");
8040 case TORTURE_SAMR_MANY_GROUPS:
8041 torture_assert(tctx,
8042 test_EnumDomainGroups(b, tctx, domain_handle, &num_enum),
8043 "failed to enum groups");
8045 case TORTURE_SAMR_MANY_ALIASES:
8046 torture_assert(tctx,
8047 test_EnumDomainAliases(b, tctx, domain_handle, &num_enum),
8048 "failed to enum aliases");
8056 switch (ctx->choice) {
8057 case TORTURE_SAMR_MANY_ACCOUNTS:
8058 torture_assert(tctx,
8059 test_QueryDisplayInfo_level(b, tctx, domain_handle, 1, &num_disp),
8060 "failed to query display info");
8062 case TORTURE_SAMR_MANY_GROUPS:
8063 torture_assert(tctx,
8064 test_QueryDisplayInfo_level(b, tctx, domain_handle, 3, &num_disp),
8065 "failed to query display info");
8067 case TORTURE_SAMR_MANY_ALIASES:
8068 /* no aliases in dispinfo */
8074 /* close or delete */
8076 for (i=0; i < num_total; i++) {
8078 if (ndr_policy_handle_empty(&handles[i])) {
8082 if (torture_setting_bool(tctx, "samba3", false)) {
8083 torture_assert(tctx,
8084 test_samr_handle_Close(b, tctx, &handles[i]),
8085 "failed to close handle");
8087 switch (ctx->choice) {
8088 case TORTURE_SAMR_MANY_ACCOUNTS:
8089 torture_assert(tctx,
8090 test_DeleteUser(b, tctx, &handles[i]),
8091 "failed to delete user");
8093 case TORTURE_SAMR_MANY_GROUPS:
8094 torture_assert(tctx,
8095 test_DeleteDomainGroup(b, tctx, &handles[i]),
8096 "failed to delete group");
8098 case TORTURE_SAMR_MANY_ALIASES:
8099 torture_assert(tctx,
8100 test_DeleteAlias(b, tctx, &handles[i]),
8101 "failed to delete alias");
8109 talloc_free(handles);
8111 if (ctx->choice == TORTURE_SAMR_MANY_ACCOUNTS && num_enum != num_anounced + num_created) {
8112 torture_comment(tctx,
8113 "unexpected number of results (%u) returned in enum call, expected %u\n",
8114 num_enum, num_anounced + num_created);
8116 torture_comment(tctx,
8117 "unexpected number of results (%u) returned in dispinfo, call, expected %u\n",
8118 num_disp, num_anounced + num_created);
8124 static bool test_Connect(struct dcerpc_binding_handle *b,
8125 struct torture_context *tctx,
8126 struct policy_handle *handle);
8128 static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
8129 struct torture_samr_context *ctx, struct dom_sid *sid)
8131 struct samr_OpenDomain r;
8132 struct policy_handle domain_handle;
8133 struct policy_handle alias_handle;
8134 struct policy_handle user_handle;
8135 struct policy_handle group_handle;
8137 struct dcerpc_binding_handle *b = p->binding_handle;
8139 ZERO_STRUCT(alias_handle);
8140 ZERO_STRUCT(user_handle);
8141 ZERO_STRUCT(group_handle);
8142 ZERO_STRUCT(domain_handle);
8144 torture_comment(tctx, "Testing OpenDomain of %s\n", dom_sid_string(tctx, sid));
8146 r.in.connect_handle = &ctx->handle;
8147 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
8149 r.out.domain_handle = &domain_handle;
8151 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenDomain_r(b, tctx, &r),
8152 "OpenDomain failed");
8153 torture_assert_ntstatus_ok(tctx, r.out.result, "OpenDomain failed");
8155 /* run the domain tests with the main handle closed - this tests
8156 the servers reference counting */
8157 torture_assert(tctx, test_samr_handle_Close(b, tctx, &ctx->handle), "Failed to close SAMR handle");
8159 switch (ctx->choice) {
8160 case TORTURE_SAMR_PASSWORDS:
8161 case TORTURE_SAMR_USER_PRIVILEGES:
8162 if (!torture_setting_bool(tctx, "samba3", false)) {
8163 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, NULL);
8165 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
8167 torture_result(tctx, TORTURE_FAIL, "Testing PASSWORDS or PRIVILEGES on domain %s failed!\n", dom_sid_string(tctx, sid));
8170 case TORTURE_SAMR_USER_ATTRIBUTES:
8171 if (!torture_setting_bool(tctx, "samba3", false)) {
8172 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, NULL);
8174 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
8175 /* This test needs 'complex' users to validate */
8176 ret &= test_QueryDisplayInfo(b, tctx, &domain_handle);
8178 torture_result(tctx, TORTURE_FAIL, "Testing ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
8181 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
8182 case TORTURE_SAMR_PASSWORDS_BADPWDCOUNT:
8183 case TORTURE_SAMR_PASSWORDS_LOCKOUT:
8184 if (!torture_setting_bool(tctx, "samba3", false)) {
8185 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, ctx->machine_credentials);
8187 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, ctx->machine_credentials, true);
8189 torture_result(tctx, TORTURE_FAIL, "Testing PASSWORDS PWDLASTSET or BADPWDCOUNT on domain %s failed!\n", dom_sid_string(tctx, sid));
8192 case TORTURE_SAMR_MANY_ACCOUNTS:
8193 case TORTURE_SAMR_MANY_GROUPS:
8194 case TORTURE_SAMR_MANY_ALIASES:
8195 ret &= test_ManyObjects(p, tctx, &domain_handle, sid, ctx);
8197 torture_result(tctx, TORTURE_FAIL, "Testing MANY-{ACCOUNTS,GROUPS,ALIASES} on domain %s failed!\n", dom_sid_string(tctx, sid));
8200 case TORTURE_SAMR_OTHER:
8201 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
8203 torture_result(tctx, TORTURE_FAIL, "Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid));
8205 if (!torture_setting_bool(tctx, "samba3", false)) {
8206 ret &= test_QuerySecurity(b, tctx, &domain_handle);
8208 ret &= test_RemoveMemberFromForeignDomain(b, tctx, &domain_handle);
8209 ret &= test_CreateAlias(b, tctx, &domain_handle, TEST_ALIASNAME, &alias_handle, sid, true);
8210 ret &= test_CreateDomainGroup(b, tctx, &domain_handle, TEST_GROUPNAME, &group_handle, sid, true);
8211 ret &= test_GetAliasMembership(b, tctx, &domain_handle);
8212 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
8213 ret &= test_QueryDomainInfo2(b, tctx, &domain_handle);
8214 ret &= test_EnumDomainUsers_all(b, tctx, &domain_handle);
8215 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
8216 ret &= test_EnumDomainGroups_all(b, tctx, &domain_handle);
8217 ret &= test_EnumDomainAliases_all(b, tctx, &domain_handle);
8218 ret &= test_QueryDisplayInfo2(b, tctx, &domain_handle);
8219 ret &= test_QueryDisplayInfo3(b, tctx, &domain_handle);
8220 ret &= test_QueryDisplayInfo_continue(b, tctx, &domain_handle);
8222 if (torture_setting_bool(tctx, "samba4", false)) {
8223 torture_comment(tctx, "skipping GetDisplayEnumerationIndex test against Samba4\n");
8225 ret &= test_GetDisplayEnumerationIndex(b, tctx, &domain_handle);
8226 ret &= test_GetDisplayEnumerationIndex2(b, tctx, &domain_handle);
8228 ret &= test_GroupList(b, tctx, sid, &domain_handle);
8229 ret &= test_TestPrivateFunctionsDomain(b, tctx, &domain_handle);
8230 ret &= test_RidToSid(b, tctx, sid, &domain_handle);
8231 ret &= test_GetBootKeyInformation(b, tctx, &domain_handle);
8233 torture_comment(tctx, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx, sid));
8238 if (!ndr_policy_handle_empty(&user_handle) &&
8239 !test_DeleteUser(b, tctx, &user_handle)) {
8243 if (!ndr_policy_handle_empty(&alias_handle) &&
8244 !test_DeleteAlias(b, tctx, &alias_handle)) {
8248 if (!ndr_policy_handle_empty(&group_handle) &&
8249 !test_DeleteDomainGroup(b, tctx, &group_handle)) {
8253 torture_assert(tctx, test_samr_handle_Close(b, tctx, &domain_handle), "Failed to close SAMR domain handle");
8255 torture_assert(tctx, test_Connect(b, tctx, &ctx->handle), "Faile to re-connect SAMR handle");
8256 /* reconnect the main handle */
8259 torture_result(tctx, TORTURE_FAIL, "Testing domain %s failed!\n", dom_sid_string(tctx, sid));
8265 static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
8266 struct torture_samr_context *ctx, const char *domain)
8268 struct samr_LookupDomain r;
8269 struct dom_sid2 *sid = NULL;
8270 struct lsa_String n1;
8271 struct lsa_String n2;
8273 struct dcerpc_binding_handle *b = p->binding_handle;
8275 torture_comment(tctx, "Testing LookupDomain(%s)\n", domain);
8277 /* check for correct error codes */
8278 r.in.connect_handle = &ctx->handle;
8279 r.in.domain_name = &n2;
8283 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupDomain_r(b, tctx, &r),
8284 "LookupDomain failed");
8285 torture_assert_ntstatus_equal(tctx, NT_STATUS_INVALID_PARAMETER, r.out.result, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
8287 init_lsa_String(&n2, "xxNODOMAINxx");
8289 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupDomain_r(b, tctx, &r),
8290 "LookupDomain failed");
8291 torture_assert_ntstatus_equal(tctx, NT_STATUS_NO_SUCH_DOMAIN, r.out.result, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
8293 r.in.connect_handle = &ctx->handle;
8295 init_lsa_String(&n1, domain);
8296 r.in.domain_name = &n1;
8298 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupDomain_r(b, tctx, &r),
8299 "LookupDomain failed");
8300 torture_assert_ntstatus_ok(tctx, r.out.result, "LookupDomain");
8302 if (!test_GetDomPwInfo(p, tctx, &n1)) {
8306 if (!test_OpenDomain(p, tctx, ctx, *r.out.sid)) {
8314 static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
8315 struct torture_samr_context *ctx)
8317 struct samr_EnumDomains r;
8318 uint32_t resume_handle = 0;
8319 uint32_t num_entries = 0;
8320 struct samr_SamArray *sam = NULL;
8323 struct dcerpc_binding_handle *b = p->binding_handle;
8325 r.in.connect_handle = &ctx->handle;
8326 r.in.resume_handle = &resume_handle;
8327 r.in.buf_size = (uint32_t)-1;
8328 r.out.resume_handle = &resume_handle;
8329 r.out.num_entries = &num_entries;
8332 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomains_r(b, tctx, &r),
8333 "EnumDomains failed");
8334 torture_assert_ntstatus_ok(tctx, r.out.result, "EnumDomains failed");
8340 for (i=0;i<sam->count;i++) {
8341 if (!test_LookupDomain(p, tctx, ctx,
8342 sam->entries[i].name.string)) {
8347 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomains_r(b, tctx, &r),
8348 "EnumDomains failed");
8349 torture_assert_ntstatus_ok(tctx, r.out.result, "EnumDomains failed");
8355 static bool test_Connect(struct dcerpc_binding_handle *b,
8356 struct torture_context *tctx,
8357 struct policy_handle *handle)
8359 struct samr_Connect r;
8360 struct samr_Connect2 r2;
8361 struct samr_Connect3 r3;
8362 struct samr_Connect4 r4;
8363 struct samr_Connect5 r5;
8364 union samr_ConnectInfo info;
8365 struct policy_handle h;
8366 uint32_t level_out = 0;
8367 bool ret = true, got_handle = false;
8369 torture_comment(tctx, "Testing samr_Connect\n");
8371 r.in.system_name = NULL;
8372 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
8373 r.out.connect_handle = &h;
8375 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect_r(b, tctx, &r),
8377 if (!NT_STATUS_IS_OK(r.out.result)) {
8378 torture_comment(tctx, "Connect failed - %s\n", nt_errstr(r.out.result));
8385 torture_comment(tctx, "Testing samr_Connect2\n");
8387 r2.in.system_name = NULL;
8388 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
8389 r2.out.connect_handle = &h;
8391 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect2_r(b, tctx, &r2),
8393 if (!NT_STATUS_IS_OK(r2.out.result)) {
8394 torture_comment(tctx, "Connect2 failed - %s\n", nt_errstr(r2.out.result));
8398 test_samr_handle_Close(b, tctx, handle);
8404 torture_comment(tctx, "Testing samr_Connect3\n");
8406 r3.in.system_name = NULL;
8408 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
8409 r3.out.connect_handle = &h;
8411 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect3_r(b, tctx, &r3),
8413 if (!NT_STATUS_IS_OK(r3.out.result)) {
8414 torture_result(tctx, TORTURE_FAIL, "Connect3 failed - %s\n", nt_errstr(r3.out.result));
8418 test_samr_handle_Close(b, tctx, handle);
8424 torture_comment(tctx, "Testing samr_Connect4\n");
8426 r4.in.system_name = "";
8427 r4.in.client_version = 0;
8428 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
8429 r4.out.connect_handle = &h;
8431 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect4_r(b, tctx, &r4),
8433 if (!NT_STATUS_IS_OK(r4.out.result)) {
8434 torture_result(tctx, TORTURE_FAIL, "Connect4 failed - %s\n", nt_errstr(r4.out.result));
8438 test_samr_handle_Close(b, tctx, handle);
8444 torture_comment(tctx, "Testing samr_Connect5\n");
8446 info.info1.client_version = 0;
8447 info.info1.unknown2 = 0;
8449 r5.in.system_name = "";
8450 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
8452 r5.out.level_out = &level_out;
8453 r5.in.info_in = &info;
8454 r5.out.info_out = &info;
8455 r5.out.connect_handle = &h;
8457 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect5_r(b, tctx, &r5),
8459 if (!NT_STATUS_IS_OK(r5.out.result)) {
8460 torture_result(tctx, TORTURE_FAIL, "Connect5 failed - %s\n", nt_errstr(r5.out.result));
8464 test_samr_handle_Close(b, tctx, handle);
8474 static bool test_samr_ValidatePassword(struct torture_context *tctx,
8475 struct dcerpc_pipe *p)
8477 struct samr_ValidatePassword r;
8478 union samr_ValidatePasswordReq req;
8479 union samr_ValidatePasswordRep *repp = NULL;
8481 const char *passwords[] = { "penguin", "p@ssw0rd", "p@ssw0rd123$", NULL };
8483 struct dcerpc_binding_handle *b = p->binding_handle;
8485 torture_comment(tctx, "Testing samr_ValidatePassword\n");
8487 if (p->conn->transport.transport != NCACN_IP_TCP) {
8488 torture_comment(tctx, "samr_ValidatePassword only should succeed over NCACN_IP_TCP!\n");
8492 r.in.level = NetValidatePasswordReset;
8497 req.req3.account.string = "non-existent-account-aklsdji";
8499 for (i=0; passwords[i]; i++) {
8500 req.req3.password.string = passwords[i];
8502 status = dcerpc_samr_ValidatePassword_r(b, tctx, &r);
8503 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE)) {
8504 torture_skip(tctx, "ValidatePassword not supported by server\n");
8506 torture_assert_ntstatus_ok(tctx, status,
8507 "samr_ValidatePassword failed");
8508 torture_assert_ntstatus_ok(tctx, r.out.result,
8509 "samr_ValidatePassword failed");
8510 torture_comment(tctx, "Server %s password '%s' with code %i\n",
8511 repp->ctr3.status==SAMR_VALIDATION_STATUS_SUCCESS?"allowed":"refused",
8512 req.req3.password.string, repp->ctr3.status);
8518 bool torture_rpc_samr(struct torture_context *torture)
8521 struct dcerpc_pipe *p;
8523 struct torture_samr_context *ctx;
8524 struct dcerpc_binding_handle *b;
8526 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8527 if (!NT_STATUS_IS_OK(status)) {
8530 b = p->binding_handle;
8532 ctx = talloc_zero(torture, struct torture_samr_context);
8534 ctx->choice = TORTURE_SAMR_OTHER;
8536 ret &= test_Connect(b, torture, &ctx->handle);
8538 if (!torture_setting_bool(torture, "samba3", false)) {
8539 ret &= test_QuerySecurity(b, torture, &ctx->handle);
8542 ret &= test_EnumDomains(p, torture, ctx);
8544 ret &= test_SetDsrmPassword(b, torture, &ctx->handle);
8546 ret &= test_Shutdown(b, torture, &ctx->handle);
8548 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8554 bool torture_rpc_samr_users(struct torture_context *torture)
8557 struct dcerpc_pipe *p;
8559 struct torture_samr_context *ctx;
8560 struct dcerpc_binding_handle *b;
8562 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8563 if (!NT_STATUS_IS_OK(status)) {
8566 b = p->binding_handle;
8568 ctx = talloc_zero(torture, struct torture_samr_context);
8570 ctx->choice = TORTURE_SAMR_USER_ATTRIBUTES;
8572 ret &= test_Connect(b, torture, &ctx->handle);
8574 if (!torture_setting_bool(torture, "samba3", false)) {
8575 ret &= test_QuerySecurity(b, torture, &ctx->handle);
8578 ret &= test_EnumDomains(p, torture, ctx);
8580 ret &= test_SetDsrmPassword(b, torture, &ctx->handle);
8582 ret &= test_Shutdown(b, torture, &ctx->handle);
8584 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8590 bool torture_rpc_samr_passwords(struct torture_context *torture)
8593 struct dcerpc_pipe *p;
8595 struct torture_samr_context *ctx;
8596 struct dcerpc_binding_handle *b;
8598 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8599 if (!NT_STATUS_IS_OK(status)) {
8602 b = p->binding_handle;
8604 ctx = talloc_zero(torture, struct torture_samr_context);
8606 ctx->choice = TORTURE_SAMR_PASSWORDS;
8608 ret &= test_Connect(b, torture, &ctx->handle);
8610 ret &= test_EnumDomains(p, torture, ctx);
8612 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8617 static bool torture_rpc_samr_pwdlastset(struct torture_context *torture,
8618 struct dcerpc_pipe *p2,
8619 struct cli_credentials *machine_credentials)
8622 struct dcerpc_pipe *p;
8624 struct torture_samr_context *ctx;
8625 struct dcerpc_binding_handle *b;
8627 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8628 if (!NT_STATUS_IS_OK(status)) {
8631 b = p->binding_handle;
8633 ctx = talloc_zero(torture, struct torture_samr_context);
8635 ctx->choice = TORTURE_SAMR_PASSWORDS_PWDLASTSET;
8636 ctx->machine_credentials = machine_credentials;
8638 ret &= test_Connect(b, torture, &ctx->handle);
8640 ret &= test_EnumDomains(p, torture, ctx);
8642 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8647 struct torture_suite *torture_rpc_samr_passwords_pwdlastset(TALLOC_CTX *mem_ctx)
8649 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.passwords.pwdlastset");
8650 struct torture_rpc_tcase *tcase;
8652 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8654 TEST_ACCOUNT_NAME_PWD);
8656 torture_rpc_tcase_add_test_creds(tcase, "pwdLastSet",
8657 torture_rpc_samr_pwdlastset);
8662 static bool torture_rpc_samr_users_privileges_delete_user(struct torture_context *torture,
8663 struct dcerpc_pipe *p2,
8664 struct cli_credentials *machine_credentials)
8667 struct dcerpc_pipe *p;
8669 struct torture_samr_context *ctx;
8670 struct dcerpc_binding_handle *b;
8672 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8673 if (!NT_STATUS_IS_OK(status)) {
8676 b = p->binding_handle;
8678 ctx = talloc_zero(torture, struct torture_samr_context);
8680 ctx->choice = TORTURE_SAMR_USER_PRIVILEGES;
8681 ctx->machine_credentials = machine_credentials;
8683 ret &= test_Connect(b, torture, &ctx->handle);
8685 ret &= test_EnumDomains(p, torture, ctx);
8687 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8692 struct torture_suite *torture_rpc_samr_user_privileges(TALLOC_CTX *mem_ctx)
8694 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.users.privileges");
8695 struct torture_rpc_tcase *tcase;
8697 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8699 TEST_ACCOUNT_NAME_PWD);
8701 torture_rpc_tcase_add_test_creds(tcase, "delete_privileged_user",
8702 torture_rpc_samr_users_privileges_delete_user);
8707 static bool torture_rpc_samr_many_accounts(struct torture_context *torture,
8708 struct dcerpc_pipe *p2,
8712 struct dcerpc_pipe *p;
8714 struct torture_samr_context *ctx =
8715 talloc_get_type_abort(data, struct torture_samr_context);
8716 struct dcerpc_binding_handle *b;
8718 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8719 if (!NT_STATUS_IS_OK(status)) {
8722 b = p->binding_handle;
8724 ctx->choice = TORTURE_SAMR_MANY_ACCOUNTS;
8725 ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
8726 ctx->num_objects_large_dc);
8728 ret &= test_Connect(b, torture, &ctx->handle);
8730 ret &= test_EnumDomains(p, torture, ctx);
8732 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8737 static bool torture_rpc_samr_many_groups(struct torture_context *torture,
8738 struct dcerpc_pipe *p2,
8742 struct dcerpc_pipe *p;
8744 struct torture_samr_context *ctx =
8745 talloc_get_type_abort(data, struct torture_samr_context);
8746 struct dcerpc_binding_handle *b;
8748 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8749 if (!NT_STATUS_IS_OK(status)) {
8752 b = p->binding_handle;
8754 ctx->choice = TORTURE_SAMR_MANY_GROUPS;
8755 ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
8756 ctx->num_objects_large_dc);
8758 ret &= test_Connect(b, torture, &ctx->handle);
8760 ret &= test_EnumDomains(p, torture, ctx);
8762 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8767 static bool torture_rpc_samr_many_aliases(struct torture_context *torture,
8768 struct dcerpc_pipe *p2,
8772 struct dcerpc_pipe *p;
8774 struct torture_samr_context *ctx =
8775 talloc_get_type_abort(data, struct torture_samr_context);
8776 struct dcerpc_binding_handle *b;
8778 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8779 if (!NT_STATUS_IS_OK(status)) {
8782 b = p->binding_handle;
8784 ctx->choice = TORTURE_SAMR_MANY_ALIASES;
8785 ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
8786 ctx->num_objects_large_dc);
8788 ret &= test_Connect(b, torture, &ctx->handle);
8790 ret &= test_EnumDomains(p, torture, ctx);
8792 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8797 struct torture_suite *torture_rpc_samr_large_dc(TALLOC_CTX *mem_ctx)
8799 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.large-dc");
8800 struct torture_rpc_tcase *tcase;
8801 struct torture_samr_context *ctx;
8803 tcase = torture_suite_add_rpc_iface_tcase(suite, "samr", &ndr_table_samr);
8805 ctx = talloc_zero(suite, struct torture_samr_context);
8806 ctx->num_objects_large_dc = 150;
8808 torture_rpc_tcase_add_test_ex(tcase, "many_aliases",
8809 torture_rpc_samr_many_aliases, ctx);
8810 torture_rpc_tcase_add_test_ex(tcase, "many_groups",
8811 torture_rpc_samr_many_groups, ctx);
8812 torture_rpc_tcase_add_test_ex(tcase, "many_accounts",
8813 torture_rpc_samr_many_accounts, ctx);
8818 static bool torture_rpc_samr_badpwdcount(struct torture_context *torture,
8819 struct dcerpc_pipe *p2,
8820 struct cli_credentials *machine_credentials)
8823 struct dcerpc_pipe *p;
8825 struct torture_samr_context *ctx;
8826 struct dcerpc_binding_handle *b;
8828 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8829 if (!NT_STATUS_IS_OK(status)) {
8832 b = p->binding_handle;
8834 ctx = talloc_zero(torture, struct torture_samr_context);
8836 ctx->choice = TORTURE_SAMR_PASSWORDS_BADPWDCOUNT;
8837 ctx->machine_credentials = machine_credentials;
8839 ret &= test_Connect(b, torture, &ctx->handle);
8841 ret &= test_EnumDomains(p, torture, ctx);
8843 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8848 struct torture_suite *torture_rpc_samr_passwords_badpwdcount(TALLOC_CTX *mem_ctx)
8850 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.passwords.badpwdcount");
8851 struct torture_rpc_tcase *tcase;
8853 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8855 TEST_ACCOUNT_NAME_PWD);
8857 torture_rpc_tcase_add_test_creds(tcase, "badPwdCount",
8858 torture_rpc_samr_badpwdcount);
8863 static bool torture_rpc_samr_lockout(struct torture_context *torture,
8864 struct dcerpc_pipe *p2,
8865 struct cli_credentials *machine_credentials)
8868 struct dcerpc_pipe *p;
8870 struct torture_samr_context *ctx;
8871 struct dcerpc_binding_handle *b;
8873 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8874 if (!NT_STATUS_IS_OK(status)) {
8877 b = p->binding_handle;
8879 ctx = talloc_zero(torture, struct torture_samr_context);
8881 ctx->choice = TORTURE_SAMR_PASSWORDS_LOCKOUT;
8882 ctx->machine_credentials = machine_credentials;
8884 ret &= test_Connect(b, torture, &ctx->handle);
8886 ret &= test_EnumDomains(p, torture, ctx);
8888 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8893 struct torture_suite *torture_rpc_samr_passwords_lockout(TALLOC_CTX *mem_ctx)
8895 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.passwords.lockout");
8896 struct torture_rpc_tcase *tcase;
8898 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8900 TEST_ACCOUNT_NAME_PWD);
8902 torture_rpc_tcase_add_test_creds(tcase, "lockout",
8903 torture_rpc_samr_lockout);
8908 struct torture_suite *torture_rpc_samr_passwords_validate(TALLOC_CTX *mem_ctx)
8910 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.passwords.validate");
8911 struct torture_rpc_tcase *tcase;
8913 tcase = torture_suite_add_rpc_iface_tcase(suite, "samr",
8915 torture_rpc_tcase_add_test(tcase, "validate",
8916 test_samr_ValidatePassword);