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 gnutls_cipher_hd_t cipher_hnd = NULL;
2271 gnutls_datum_t old_lm_key = {
2272 .data = old_lm_hash,
2273 .size = sizeof(old_lm_hash),
2276 domain_name.string = "";
2277 dom_pw_info.in.domain_name = &domain_name;
2278 dom_pw_info.out.info = &info;
2280 torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name);
2282 torture_assert(tctx, *password != NULL,
2283 "Failing ChangePasswordUser2 as old password was NULL. Previous test failed?");
2284 oldpass = *password;
2287 int policy_min_pw_len = 0;
2288 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDomPwInfo_r(b, tctx, &dom_pw_info),
2289 "GetDomPwInfo failed");
2290 if (NT_STATUS_IS_OK(dom_pw_info.out.result)) {
2291 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
2294 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2297 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2298 init_lsa_String(&account, acct_name);
2300 E_md4hash(oldpass, old_nt_hash);
2301 E_md4hash(newpass, new_nt_hash);
2303 E_deshash(oldpass, old_lm_hash);
2304 E_deshash(newpass, new_lm_hash);
2306 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
2308 gnutls_cipher_init(&cipher_hnd,
2309 GNUTLS_CIPHER_ARCFOUR_128,
2312 gnutls_cipher_encrypt(cipher_hnd,
2315 gnutls_cipher_deinit(cipher_hnd);
2317 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2319 status = init_samr_CryptPassword(newpass,
2322 torture_assert_ntstatus_ok(tctx,
2324 "init_samr_CryptPassword failed");
2326 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2328 r.in.server = &server;
2329 r.in.account = &account;
2330 r.in.nt_password = &nt_pass;
2331 r.in.nt_verifier = &nt_verifier;
2333 r.in.lm_password = &lm_pass;
2334 r.in.lm_verifier = &lm_verifier;
2336 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser2_r(b, tctx, &r),
2337 "ChangePasswordUser2 failed");
2338 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2339 __location__, __FUNCTION__,
2340 oldpass, newpass, nt_errstr(r.out.result));
2342 if (allow_password_restriction && NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
2343 torture_comment(tctx, "ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(r.out.result));
2344 } else if (!NT_STATUS_IS_OK(r.out.result)) {
2345 torture_result(tctx, TORTURE_FAIL, "ChangePasswordUser2 failed - %s\n", nt_errstr(r.out.result));
2348 *password = newpass;
2355 static bool test_ChangePasswordUser2_ntstatus(struct dcerpc_pipe *p, struct torture_context *tctx,
2356 const char *acct_name,
2357 const char *password, NTSTATUS status)
2359 struct samr_ChangePasswordUser2 r;
2360 struct lsa_String server, account;
2361 struct samr_CryptPassword nt_pass, lm_pass;
2362 struct samr_Password nt_verifier, lm_verifier;
2363 const char *oldpass;
2364 struct dcerpc_binding_handle *b = p->binding_handle;
2365 uint8_t old_nt_hash[16], new_nt_hash[16];
2366 uint8_t old_lm_hash[16], new_lm_hash[16];
2367 DATA_BLOB old_nt_hash_blob
2368 = data_blob_const(old_nt_hash, sizeof(old_nt_hash));
2369 gnutls_cipher_hd_t cipher_hnd = NULL;
2370 gnutls_datum_t old_lm_key = {
2371 .data = old_lm_hash,
2372 .size = sizeof(old_lm_hash),
2375 struct samr_GetDomPwInfo dom_pw_info;
2376 struct samr_PwInfo info;
2378 struct lsa_String domain_name;
2379 NTSTATUS crypt_status;
2382 int policy_min_pw_len = 0;
2384 domain_name.string = "";
2385 dom_pw_info.in.domain_name = &domain_name;
2386 dom_pw_info.out.info = &info;
2388 torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name);
2392 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDomPwInfo_r(b, tctx, &dom_pw_info),
2393 "GetDomPwInfo failed");
2394 if (NT_STATUS_IS_OK(dom_pw_info.out.result)) {
2395 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
2398 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2400 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2401 init_lsa_String(&account, acct_name);
2403 E_md4hash(oldpass, old_nt_hash);
2404 E_md4hash(newpass, new_nt_hash);
2406 E_deshash(oldpass, old_lm_hash);
2407 E_deshash(newpass, new_lm_hash);
2409 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
2411 gnutls_cipher_init(&cipher_hnd,
2412 GNUTLS_CIPHER_ARCFOUR_128,
2415 gnutls_cipher_encrypt(cipher_hnd,
2418 gnutls_cipher_deinit(cipher_hnd);
2420 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2422 crypt_status = init_samr_CryptPassword(newpass,
2425 torture_assert_ntstatus_ok(tctx,
2427 "init_samr_CryptPassword failed");
2429 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2431 r.in.server = &server;
2432 r.in.account = &account;
2433 r.in.nt_password = &nt_pass;
2434 r.in.nt_verifier = &nt_verifier;
2436 r.in.lm_password = &lm_pass;
2437 r.in.lm_verifier = &lm_verifier;
2439 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser2_r(b, tctx, &r),
2440 "ChangePasswordUser2 failed");
2441 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2442 __location__, __FUNCTION__,
2443 oldpass, newpass, nt_errstr(r.out.result));
2445 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
2446 torture_comment(tctx, "ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(r.out.result));
2448 torture_assert_ntstatus_equal(tctx, r.out.result, status, "ChangePasswordUser2 returned unexpected value");
2455 bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tctx,
2456 const char *account_string,
2457 int policy_min_pw_len,
2459 const char *newpass,
2460 NTTIME last_password_change,
2461 bool handle_reject_reason)
2463 struct samr_ChangePasswordUser3 r;
2465 struct lsa_String server, account, account_bad;
2466 struct samr_CryptPassword nt_pass, lm_pass;
2467 struct samr_Password nt_verifier, lm_verifier;
2469 struct dcerpc_binding_handle *b = p->binding_handle;
2470 uint8_t old_nt_hash[16], new_nt_hash[16];
2471 uint8_t old_lm_hash[16], new_lm_hash[16];
2473 struct samr_DomInfo1 *dominfo = NULL;
2474 struct userPwdChangeFailureInformation *reject = NULL;
2475 DATA_BLOB old_nt_hash_blob = data_blob_const(old_nt_hash, 16);
2478 torture_comment(tctx, "Testing ChangePasswordUser3\n");
2480 if (newpass == NULL) {
2482 if (policy_min_pw_len == 0) {
2483 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2485 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len);
2487 } while (check_password_quality(newpass) == false);
2489 torture_comment(tctx, "Using password '%s'\n", newpass);
2492 torture_assert(tctx, *password != NULL,
2493 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2495 oldpass = *password;
2496 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2497 init_lsa_String(&account, account_string);
2499 E_md4hash(oldpass, old_nt_hash);
2500 E_md4hash(newpass, new_nt_hash);
2502 E_deshash(oldpass, old_lm_hash);
2503 E_deshash(newpass, new_lm_hash);
2506 * The new plaintext password is encrypted using RC4 with the
2507 * old NT password hash (directly, with no confounder). The
2508 * password is at the end of the random padded buffer,
2509 * offering a little protection.
2511 * This is almost certainly wrong, it should be the old LM
2512 * hash, it was switched in an unrelated commit
2513 * 579c13da43d5b40ac6d6c1436399fbc1d8dfd054 in 2004.
2515 status = init_samr_CryptPassword(newpass,
2518 torture_assert_ntstatus_ok(tctx,
2520 "init_samr_CryptPassword");
2523 * Now we prepare a DES cross-hash of the old LM and new NT
2524 * passwords to link the two buffers
2526 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2529 * The new plaintext password is also encrypted using RC4 with
2530 * the old NT password hash (directly, with no confounder).
2531 * The password is at the end of the random padded buffer,
2532 * offering a little protection.
2534 status = init_samr_CryptPassword(newpass,
2537 torture_assert_ntstatus_ok(tctx,
2539 "init_samr_CryptPassword");
2542 * Another DES based cross-hash
2544 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2546 /* Break the verification */
2547 nt_verifier.hash[0]++;
2549 r.in.server = &server;
2550 r.in.account = &account;
2551 r.in.nt_password = &nt_pass;
2552 r.in.nt_verifier = &nt_verifier;
2554 r.in.lm_password = &lm_pass;
2555 r.in.lm_verifier = &lm_verifier;
2556 r.in.password3 = NULL;
2557 r.out.dominfo = &dominfo;
2558 r.out.reject = &reject;
2560 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2561 "ChangePasswordUser3 failed");
2562 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2563 __location__, __FUNCTION__,
2564 oldpass, newpass, nt_errstr(r.out.result));
2565 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION) &&
2566 (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD))) {
2567 torture_result(tctx, TORTURE_FAIL, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
2568 nt_errstr(r.out.result));
2572 status = init_samr_CryptPassword(newpass,
2575 torture_assert_ntstatus_ok(tctx,
2577 "init_samr_CryptPassword");
2579 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2581 /* Break the NT Hash */
2584 status = init_samr_CryptPassword(newpass,
2587 torture_assert_ntstatus_ok(tctx,
2589 "init_samr_CryptPassword");
2591 /* Unbreak it again */
2594 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2596 r.in.server = &server;
2597 r.in.account = &account;
2598 r.in.nt_password = &nt_pass;
2599 r.in.nt_verifier = &nt_verifier;
2601 r.in.lm_password = &lm_pass;
2602 r.in.lm_verifier = &lm_verifier;
2603 r.in.password3 = NULL;
2604 r.out.dominfo = &dominfo;
2605 r.out.reject = &reject;
2607 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2608 "ChangePasswordUser3 failed");
2609 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2610 __location__, __FUNCTION__,
2611 oldpass, newpass, nt_errstr(r.out.result));
2612 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION) &&
2613 (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD))) {
2614 torture_result(tctx, TORTURE_FAIL, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
2615 nt_errstr(r.out.result));
2619 /* This shouldn't be a valid name */
2620 init_lsa_String(&account_bad, talloc_asprintf(tctx, "%sXX", account_string));
2622 r.in.account = &account_bad;
2623 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2624 "ChangePasswordUser3 failed");
2625 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2626 __location__, __FUNCTION__,
2627 oldpass, newpass, nt_errstr(r.out.result));
2628 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD)) {
2629 torture_result(tctx, TORTURE_FAIL, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
2630 nt_errstr(r.out.result));
2634 E_md4hash(oldpass, old_nt_hash);
2635 E_md4hash(newpass, new_nt_hash);
2637 E_deshash(oldpass, old_lm_hash);
2638 E_deshash(newpass, new_lm_hash);
2640 status = init_samr_CryptPassword(newpass,
2643 torture_assert_ntstatus_ok(tctx,
2645 "init_samr_CryptPassword");
2647 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2649 status = init_samr_CryptPassword(newpass,
2652 torture_assert_ntstatus_ok(tctx,
2654 "init_samr_CryptPassword");
2656 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2658 r.in.server = &server;
2659 r.in.account = &account;
2660 r.in.nt_password = &nt_pass;
2661 r.in.nt_verifier = &nt_verifier;
2663 r.in.lm_password = &lm_pass;
2664 r.in.lm_verifier = &lm_verifier;
2665 r.in.password3 = NULL;
2666 r.out.dominfo = &dominfo;
2667 r.out.reject = &reject;
2669 unix_to_nt_time(&t, time(NULL));
2671 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2672 "ChangePasswordUser3 failed");
2673 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2674 __location__, __FUNCTION__,
2675 oldpass, newpass, nt_errstr(r.out.result));
2677 torture_comment(tctx, "(%s): dominfo[%s], reject[%s], handle_reject_reason[%s], "
2678 "last_password_change[%s], dominfo->min_password_age[%lld]\n",
2680 (dominfo == NULL)? "NULL" : "present",
2681 reject ? "true" : "false",
2682 handle_reject_reason ? "true" : "false",
2683 null_nttime(last_password_change) ? "null" : "not null",
2684 dominfo ? (long long)dominfo->min_password_age : (long long)0);
2686 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)
2689 && handle_reject_reason
2690 && (!null_nttime(last_password_change) || !dominfo->min_password_age)) {
2691 if (dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
2693 if (reject && (reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR)) {
2694 torture_result(tctx, TORTURE_FAIL, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2695 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2700 /* We tested the order of precendence which is as follows:
2709 if ((dominfo->min_password_age < 0) && !null_nttime(last_password_change) &&
2710 (last_password_change - dominfo->min_password_age > t)) {
2712 if (reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2713 torture_result(tctx, TORTURE_FAIL, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2714 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2718 } else if ((dominfo->min_password_length > 0) &&
2719 (strlen(newpass) < dominfo->min_password_length)) {
2721 if (reject->extendedFailureReason != SAM_PWD_CHANGE_PASSWORD_TOO_SHORT) {
2722 torture_result(tctx, TORTURE_FAIL, "expected SAM_PWD_CHANGE_PASSWORD_TOO_SHORT (%d), got %d\n",
2723 SAM_PWD_CHANGE_PASSWORD_TOO_SHORT, reject->extendedFailureReason);
2727 } else if ((dominfo->password_history_length > 0) &&
2728 strequal(oldpass, newpass)) {
2730 if (reject->extendedFailureReason != SAM_PWD_CHANGE_PWD_IN_HISTORY) {
2731 torture_result(tctx, TORTURE_FAIL, "expected SAM_PWD_CHANGE_PWD_IN_HISTORY (%d), got %d\n",
2732 SAM_PWD_CHANGE_PWD_IN_HISTORY, reject->extendedFailureReason);
2735 } else if (dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
2737 if (reject->extendedFailureReason != SAM_PWD_CHANGE_NOT_COMPLEX) {
2738 torture_result(tctx, TORTURE_FAIL, "expected SAM_PWD_CHANGE_NOT_COMPLEX (%d), got %d\n",
2739 SAM_PWD_CHANGE_NOT_COMPLEX, reject->extendedFailureReason);
2745 if (reject->extendedFailureReason == SAM_PWD_CHANGE_PASSWORD_TOO_SHORT) {
2746 /* retry with adjusted size */
2747 return test_ChangePasswordUser3(p, tctx, account_string,
2748 dominfo->min_password_length,
2749 password, NULL, 0, false);
2753 } else if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
2754 if (reject && reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2755 torture_result(tctx, TORTURE_FAIL, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2756 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2759 /* Perhaps the server has a 'min password age' set? */
2762 torture_assert_ntstatus_ok(tctx, r.out.result, "ChangePasswordUser3");
2764 *password = talloc_strdup(tctx, newpass);
2770 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_context *tctx,
2771 const char *account_string,
2772 struct policy_handle *handle,
2776 struct samr_ChangePasswordUser3 r;
2777 struct samr_SetUserInfo s;
2778 union samr_UserInfo u;
2779 DATA_BLOB session_key;
2780 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
2781 uint8_t confounder[16];
2782 gnutls_hash_hd_t hash_hnd;
2785 struct lsa_String server, account;
2786 struct samr_CryptPassword nt_pass;
2787 struct samr_Password nt_verifier;
2788 DATA_BLOB new_random_pass;
2791 struct dcerpc_binding_handle *b = p->binding_handle;
2792 uint8_t old_nt_hash[16], new_nt_hash[16];
2793 DATA_BLOB old_nt_hash_blob
2794 = data_blob_const(old_nt_hash,
2795 sizeof(old_nt_hash));
2797 struct samr_DomInfo1 *dominfo = NULL;
2798 struct userPwdChangeFailureInformation *reject = NULL;
2799 gnutls_cipher_hd_t cipher_hnd = NULL;
2800 gnutls_datum_t old_nt_key = {
2801 .data = old_nt_hash,
2802 .size = sizeof(old_nt_hash),
2805 new_random_pass = samr_very_rand_pass(tctx, 128);
2807 torture_assert(tctx, *password != NULL,
2808 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2810 oldpass = *password;
2811 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2812 init_lsa_String(&account, account_string);
2814 s.in.user_handle = handle;
2820 u.info25.info.fields_present = SAMR_FIELD_NT_PASSWORD_PRESENT;
2822 set_pw_in_buffer(u.info25.password.data, &new_random_pass);
2824 status = dcerpc_fetch_session_key(p, &session_key);
2825 if (!NT_STATUS_IS_OK(status)) {
2826 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u - no session key - %s\n",
2827 s.in.level, nt_errstr(status));
2831 generate_random_buffer((uint8_t *)confounder, 16);
2833 gnutls_hash_init(&hash_hnd, GNUTLS_DIG_MD5);
2834 gnutls_hash(hash_hnd, confounder, 16);
2835 gnutls_hash(hash_hnd, session_key.data, session_key.length);
2836 gnutls_hash_deinit(hash_hnd, confounded_session_key.data);
2838 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
2839 memcpy(&u.info25.password.data[516], confounder, 16);
2841 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
2843 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
2844 "SetUserInfo failed");
2845 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2846 __location__, __FUNCTION__,
2847 oldpass, "RANDOM", nt_errstr(s.out.result));
2848 if (!NT_STATUS_IS_OK(s.out.result)) {
2849 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u failed - %s\n",
2850 s.in.level, nt_errstr(s.out.result));
2854 torture_comment(tctx, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
2856 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2858 new_random_pass = samr_very_rand_pass(tctx, 128);
2860 mdfour(new_nt_hash, new_random_pass.data, new_random_pass.length);
2862 set_pw_in_buffer(nt_pass.data, &new_random_pass);
2864 gnutls_cipher_init(&cipher_hnd,
2865 GNUTLS_CIPHER_ARCFOUR_128,
2868 gnutls_cipher_encrypt(cipher_hnd,
2871 gnutls_cipher_deinit(cipher_hnd);
2873 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2875 r.in.server = &server;
2876 r.in.account = &account;
2877 r.in.nt_password = &nt_pass;
2878 r.in.nt_verifier = &nt_verifier;
2880 r.in.lm_password = NULL;
2881 r.in.lm_verifier = NULL;
2882 r.in.password3 = NULL;
2883 r.out.dominfo = &dominfo;
2884 r.out.reject = &reject;
2886 unix_to_nt_time(&t, time(NULL));
2888 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2889 "ChangePasswordUser3 failed");
2890 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2891 __location__, __FUNCTION__,
2892 oldpass, "RANDOM", nt_errstr(r.out.result));
2894 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
2895 if (reject && reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2896 torture_result(tctx, TORTURE_FAIL, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2897 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2900 /* Perhaps the server has a 'min password age' set? */
2902 } else if (!NT_STATUS_IS_OK(r.out.result)) {
2903 torture_result(tctx, TORTURE_FAIL, "ChangePasswordUser3 failed - %s\n", nt_errstr(r.out.result));
2907 newpass = samr_rand_pass(tctx, 128);
2909 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2911 E_md4hash(newpass, new_nt_hash);
2913 status = init_samr_CryptPassword(newpass,
2916 torture_assert_ntstatus_ok(tctx,
2918 "init_samr_CryptPassword failed");
2920 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2922 r.in.server = &server;
2923 r.in.account = &account;
2924 r.in.nt_password = &nt_pass;
2925 r.in.nt_verifier = &nt_verifier;
2927 r.in.lm_password = NULL;
2928 r.in.lm_verifier = NULL;
2929 r.in.password3 = NULL;
2930 r.out.dominfo = &dominfo;
2931 r.out.reject = &reject;
2933 unix_to_nt_time(&t, time(NULL));
2935 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2936 "ChangePasswordUser3 failed");
2937 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2938 __location__, __FUNCTION__,
2939 oldpass, newpass, nt_errstr(r.out.result));
2941 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
2942 if (reject && reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2943 torture_result(tctx, TORTURE_FAIL, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2944 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2947 /* Perhaps the server has a 'min password age' set? */
2950 torture_assert_ntstatus_ok(tctx, r.out.result, "ChangePasswordUser3 (on second random password)");
2951 *password = talloc_strdup(tctx, newpass);
2958 static bool test_GetMembersInAlias(struct dcerpc_binding_handle *b,
2959 struct torture_context *tctx,
2960 struct policy_handle *alias_handle)
2962 struct samr_GetMembersInAlias r;
2963 struct lsa_SidArray sids;
2965 torture_comment(tctx, "Testing GetMembersInAlias\n");
2967 r.in.alias_handle = alias_handle;
2970 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetMembersInAlias_r(b, tctx, &r),
2971 "GetMembersInAlias failed");
2972 torture_assert_ntstatus_ok(tctx, r.out.result, "GetMembersInAlias failed");
2977 static bool test_AddMemberToAlias(struct dcerpc_binding_handle *b,
2978 struct torture_context *tctx,
2979 struct policy_handle *alias_handle,
2980 const struct dom_sid *domain_sid)
2982 struct samr_AddAliasMember r;
2983 struct samr_DeleteAliasMember d;
2984 struct dom_sid *sid;
2986 sid = dom_sid_add_rid(tctx, domain_sid, 512);
2988 torture_comment(tctx, "Testing AddAliasMember\n");
2989 r.in.alias_handle = alias_handle;
2992 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddAliasMember_r(b, tctx, &r),
2993 "AddAliasMember failed");
2994 torture_assert_ntstatus_ok(tctx, r.out.result, "AddAliasMember failed");
2996 d.in.alias_handle = alias_handle;
2999 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteAliasMember_r(b, tctx, &d),
3000 "DeleteAliasMember failed");
3001 torture_assert_ntstatus_ok(tctx, d.out.result, "DelAliasMember failed");
3006 static bool test_AddMultipleMembersToAlias(struct dcerpc_binding_handle *b,
3007 struct torture_context *tctx,
3008 struct policy_handle *alias_handle)
3010 struct samr_AddMultipleMembersToAlias a;
3011 struct samr_RemoveMultipleMembersFromAlias r;
3012 struct lsa_SidArray sids;
3014 torture_comment(tctx, "Testing AddMultipleMembersToAlias\n");
3015 a.in.alias_handle = alias_handle;
3019 sids.sids = talloc_array(tctx, struct lsa_SidPtr, 3);
3021 sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
3022 sids.sids[1].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-2");
3023 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-3");
3025 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddMultipleMembersToAlias_r(b, tctx, &a),
3026 "AddMultipleMembersToAlias failed");
3027 torture_assert_ntstatus_ok(tctx, a.out.result, "AddMultipleMembersToAlias");
3030 torture_comment(tctx, "Testing RemoveMultipleMembersFromAlias\n");
3031 r.in.alias_handle = alias_handle;
3034 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RemoveMultipleMembersFromAlias_r(b, tctx, &r),
3035 "RemoveMultipleMembersFromAlias failed");
3036 torture_assert_ntstatus_ok(tctx, r.out.result, "RemoveMultipleMembersFromAlias failed");
3038 /* strange! removing twice doesn't give any error */
3039 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RemoveMultipleMembersFromAlias_r(b, tctx, &r),
3040 "RemoveMultipleMembersFromAlias failed");
3041 torture_assert_ntstatus_ok(tctx, r.out.result, "RemoveMultipleMembersFromAlias failed");
3043 /* but removing an alias that isn't there does */
3044 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-4");
3046 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RemoveMultipleMembersFromAlias_r(b, tctx, &r),
3047 "RemoveMultipleMembersFromAlias failed");
3048 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND, "RemoveMultipleMembersFromAlias");
3053 static bool test_GetAliasMembership(struct dcerpc_binding_handle *b,
3054 struct torture_context *tctx,
3055 struct policy_handle *domain_handle)
3057 struct samr_GetAliasMembership r;
3058 struct lsa_SidArray sids;
3059 struct samr_Ids rids;
3061 torture_comment(tctx, "Testing GetAliasMembership\n");
3063 r.in.domain_handle = domain_handle;
3068 sids.sids = talloc_zero_array(tctx, struct lsa_SidPtr, sids.num_sids);
3070 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetAliasMembership_r(b, tctx, &r),
3071 "GetAliasMembership failed");
3072 torture_assert_ntstatus_ok(tctx, r.out.result,
3073 "samr_GetAliasMembership failed");
3075 torture_assert_int_equal(tctx, sids.num_sids, rids.count,
3076 "protocol misbehaviour");
3079 sids.sids = talloc_zero_array(tctx, struct lsa_SidPtr, sids.num_sids);
3080 sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
3082 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetAliasMembership_r(b, tctx, &r),
3083 "samr_GetAliasMembership failed");
3084 torture_assert_ntstatus_ok(tctx, r.out.result,
3085 "samr_GetAliasMembership failed");
3088 /* only true for w2k8 it seems
3089 * win7, xp, w2k3 will return a 0 length array pointer */
3091 if (rids.ids && (rids.count == 0)) {
3092 torture_fail(tctx, "samr_GetAliasMembership returned 0 count and a rids array");
3095 if (!rids.ids && rids.count) {
3096 torture_fail(tctx, "samr_GetAliasMembership returned non-0 count but no rids");
3102 static bool test_TestPrivateFunctionsUser(struct dcerpc_binding_handle *b,
3103 struct torture_context *tctx,
3104 struct policy_handle *user_handle)
3106 struct samr_TestPrivateFunctionsUser r;
3108 torture_comment(tctx, "Testing TestPrivateFunctionsUser\n");
3110 r.in.user_handle = user_handle;
3112 torture_assert_ntstatus_ok(tctx, dcerpc_samr_TestPrivateFunctionsUser_r(b, tctx, &r),
3113 "TestPrivateFunctionsUser failed");
3114 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsUser");
3119 static bool test_QueryUserInfo_pwdlastset(struct dcerpc_binding_handle *b,
3120 struct torture_context *tctx,
3121 struct policy_handle *handle,
3126 uint16_t levels[] = { /* 3, */ 5, 21 };
3128 /* NTTIME pwdlastset3 = 0; */
3129 NTTIME pwdlastset5 = 0;
3130 NTTIME pwdlastset21 = 0;
3132 torture_comment(tctx, "Testing QueryUserInfo%s level 5 and 21 call ",
3133 use_info2 ? "2":"");
3135 for (i=0; i<ARRAY_SIZE(levels); i++) {
3137 struct samr_QueryUserInfo r;
3138 struct samr_QueryUserInfo2 r2;
3139 union samr_UserInfo *info;
3142 r2.in.user_handle = handle;
3143 r2.in.level = levels[i];
3144 r2.out.info = &info;
3145 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo2_r(b, tctx, &r2),
3146 "QueryUserInfo2 failed");
3147 status = r2.out.result;
3150 r.in.user_handle = handle;
3151 r.in.level = levels[i];
3153 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
3154 "QueryUserInfo failed");
3155 status = r.out.result;
3158 if (!NT_STATUS_IS_OK(status) &&
3159 !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
3160 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo%s level %u failed - %s\n",
3161 use_info2 ? "2":"", levels[i], nt_errstr(status));
3165 switch (levels[i]) {
3167 /* pwdlastset3 = info->info3.last_password_change; */
3170 pwdlastset5 = info->info5.last_password_change;
3173 pwdlastset21 = info->info21.last_password_change;
3179 /* torture_assert_int_equal(tctx, pwdlastset3, pwdlastset5,
3180 "pwdlastset mixup"); */
3181 torture_assert_int_equal(tctx, pwdlastset5, pwdlastset21,
3182 "pwdlastset mixup");
3184 *pwdlastset = pwdlastset21;
3186 torture_comment(tctx, "(pwdlastset: %llu)\n",
3187 (unsigned long long) *pwdlastset);
3192 static bool test_SamLogon(struct torture_context *tctx,
3193 struct dcerpc_pipe *p,
3194 struct cli_credentials *machine_credentials,
3195 struct cli_credentials *test_credentials,
3196 NTSTATUS expected_result,
3200 struct netr_LogonSamLogonEx r;
3201 union netr_LogonLevel logon;
3202 union netr_Validation validation;
3203 uint8_t authoritative;
3204 struct netr_IdentityInfo identity;
3205 struct netr_NetworkInfo ninfo;
3206 struct netr_PasswordInfo pinfo;
3207 DATA_BLOB names_blob, chal, lm_resp, nt_resp;
3208 int flags = CLI_CRED_NTLM_AUTH;
3209 uint32_t samlogon_flags = 0;
3210 struct netlogon_creds_CredentialState *creds;
3211 struct netr_Authenticator a;
3212 struct dcerpc_binding_handle *b = p->binding_handle;
3214 torture_assert(tctx, (creds = cli_credentials_get_netlogon_creds(machine_credentials)), "");
3216 if (lpcfg_client_lanman_auth(tctx->lp_ctx)) {
3217 flags |= CLI_CRED_LANMAN_AUTH;
3220 if (lpcfg_client_ntlmv2_auth(tctx->lp_ctx)) {
3221 flags |= CLI_CRED_NTLMv2_AUTH;
3224 cli_credentials_get_ntlm_username_domain(test_credentials, tctx,
3225 &identity.account_name.string,
3226 &identity.domain_name.string);
3228 identity.parameter_control =
3229 MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT |
3230 MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;
3231 identity.logon_id = 0;
3232 identity.workstation.string = cli_credentials_get_workstation(test_credentials);
3235 netlogon_creds_client_authenticator(creds, &a);
3237 if (!E_deshash(cli_credentials_get_password(test_credentials), pinfo.lmpassword.hash)) {
3238 ZERO_STRUCT(pinfo.lmpassword.hash);
3240 E_md4hash(cli_credentials_get_password(test_credentials), pinfo.ntpassword.hash);
3242 if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
3243 netlogon_creds_aes_encrypt(creds, pinfo.lmpassword.hash, 16);
3244 netlogon_creds_aes_encrypt(creds, pinfo.ntpassword.hash, 16);
3245 } else if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
3246 netlogon_creds_arcfour_crypt(creds, pinfo.lmpassword.hash, 16);
3247 netlogon_creds_arcfour_crypt(creds, pinfo.ntpassword.hash, 16);
3249 netlogon_creds_des_encrypt(creds, &pinfo.lmpassword);
3250 netlogon_creds_des_encrypt(creds, &pinfo.ntpassword);
3253 pinfo.identity_info = identity;
3254 logon.password = &pinfo;
3256 r.in.logon_level = NetlogonInteractiveInformation;
3258 generate_random_buffer(ninfo.challenge,
3259 sizeof(ninfo.challenge));
3260 chal = data_blob_const(ninfo.challenge,
3261 sizeof(ninfo.challenge));
3263 names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(test_credentials),
3264 cli_credentials_get_domain(test_credentials));
3266 status = cli_credentials_get_ntlm_response(test_credentials, tctx,
3269 NULL, /* server_timestamp */
3273 torture_assert_ntstatus_ok(tctx, status, "cli_credentials_get_ntlm_response failed");
3275 ninfo.lm.data = lm_resp.data;
3276 ninfo.lm.length = lm_resp.length;
3278 ninfo.nt.data = nt_resp.data;
3279 ninfo.nt.length = nt_resp.length;
3281 ninfo.identity_info = identity;
3282 logon.network = &ninfo;
3284 r.in.logon_level = NetlogonNetworkInformation;
3287 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3288 r.in.computer_name = cli_credentials_get_workstation(test_credentials);
3289 r.in.logon = &logon;
3290 r.in.flags = &samlogon_flags;
3291 r.out.flags = &samlogon_flags;
3292 r.out.validation = &validation;
3293 r.out.authoritative = &authoritative;
3295 torture_comment(tctx, "Testing LogonSamLogon with name %s\n", identity.account_name.string);
3297 r.in.validation_level = 6;
3299 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogonEx_r(b, tctx, &r),
3300 "netr_LogonSamLogonEx failed");
3301 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_INFO_CLASS)) {
3302 r.in.validation_level = 3;
3303 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogonEx_r(b, tctx, &r),
3304 "netr_LogonSamLogonEx failed");
3306 if (!NT_STATUS_IS_OK(r.out.result)) {
3307 torture_assert_ntstatus_equal(tctx, r.out.result, expected_result, "LogonSamLogonEx failed");
3310 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogonEx failed");
3316 static bool test_SamLogon_with_creds(struct torture_context *tctx,
3317 struct dcerpc_pipe *p,
3318 struct cli_credentials *machine_creds,
3319 const char *acct_name,
3320 const char *password,
3321 NTSTATUS expected_samlogon_result,
3325 struct cli_credentials *test_credentials;
3327 test_credentials = cli_credentials_init(tctx);
3329 cli_credentials_set_workstation(test_credentials,
3330 cli_credentials_get_workstation(machine_creds), CRED_SPECIFIED);
3331 cli_credentials_set_domain(test_credentials,
3332 cli_credentials_get_domain(machine_creds), CRED_SPECIFIED);
3333 cli_credentials_set_username(test_credentials,
3334 acct_name, CRED_SPECIFIED);
3335 cli_credentials_set_password(test_credentials,
3336 password, CRED_SPECIFIED);
3338 torture_comment(tctx, "Testing samlogon (%s) as %s password: %s\n",
3339 interactive ? "interactive" : "network", acct_name, password);
3341 if (!test_SamLogon(tctx, p, machine_creds, test_credentials,
3342 expected_samlogon_result, interactive)) {
3343 torture_result(tctx, TORTURE_FAIL, "new password did not work\n");
3350 static bool test_SetPassword_level(struct dcerpc_pipe *p,
3351 struct dcerpc_pipe *np,
3352 struct torture_context *tctx,
3353 struct policy_handle *handle,
3355 uint32_t fields_present,
3356 uint8_t password_expired,
3357 bool *matched_expected_error,
3359 const char *acct_name,
3361 struct cli_credentials *machine_creds,
3362 bool use_queryinfo2,
3364 NTSTATUS expected_samlogon_result)
3366 const char *fields = NULL;
3368 struct dcerpc_binding_handle *b = p->binding_handle;
3374 fields = talloc_asprintf(tctx, "(fields_present: 0x%08x)",
3381 torture_comment(tctx, "Testing SetUserInfo%s level %d call "
3382 "(password_expired: %d) %s\n",
3383 use_setinfo2 ? "2":"", level, password_expired,
3384 fields ? fields : "");
3386 if (!test_SetUserPass_level_ex(p, tctx, handle, level,
3391 matched_expected_error)) {
3395 if (!test_QueryUserInfo_pwdlastset(b, tctx, handle,
3401 if (*matched_expected_error == true) {
3405 if (!test_SamLogon_with_creds(tctx, np,
3409 expected_samlogon_result,
3417 static bool setup_schannel_netlogon_pipe(struct torture_context *tctx,
3418 struct cli_credentials *credentials,
3419 struct dcerpc_pipe **p)
3421 struct dcerpc_binding *b;
3424 torture_assert_ntstatus_ok(tctx, torture_rpc_binding(tctx, &b),
3425 "failed to get rpc binding");
3427 /* We have to use schannel, otherwise the SamLogonEx fails
3428 * with INTERNAL_ERROR */
3430 status = dcerpc_binding_set_flags(b,
3432 DCERPC_SIGN | DCERPC_SEAL |
3433 DCERPC_SCHANNEL_AUTO,
3434 DCERPC_AUTH_OPTIONS);
3435 torture_assert_ntstatus_ok(tctx, status, "set flags");
3437 torture_assert_ntstatus_ok(tctx,
3438 dcerpc_pipe_connect_b(tctx, p, b, &ndr_table_netlogon,
3439 credentials, tctx->ev, tctx->lp_ctx),
3440 "failed to bind to netlogon");
3445 static bool test_SetPassword_pwdlastset(struct dcerpc_pipe *p,
3446 struct torture_context *tctx,
3447 uint32_t acct_flags,
3448 const char *acct_name,
3449 struct policy_handle *handle,
3451 struct cli_credentials *machine_credentials)
3453 int s = 0, q = 0, f = 0, l = 0, z = 0;
3456 bool set_levels[] = { false, true };
3457 bool query_levels[] = { false, true };
3458 uint32_t levels[] = { 18, 21, 26, 23, 24, 25 }; /* Second half only used when TEST_ALL_LEVELS defined */
3459 uint32_t nonzeros[] = { 1, 24 };
3460 uint32_t fields_present[] = {
3462 SAMR_FIELD_EXPIRED_FLAG,
3463 SAMR_FIELD_LAST_PWD_CHANGE,
3464 SAMR_FIELD_EXPIRED_FLAG | SAMR_FIELD_LAST_PWD_CHANGE,
3466 SAMR_FIELD_NT_PASSWORD_PRESENT,
3467 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
3468 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
3469 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
3470 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
3471 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
3472 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE | SAMR_FIELD_EXPIRED_FLAG
3474 struct dcerpc_pipe *np = NULL;
3476 if (torture_setting_bool(tctx, "samba3", false) ||
3477 torture_setting_bool(tctx, "samba4", false)) {
3479 torture_comment(tctx, "Samba3 has second granularity, setting delay to: %d\n",
3483 torture_assert(tctx, setup_schannel_netlogon_pipe(tctx, machine_credentials, &np), "");
3485 /* set to 1 to enable testing for all possible opcode
3486 (SetUserInfo, SetUserInfo2, QueryUserInfo, QueryUserInfo2)
3489 #define TEST_ALL_LEVELS 1
3490 #define TEST_SET_LEVELS 1
3491 #define TEST_QUERY_LEVELS 1
3493 #ifdef TEST_ALL_LEVELS
3494 for (l=0; l<ARRAY_SIZE(levels); l++) {
3496 for (l=0; l<(ARRAY_SIZE(levels))/2; l++) {
3498 for (z=0; z<ARRAY_SIZE(nonzeros); z++) {
3499 for (f=0; f<ARRAY_SIZE(fields_present); f++) {
3500 #ifdef TEST_SET_LEVELS
3501 for (s=0; s<ARRAY_SIZE(set_levels); s++) {
3503 #ifdef TEST_QUERY_LEVELS
3504 for (q=0; q<ARRAY_SIZE(query_levels); q++) {
3506 NTTIME pwdlastset_old = 0;
3507 NTTIME pwdlastset_new = 0;
3508 bool matched_expected_error = false;
3509 NTSTATUS expected_samlogon_result = NT_STATUS_ACCOUNT_DISABLED;
3511 torture_comment(tctx, "------------------------------\n"
3512 "Testing pwdLastSet attribute for flags: 0x%08x "
3513 "(s: %d (l: %d), q: %d)\n",
3514 acct_flags, s, levels[l], q);
3516 switch (levels[l]) {
3520 if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3521 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT))) {
3522 expected_samlogon_result = NT_STATUS_WRONG_PASSWORD;
3530 /* set a password and force password change (pwdlastset 0) by
3531 * setting the password expired flag to a non-0 value */
3533 if (!test_SetPassword_level(p, np, tctx, handle,
3537 &matched_expected_error,
3541 machine_credentials,
3544 expected_samlogon_result)) {
3548 if (matched_expected_error == true) {
3549 /* skipping on expected failure */
3553 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3554 * set without the SAMR_FIELD_EXPIRED_FLAG */
3556 switch (levels[l]) {
3560 if ((pwdlastset_new != 0) &&
3561 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
3562 torture_comment(tctx, "not considering a non-0 "
3563 "pwdLastSet as a an error as the "
3564 "SAMR_FIELD_EXPIRED_FLAG has not "
3570 if (pwdlastset_new != 0) {
3571 torture_result(tctx, TORTURE_FAIL, "pwdLastSet test failed: "
3572 "expected pwdLastSet 0 but got %llu\n",
3573 (unsigned long long) pwdlastset_old);
3579 switch (levels[l]) {
3583 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3584 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3585 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3586 (pwdlastset_old >= pwdlastset_new)) {
3587 torture_result(tctx, TORTURE_FAIL, "pwdlastset not increasing\n");
3593 pwdlastset_old = pwdlastset_new;
3599 /* set a password, pwdlastset needs to get updated (increased
3600 * value), password_expired value used here is 0 */
3602 if (!test_SetPassword_level(p, np, tctx, handle,
3606 &matched_expected_error,
3610 machine_credentials,
3613 expected_samlogon_result)) {
3617 /* when a password has been changed, pwdlastset must not be 0 afterwards
3618 * and must be larger then the old value */
3620 switch (levels[l]) {
3624 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3625 * password has been changed, old and new pwdlastset
3626 * need to be the same value */
3628 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3629 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3630 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3632 torture_assert_int_equal(tctx, pwdlastset_old,
3633 pwdlastset_new, "pwdlastset must be equal");
3638 if (pwdlastset_old >= pwdlastset_new) {
3639 torture_result(tctx, TORTURE_FAIL, "pwdLastSet test failed: "
3640 "expected last pwdlastset (%llu) < new pwdlastset (%llu)\n",
3641 (unsigned long long) pwdlastset_old,
3642 (unsigned long long) pwdlastset_new);
3645 if (pwdlastset_new == 0) {
3646 torture_result(tctx, TORTURE_FAIL, "pwdLastSet test failed: "
3647 "expected non-0 pwdlastset, got: %llu\n",
3648 (unsigned long long) pwdlastset_new);
3654 switch (levels[l]) {
3658 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3659 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3660 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3661 (pwdlastset_old >= pwdlastset_new)) {
3662 torture_result(tctx, TORTURE_FAIL, "pwdlastset not increasing\n");
3668 pwdlastset_old = pwdlastset_new;
3674 /* set a password, pwdlastset needs to get updated (increased
3675 * value), password_expired value used here is 0 */
3677 if (!test_SetPassword_level(p, np, tctx, handle,
3681 &matched_expected_error,
3685 machine_credentials,
3688 expected_samlogon_result)) {
3692 /* when a password has been changed, pwdlastset must not be 0 afterwards
3693 * and must be larger then the old value */
3695 switch (levels[l]) {
3700 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3701 * password has been changed, old and new pwdlastset
3702 * need to be the same value */
3704 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3705 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3706 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3708 torture_assert_int_equal(tctx, pwdlastset_old,
3709 pwdlastset_new, "pwdlastset must be equal");
3714 if (pwdlastset_old >= pwdlastset_new) {
3715 torture_result(tctx, TORTURE_FAIL, "pwdLastSet test failed: "
3716 "expected last pwdlastset (%llu) < new pwdlastset (%llu)\n",
3717 (unsigned long long) pwdlastset_old,
3718 (unsigned long long) pwdlastset_new);
3721 if (pwdlastset_new == 0) {
3722 torture_result(tctx, TORTURE_FAIL, "pwdLastSet test failed: "
3723 "expected non-0 pwdlastset, got: %llu\n",
3724 (unsigned long long) pwdlastset_new);
3730 switch (levels[l]) {
3734 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3735 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3736 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3737 (pwdlastset_old >= pwdlastset_new)) {
3738 torture_result(tctx, TORTURE_FAIL, "pwdlastset not increasing\n");
3744 pwdlastset_old = pwdlastset_new;
3750 /* set a password and force password change (pwdlastset 0) by
3751 * setting the password expired flag to a non-0 value */
3753 if (!test_SetPassword_level(p, np, tctx, handle,
3757 &matched_expected_error,
3761 machine_credentials,
3764 expected_samlogon_result)) {
3768 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3769 * set without the SAMR_FIELD_EXPIRED_FLAG */
3771 switch (levels[l]) {
3775 if ((pwdlastset_new != 0) &&
3776 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
3777 torture_comment(tctx, "not considering a non-0 "
3778 "pwdLastSet as a an error as the "
3779 "SAMR_FIELD_EXPIRED_FLAG has not "
3784 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3785 * password has been changed, old and new pwdlastset
3786 * need to be the same value */
3788 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3789 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3790 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3792 torture_assert_int_equal(tctx, pwdlastset_old,
3793 pwdlastset_new, "pwdlastset must be equal");
3798 if (pwdlastset_new != 0) {
3799 torture_result(tctx, TORTURE_FAIL, "pwdLastSet test failed: "
3800 "expected pwdLastSet 0, got %llu\n",
3801 (unsigned long long) pwdlastset_old);
3807 switch (levels[l]) {
3811 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3812 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3813 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3814 (pwdlastset_old >= pwdlastset_new)) {
3815 torture_result(tctx, TORTURE_FAIL, "pwdlastset not increasing\n");
3821 /* if the level we are testing does not have a fields_present
3822 * field, skip all fields present tests by setting f to to
3824 switch (levels[l]) {
3828 f = ARRAY_SIZE(fields_present);
3832 #ifdef TEST_QUERY_LEVELS
3835 #ifdef TEST_SET_LEVELS
3838 } /* fields present */
3842 #undef TEST_SET_LEVELS
3843 #undef TEST_QUERY_LEVELS
3850 static bool test_QueryUserInfo_badpwdcount(struct dcerpc_binding_handle *b,
3851 struct torture_context *tctx,
3852 struct policy_handle *handle,
3853 uint32_t *badpwdcount)
3855 union samr_UserInfo *info;
3856 struct samr_QueryUserInfo r;
3858 r.in.user_handle = handle;
3862 torture_comment(tctx, "Testing QueryUserInfo level %d", r.in.level);
3864 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
3865 "failed to query userinfo");
3866 torture_assert_ntstatus_ok(tctx, r.out.result,
3867 "failed to query userinfo");
3869 *badpwdcount = info->info3.bad_password_count;
3871 torture_comment(tctx, " (bad password count: %d)\n", *badpwdcount);
3876 static bool test_SetUserInfo_acct_flags(struct dcerpc_binding_handle *b,
3877 struct torture_context *tctx,
3878 struct policy_handle *user_handle,
3879 uint32_t acct_flags)
3881 struct samr_SetUserInfo r;
3882 union samr_UserInfo user_info;
3884 torture_comment(tctx, "Testing SetUserInfo level 16\n");
3886 user_info.info16.acct_flags = acct_flags;
3888 r.in.user_handle = user_handle;
3890 r.in.info = &user_info;
3892 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &r),
3893 "failed to set account flags");
3894 torture_assert_ntstatus_ok(tctx, r.out.result,
3895 "failed to set account flags");
3900 static bool test_reset_badpwdcount(struct dcerpc_pipe *p,
3901 struct torture_context *tctx,
3902 struct policy_handle *user_handle,
3903 uint32_t acct_flags,
3906 struct dcerpc_binding_handle *b = p->binding_handle;
3908 torture_assert(tctx, test_SetUserPass(p, tctx, user_handle, password),
3909 "failed to set password");
3911 torture_comment(tctx, "Testing SetUserInfo level 16 (enable account)\n");
3913 torture_assert(tctx,
3914 test_SetUserInfo_acct_flags(b, tctx, user_handle,
3915 acct_flags & ~ACB_DISABLED),
3916 "failed to enable user");
3918 torture_assert(tctx, test_SetUserPass(p, tctx, user_handle, password),
3919 "failed to set password");
3924 static bool test_SetDomainInfo(struct dcerpc_binding_handle *b,
3925 struct torture_context *tctx,
3926 struct policy_handle *domain_handle,
3927 enum samr_DomainInfoClass level,
3928 union samr_DomainInfo *info)
3930 struct samr_SetDomainInfo r;
3932 r.in.domain_handle = domain_handle;
3936 torture_assert_ntstatus_ok(tctx,
3937 dcerpc_samr_SetDomainInfo_r(b, tctx, &r),
3938 "failed to set domain info");
3939 torture_assert_ntstatus_ok(tctx, r.out.result,
3940 "failed to set domain info");
3945 static bool test_SetDomainInfo_ntstatus(struct dcerpc_binding_handle *b,
3946 struct torture_context *tctx,
3947 struct policy_handle *domain_handle,
3948 enum samr_DomainInfoClass level,
3949 union samr_DomainInfo *info,
3952 struct samr_SetDomainInfo r;
3954 r.in.domain_handle = domain_handle;
3958 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &r),
3959 "SetDomainInfo failed");
3960 torture_assert_ntstatus_equal(tctx, r.out.result, expected, "");
3965 static bool test_QueryDomainInfo2_level(struct dcerpc_binding_handle *b,
3966 struct torture_context *tctx,
3967 struct policy_handle *domain_handle,
3968 enum samr_DomainInfoClass level,
3969 union samr_DomainInfo **q_info)
3971 struct samr_QueryDomainInfo2 r;
3973 r.in.domain_handle = domain_handle;
3975 r.out.info = q_info;
3977 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo2_r(b, tctx, &r),
3978 "failed to query domain info");
3979 torture_assert_ntstatus_ok(tctx, r.out.result,
3980 "failed to query domain info");
3985 static bool test_Password_badpwdcount(struct dcerpc_pipe *p,
3986 struct dcerpc_pipe *np,
3987 struct torture_context *tctx,
3988 uint32_t acct_flags,
3989 const char *acct_name,
3990 struct policy_handle *domain_handle,
3991 struct policy_handle *user_handle,
3993 struct cli_credentials *machine_credentials,
3994 const char *comment,
3997 NTSTATUS expected_success_status,
3998 struct samr_DomInfo1 *info1,
3999 struct samr_DomInfo12 *info12)
4001 union samr_DomainInfo info;
4004 uint32_t badpwdcount, tmp;
4005 uint32_t password_history_length = 12;
4006 uint32_t lockout_threshold = 15;
4007 uint32_t lockout_seconds = 5;
4008 uint64_t delta_time_factor = 10 * 1000 * 1000;
4009 struct dcerpc_binding_handle *b = p->binding_handle;
4011 if (torture_setting_bool(tctx, "samba3", false)) {
4012 lockout_seconds = 60;
4015 torture_comment(tctx, "\nTesting bad pwd count with: %s\n", comment);
4017 torture_assert(tctx, password_history_length < lockout_threshold,
4018 "password history length needs to be smaller than account lockout threshold for this test");
4023 info.info1 = *info1;
4024 info.info1.password_history_length = password_history_length;
4025 info.info1.min_password_age = 0;
4027 torture_assert(tctx,
4028 test_SetDomainInfo(b, tctx, domain_handle,
4029 DomainPasswordInformation, &info),
4030 "failed to set password history length and min passwd age");
4032 info.info12 = *info12;
4033 info.info12.lockout_threshold = lockout_threshold;
4035 /* set lockout duration of 5 seconds */
4036 info.info12.lockout_duration = ~(lockout_seconds * delta_time_factor);
4037 info.info12.lockout_window = ~(lockout_seconds * delta_time_factor);
4039 torture_assert(tctx,
4040 test_SetDomainInfo(b, tctx, domain_handle,
4041 DomainLockoutInformation, &info),
4042 "failed to set lockout threshold");
4044 /* reset bad pwd count */
4046 torture_assert(tctx,
4047 test_reset_badpwdcount(p, tctx, user_handle, acct_flags, password), "");
4050 /* enable or disable account */
4052 torture_assert(tctx,
4053 test_SetUserInfo_acct_flags(b, tctx, user_handle,
4054 acct_flags | ACB_DISABLED),
4055 "failed to disable user");
4057 torture_assert(tctx,
4058 test_SetUserInfo_acct_flags(b, tctx, user_handle,
4059 acct_flags & ~ACB_DISABLED),
4060 "failed to enable user");
4064 /* setup password history */
4066 passwords = talloc_array(tctx, char *, password_history_length);
4068 for (i=0; i < password_history_length; i++) {
4070 torture_assert(tctx, test_SetUserPass(p, tctx, user_handle, password),
4071 "failed to set password");
4072 passwords[i] = talloc_strdup(tctx, *password);
4074 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
4075 acct_name, passwords[i],
4076 expected_success_status, interactive)) {
4077 torture_fail(tctx, "failed to auth with latest password");
4080 torture_assert(tctx,
4081 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
4083 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
4087 /* test with wrong password */
4089 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
4090 acct_name, "random_crap",
4091 NT_STATUS_WRONG_PASSWORD, interactive)) {
4092 torture_fail(tctx, "succeeded to authenticate with wrong password");
4095 torture_assert(tctx,
4096 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
4098 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
4101 /* test with latest good password */
4103 if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
4104 passwords[password_history_length-1],
4105 expected_success_status, interactive)) {
4106 torture_fail(tctx, "succeeded to authenticate with wrong password");
4109 torture_assert(tctx,
4110 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
4113 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
4115 /* only enabled accounts get the bad pwd count reset upon
4116 * successful logon */
4117 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
4123 /* test password history */
4125 for (i=0; i < password_history_length; i++) {
4127 torture_comment(tctx, "Testing bad password count behavior with "
4128 "password #%d of #%d\n", i, password_history_length);
4130 /* - network samlogon will succeed auth and not
4131 * increase badpwdcount for 2 last entries
4132 * - interactive samlogon only for the last one */
4134 if (i == password_history_length - 1 ||
4135 (i == password_history_length - 2 && !interactive)) {
4137 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
4138 acct_name, passwords[i],
4139 expected_success_status, interactive)) {
4140 torture_fail(tctx, talloc_asprintf(tctx, "did not successfully to obtain %s for %s login with old password (#%d of #%d in history)",
4141 nt_errstr(expected_success_status),
4142 interactive ? "interactive" : "network", i, password_history_length));
4145 torture_assert(tctx,
4146 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
4149 /* torture_comment(tctx, "expecting bad pwd count to *NOT INCREASE* for pwd history entry %d\n", i); */
4150 torture_assert_int_equal(tctx, badpwdcount, tmp, "unexpected badpwdcount");
4152 /* torture_comment(tctx, "expecting bad pwd count to be 0 for pwd history entry %d\n", i); */
4153 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
4161 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
4162 acct_name, passwords[i],
4163 NT_STATUS_WRONG_PASSWORD, interactive)) {
4164 torture_fail(tctx, talloc_asprintf(tctx, "succeeded to authenticate with old password (#%d of #%d in history)", i, password_history_length));
4167 torture_assert(tctx,
4168 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
4170 /* - network samlogon will fail auth but not increase
4171 * badpwdcount for 3rd last entry
4172 * - interactive samlogon for 3rd and 2nd last entry */
4174 if (i == password_history_length - 3 ||
4175 (i == password_history_length - 2 && interactive)) {
4176 /* torture_comment(tctx, "expecting bad pwd count to *NOT INCREASE * by one for pwd history entry %d\n", i); */
4177 torture_assert_int_equal(tctx, badpwdcount, tmp, "unexpected badpwdcount");
4179 /* torture_comment(tctx, "expecting bad pwd count to increase by one for pwd history entry %d\n", i); */
4180 torture_assert_int_equal(tctx, badpwdcount, tmp + 1, "unexpected badpwdcount");
4189 static bool test_Password_badpwdcount_wrap(struct dcerpc_pipe *p,
4190 struct torture_context *tctx,
4191 uint32_t acct_flags,
4192 const char *acct_name,
4193 struct policy_handle *domain_handle,
4194 struct policy_handle *user_handle,
4196 struct cli_credentials *machine_credentials)
4198 union samr_DomainInfo *q_info, s_info;
4199 struct samr_DomInfo1 info1, _info1;
4200 struct samr_DomInfo12 info12, _info12;
4202 struct dcerpc_binding_handle *b = p->binding_handle;
4203 struct dcerpc_pipe *np;
4207 const char *comment;
4210 NTSTATUS expected_success_status;
4213 .comment = "network logon (disabled account)",
4215 .interactive = false,
4216 .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
4219 .comment = "network logon (enabled account)",
4221 .interactive = false,
4222 .expected_success_status= NT_STATUS_OK
4225 .comment = "interactive logon (disabled account)",
4227 .interactive = true,
4228 .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
4231 .comment = "interactive logon (enabled account)",
4233 .interactive = true,
4234 .expected_success_status= NT_STATUS_OK
4238 torture_assert(tctx, setup_schannel_netlogon_pipe(tctx, machine_credentials, &np), "");
4240 /* backup old policies */
4242 torture_assert(tctx,
4243 test_QueryDomainInfo2_level(b, tctx, domain_handle,
4244 DomainPasswordInformation, &q_info),
4245 "failed to query domain info level 1");
4247 info1 = q_info->info1;
4250 torture_assert(tctx,
4251 test_QueryDomainInfo2_level(b, tctx, domain_handle,
4252 DomainLockoutInformation, &q_info),
4253 "failed to query domain info level 12");
4255 info12 = q_info->info12;
4260 for (i=0; i < ARRAY_SIZE(creds); i++) {
4262 /* skip trust tests for now */
4263 if (acct_flags & ACB_WSTRUST ||
4264 acct_flags & ACB_SVRTRUST ||
4265 acct_flags & ACB_DOMTRUST) {
4269 if (!test_Password_badpwdcount(p, np, tctx, acct_flags, acct_name,
4270 domain_handle, user_handle, password,
4271 machine_credentials,
4274 creds[i].interactive,
4275 creds[i].expected_success_status,
4276 &_info1, &_info12)) {
4277 torture_result(tctx, TORTURE_FAIL, "TEST #%d (%s) failed\n", i, creds[i].comment);
4280 torture_comment(tctx, "TEST #%d (%s) succeeded\n", i, creds[i].comment);
4284 /* restore policies */
4286 s_info.info1 = info1;
4288 torture_assert(tctx,
4289 test_SetDomainInfo(b, tctx, domain_handle,
4290 DomainPasswordInformation, &s_info),
4291 "failed to set password information");
4293 s_info.info12 = info12;
4295 torture_assert(tctx,
4296 test_SetDomainInfo(b, tctx, domain_handle,
4297 DomainLockoutInformation, &s_info),
4298 "failed to set lockout information");
4303 static bool test_QueryUserInfo_lockout(struct dcerpc_binding_handle *b,
4304 struct torture_context *tctx,
4305 struct policy_handle *domain_handle,
4306 const char *acct_name,
4307 uint16_t raw_bad_password_count,
4308 uint16_t effective_bad_password_count,
4309 uint32_t effective_acb_lockout)
4311 struct policy_handle user_handle;
4312 union samr_UserInfo *i;
4313 struct samr_QueryUserInfo r;
4315 NTSTATUS status = test_OpenUser_byname(b, tctx, domain_handle, acct_name, &user_handle);
4316 if (!NT_STATUS_IS_OK(status)) {
4320 r.in.user_handle = &user_handle;
4323 torture_comment(tctx, "Testing QueryUserInfo level %d", r.in.level);
4324 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
4325 "failed to query userinfo");
4326 torture_assert_ntstatus_ok(tctx, r.out.result,
4327 "failed to query userinfo");
4328 torture_comment(tctx, " (acct_flags: 0x%08x) (raw_bad_pwd_count: %u)\n",
4329 i->info3.acct_flags, i->info3.bad_password_count);
4330 torture_assert_int_equal(tctx, i->info3.bad_password_count,
4331 raw_bad_password_count,
4333 torture_assert_int_equal(tctx, i->info3.acct_flags & ACB_AUTOLOCK,
4334 effective_acb_lockout,
4335 "effective acb_lockout");
4338 r.in.user_handle = &user_handle;
4341 torture_comment(tctx, "Testing QueryUserInfo level %d", r.in.level);
4342 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
4343 "failed to query userinfo");
4344 torture_assert_ntstatus_ok(tctx, r.out.result,
4345 "failed to query userinfo");
4346 torture_comment(tctx, " (acct_flags: 0x%08x) (effective_bad_pwd_count: %u)\n",
4347 i->info5.acct_flags, i->info5.bad_password_count);
4348 torture_assert_int_equal(tctx, i->info5.bad_password_count,
4349 effective_bad_password_count,
4350 "effective badpwdcount");
4351 torture_assert_int_equal(tctx, i->info5.acct_flags & ACB_AUTOLOCK,
4352 effective_acb_lockout,
4353 "effective acb_lockout");
4356 r.in.user_handle = &user_handle;
4359 torture_comment(tctx, "Testing QueryUserInfo level %d", r.in.level);
4360 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
4361 "failed to query userinfo");
4362 torture_assert_ntstatus_ok(tctx, r.out.result,
4363 "failed to query userinfo");
4364 torture_comment(tctx, " (acct_flags: 0x%08x)\n",
4365 i->info16.acct_flags);
4366 torture_assert_int_equal(tctx, i->info16.acct_flags & ACB_AUTOLOCK,
4367 effective_acb_lockout,
4368 "effective acb_lockout");
4371 r.in.user_handle = &user_handle;
4374 torture_comment(tctx, "Testing QueryUserInfo level %d", r.in.level);
4375 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
4376 "failed to query userinfo");
4377 torture_assert_ntstatus_ok(tctx, r.out.result,
4378 "failed to query userinfo");
4379 torture_comment(tctx, " (acct_flags: 0x%08x) (effective_bad_pwd_count: %u)\n",
4380 i->info21.acct_flags, i->info21.bad_password_count);
4381 torture_assert_int_equal(tctx, i->info21.bad_password_count,
4382 effective_bad_password_count,
4383 "effective badpwdcount");
4384 torture_assert_int_equal(tctx, i->info21.acct_flags & ACB_AUTOLOCK,
4385 effective_acb_lockout,
4386 "effective acb_lockout");
4389 if (!test_samr_handle_Close(b, tctx, &user_handle)) {
4396 static bool test_Password_lockout(struct dcerpc_pipe *p,
4397 struct dcerpc_pipe *np,
4398 struct torture_context *tctx,
4399 uint32_t acct_flags,
4400 const char *acct_name,
4401 struct policy_handle *domain_handle,
4402 struct policy_handle *user_handle,
4404 struct cli_credentials *machine_credentials,
4405 const char *comment,
4408 uint32_t password_history_length,
4409 NTSTATUS expected_success_status,
4410 struct samr_DomInfo1 *info1,
4411 struct samr_DomInfo12 *info12)
4413 union samr_DomainInfo info;
4414 uint64_t lockout_threshold = 1;
4415 uint32_t lockout_seconds = 5;
4416 uint64_t delta_time_factor = 10 * 1000 * 1000;
4417 struct dcerpc_binding_handle *b = p->binding_handle;
4419 if (torture_setting_bool(tctx, "samba3", false)) {
4420 lockout_seconds = 60;
4423 torture_comment(tctx, "\nTesting account lockout: %s\n", comment);
4427 info.info1 = *info1;
4429 torture_comment(tctx, "setting password history length to %d.\n", password_history_length);
4430 info.info1.password_history_length = password_history_length;
4432 torture_comment(tctx, "setting min password again.\n");
4433 info.info1.min_password_age = 0;
4435 torture_assert(tctx,
4436 test_SetDomainInfo(b, tctx, domain_handle,
4437 DomainPasswordInformation, &info),
4438 "failed to set password history length");
4440 info.info12 = *info12;
4441 info.info12.lockout_threshold = lockout_threshold;
4443 /* set lockout duration < lockout window: should fail */
4444 info.info12.lockout_duration = ~(lockout_seconds * delta_time_factor);
4445 info.info12.lockout_window = ~((lockout_seconds + 1) * delta_time_factor);
4447 torture_assert(tctx,
4448 test_SetDomainInfo_ntstatus(b, tctx, domain_handle,
4449 DomainLockoutInformation, &info,
4450 NT_STATUS_INVALID_PARAMETER),
4451 "setting lockout duration < lockout window gave unexpected result");
4453 info.info12.lockout_duration = 0;
4454 info.info12.lockout_window = 0;
4456 torture_assert(tctx,
4457 test_SetDomainInfo(b, tctx, domain_handle,
4458 DomainLockoutInformation, &info),
4459 "failed to set lockout window and duration to 0");
4462 /* set lockout duration of 5 seconds */
4463 info.info12.lockout_duration = ~(lockout_seconds * delta_time_factor);
4464 info.info12.lockout_window = ~(lockout_seconds * delta_time_factor);
4466 torture_assert(tctx,
4467 test_SetDomainInfo(b, tctx, domain_handle,
4468 DomainLockoutInformation, &info),
4469 "failed to set lockout window and duration to 5 seconds");
4471 /* reset bad pwd count */
4473 torture_assert(tctx,
4474 test_reset_badpwdcount(p, tctx, user_handle, acct_flags, password), "");
4477 /* enable or disable account */
4480 torture_assert(tctx,
4481 test_SetUserInfo_acct_flags(b, tctx, user_handle,
4482 acct_flags | ACB_DISABLED),
4483 "failed to disable user");
4485 torture_assert(tctx,
4486 test_SetUserInfo_acct_flags(b, tctx, user_handle,
4487 acct_flags & ~ACB_DISABLED),
4488 "failed to enable user");
4492 /* test logon with right password */
4494 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
4495 acct_name, *password,
4496 expected_success_status, interactive)) {
4497 torture_fail(tctx, "failed to auth with latest password");
4500 torture_assert(tctx,
4501 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4503 "expected account to not be locked");
4505 /* test with wrong password ==> lockout */
4507 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
4508 acct_name, "random_crap",
4509 NT_STATUS_WRONG_PASSWORD, interactive)) {
4510 torture_fail(tctx, "succeeded to authenticate with wrong password");
4514 * curiously, windows does _not_ return fresh values of
4515 * effective bad_password_count and ACB_AUTOLOCK.
4517 torture_assert(tctx,
4518 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4519 1, 1, ACB_AUTOLOCK),
4520 "expected account to not be locked");
4522 /* test with good password */
4524 if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
4526 NT_STATUS_ACCOUNT_LOCKED_OUT, interactive))
4528 torture_fail(tctx, "authenticate did not return NT_STATUS_ACCOUNT_LOCKED_OUT");
4531 /* bad pwd count should not get updated */
4532 torture_assert(tctx,
4533 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4534 1, 1, ACB_AUTOLOCK),
4535 "expected account to be locked");
4537 torture_assert(tctx,
4538 test_ChangePasswordUser2_ntstatus(p, tctx, acct_name, *password,
4539 NT_STATUS_ACCOUNT_LOCKED_OUT),
4540 "got wrong status from ChangePasswordUser2");
4542 /* bad pwd count should not get updated */
4543 torture_assert(tctx,
4544 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4545 1, 1, ACB_AUTOLOCK),
4546 "expected account to be locked");
4548 torture_assert(tctx,
4549 test_ChangePasswordUser2_ntstatus(p, tctx, acct_name, "random_crap", NT_STATUS_ACCOUNT_LOCKED_OUT),
4550 "got wrong status from ChangePasswordUser2");
4552 /* bad pwd count should not get updated */
4553 torture_assert(tctx,
4554 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4555 1, 1, ACB_AUTOLOCK),
4556 "expected account to be locked");
4558 /* with bad password */
4560 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
4561 acct_name, "random_crap2",
4562 NT_STATUS_ACCOUNT_LOCKED_OUT, interactive))
4564 torture_fail(tctx, "authenticate did not return NT_STATUS_ACCOUNT_LOCKED_OUT");
4567 /* bad pwd count should not get updated */
4568 torture_assert(tctx,
4569 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4570 1, 1, ACB_AUTOLOCK),
4571 "expected account to be locked");
4573 /* let lockout duration expire ==> unlock */
4575 torture_comment(tctx, "let lockout duration expire...\n");
4576 sleep(lockout_seconds + 1);
4578 torture_assert(tctx,
4579 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4581 "expected account to not be locked");
4583 if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
4585 expected_success_status, interactive))
4587 torture_fail(tctx, "failed to authenticate after lockout expired");
4590 if (NT_STATUS_IS_OK(expected_success_status)) {
4591 torture_assert(tctx,
4592 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4594 "expected account to not be locked");
4596 torture_assert(tctx,
4597 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4599 "expected account to not be locked");
4602 torture_assert(tctx,
4603 test_ChangePasswordUser2_ntstatus(p, tctx, acct_name, "random_crap", NT_STATUS_WRONG_PASSWORD),
4604 "got wrong status from ChangePasswordUser2");
4606 torture_assert(tctx,
4607 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4608 1, 1, ACB_AUTOLOCK),
4609 "expected account to be locked");
4611 torture_assert(tctx,
4612 test_ChangePasswordUser2_ntstatus(p, tctx, acct_name, *password, NT_STATUS_ACCOUNT_LOCKED_OUT),
4613 "got wrong status from ChangePasswordUser2");
4615 torture_assert(tctx,
4616 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4617 1, 1, ACB_AUTOLOCK),
4618 "expected account to be locked");
4620 torture_assert(tctx,
4621 test_ChangePasswordUser2_ntstatus(p, tctx, acct_name, "random_crap", NT_STATUS_ACCOUNT_LOCKED_OUT),
4622 "got wrong status from ChangePasswordUser2");
4624 torture_assert(tctx,
4625 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4626 1, 1, ACB_AUTOLOCK),
4627 "expected account to be locked");
4629 /* let lockout duration expire ==> unlock */
4631 torture_comment(tctx, "let lockout duration expire...\n");
4632 sleep(lockout_seconds + 1);
4634 torture_assert(tctx,
4635 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4637 "expected account to not be locked");
4639 if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
4641 expected_success_status, interactive))
4643 torture_fail(tctx, "failed to authenticate after lockout expired");
4646 if (NT_STATUS_IS_OK(expected_success_status)) {
4647 torture_assert(tctx,
4648 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4650 "expected account to not be locked");
4652 torture_assert(tctx,
4653 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4655 "expected account to not be locked");
4658 /* Testing ChangePasswordUser behaviour with 3 attempts */
4659 info.info12.lockout_threshold = 3;
4661 torture_assert(tctx,
4662 test_SetDomainInfo(b, tctx, domain_handle,
4663 DomainLockoutInformation, &info),
4664 "failed to set lockout threshold to 3");
4666 if (NT_STATUS_IS_OK(expected_success_status)) {
4667 torture_assert(tctx,
4668 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4670 "expected account to not be locked");
4672 torture_assert(tctx,
4673 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4675 "expected account to not be locked");
4678 torture_assert(tctx,
4679 test_ChangePasswordUser2_ntstatus(p, tctx, acct_name, "random_crap", NT_STATUS_WRONG_PASSWORD),
4680 "got wrong status from ChangePasswordUser2");
4682 /* bad pwd count will get updated */
4683 torture_assert(tctx,
4684 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4686 "expected account to not be locked");
4688 torture_assert(tctx,
4689 test_ChangePasswordUser2_ntstatus(p, tctx, acct_name, "random_crap", NT_STATUS_WRONG_PASSWORD),
4690 "got wrong status from ChangePasswordUser2");
4692 /* bad pwd count will get updated */
4693 torture_assert(tctx,
4694 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4696 "expected account to not be locked");
4698 torture_assert(tctx,
4699 test_ChangePasswordUser2_ntstatus(p, tctx, acct_name, "random_crap", NT_STATUS_WRONG_PASSWORD),
4700 "got wrong status from ChangePasswordUser2");
4702 /* bad pwd count should get updated */
4703 torture_assert(tctx,
4704 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4705 3, 3, ACB_AUTOLOCK),
4706 "expected account to be locked");
4708 torture_assert(tctx,
4709 test_ChangePasswordUser2_ntstatus(p, tctx, acct_name, *password, NT_STATUS_ACCOUNT_LOCKED_OUT),
4710 "got wrong status from ChangePasswordUser2");
4712 /* bad pwd count should not get updated */
4713 torture_assert(tctx,
4714 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4715 3, 3, ACB_AUTOLOCK),
4716 "expected account to be locked");
4718 /* let lockout duration expire ==> unlock */
4720 torture_comment(tctx, "let lockout duration expire...\n");
4721 sleep(lockout_seconds + 1);
4723 torture_assert(tctx,
4724 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4726 "expected account to not be locked");
4728 torture_assert(tctx,
4729 test_ChangePasswordUser2(p, tctx, acct_name, password, NULL, false),
4730 "got wrong status from ChangePasswordUser2");
4732 torture_assert(tctx,
4733 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4735 "expected account to not be locked");
4737 /* Used to reset the badPwdCount for the other tests */
4738 if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
4740 expected_success_status, interactive))
4742 torture_fail(tctx, "failed to authenticate after lockout expired");
4745 if (NT_STATUS_IS_OK(expected_success_status)) {
4746 torture_assert(tctx,
4747 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4749 "expected account to not be locked");
4751 torture_assert(tctx,
4752 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4754 "expected account to not be locked");
4760 static bool test_Password_lockout_wrap(struct dcerpc_pipe *p,
4761 struct torture_context *tctx,
4762 uint32_t acct_flags,
4763 const char *acct_name,
4764 struct policy_handle *domain_handle,
4765 struct policy_handle *user_handle,
4767 struct cli_credentials *machine_credentials)
4769 union samr_DomainInfo *q_info, s_info;
4770 struct samr_DomInfo1 info1, _info1;
4771 struct samr_DomInfo12 info12, _info12;
4773 struct dcerpc_binding_handle *b = p->binding_handle;
4774 struct dcerpc_pipe *np;
4778 const char *comment;
4781 uint32_t password_history_length;
4782 NTSTATUS expected_success_status;
4785 .comment = "network logon (disabled account)",
4787 .interactive = false,
4788 .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
4791 .comment = "network logon (enabled account)",
4793 .interactive = false,
4794 .expected_success_status= NT_STATUS_OK
4797 .comment = "network logon (enabled account, history len = 1)",
4799 .interactive = false,
4800 .expected_success_status= NT_STATUS_OK,
4801 .password_history_length = 1
4804 .comment = "interactive logon (disabled account)",
4806 .interactive = true,
4807 .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
4810 .comment = "interactive logon (enabled account)",
4812 .interactive = true,
4813 .expected_success_status= NT_STATUS_OK
4816 .comment = "interactive logon (enabled account, history len = 1)",
4818 .interactive = true,
4819 .expected_success_status= NT_STATUS_OK,
4820 .password_history_length = 1
4824 torture_assert(tctx, setup_schannel_netlogon_pipe(tctx, machine_credentials, &np), "");
4826 /* backup old policies */
4828 torture_assert(tctx,
4829 test_QueryDomainInfo2_level(b, tctx, domain_handle,
4830 DomainPasswordInformation, &q_info),
4831 "failed to query domain info level 1");
4833 info1 = q_info->info1;
4836 torture_assert(tctx,
4837 test_QueryDomainInfo2_level(b, tctx, domain_handle,
4838 DomainLockoutInformation, &q_info),
4839 "failed to query domain info level 12");
4841 info12 = q_info->info12;
4846 for (i=0; i < ARRAY_SIZE(creds); i++) {
4848 /* skip trust tests for now */
4849 if (acct_flags & ACB_WSTRUST ||
4850 acct_flags & ACB_SVRTRUST ||
4851 acct_flags & ACB_DOMTRUST) {
4855 test_passed = test_Password_lockout(p, np, tctx, acct_flags, acct_name,
4856 domain_handle, user_handle, password,
4857 machine_credentials,
4860 creds[i].interactive,
4861 creds[i].password_history_length,
4862 creds[i].expected_success_status,
4866 torture_result(tctx, TORTURE_FAIL, "TEST #%d (%s) failed\n", i, creds[i].comment);
4869 torture_comment(tctx, "TEST #%d (%s) succeeded\n", i, creds[i].comment);
4873 /* restore policies */
4875 s_info.info1 = info1;
4877 torture_assert(tctx,
4878 test_SetDomainInfo(b, tctx, domain_handle,
4879 DomainPasswordInformation, &s_info),
4880 "failed to set password information");
4882 s_info.info12 = info12;
4884 torture_assert(tctx,
4885 test_SetDomainInfo(b, tctx, domain_handle,
4886 DomainLockoutInformation, &s_info),
4887 "failed to set lockout information");
4892 static bool test_DeleteUser_with_privs(struct dcerpc_pipe *p,
4893 struct dcerpc_pipe *lp,
4894 struct torture_context *tctx,
4895 struct policy_handle *domain_handle,
4896 struct policy_handle *lsa_handle,
4897 struct policy_handle *user_handle,
4898 const struct dom_sid *domain_sid,
4900 struct cli_credentials *machine_credentials)
4903 struct dcerpc_binding_handle *b = p->binding_handle;
4904 struct dcerpc_binding_handle *lb = lp->binding_handle;
4906 struct policy_handle lsa_acct_handle;
4907 struct dom_sid *user_sid;
4909 user_sid = dom_sid_add_rid(tctx, domain_sid, rid);
4912 struct lsa_EnumAccountRights r;
4913 struct lsa_RightSet rights;
4915 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4917 r.in.handle = lsa_handle;
4918 r.in.sid = user_sid;
4919 r.out.rights = &rights;
4921 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
4922 "lsa_EnumAccountRights failed");
4923 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4924 "Expected enum rights for account to fail");
4928 struct lsa_RightSet rights;
4929 struct lsa_StringLarge names[2];
4930 struct lsa_AddAccountRights r;
4932 torture_comment(tctx, "Testing LSA AddAccountRights\n");
4934 init_lsa_StringLarge(&names[0], "SeMachineAccountPrivilege");
4935 init_lsa_StringLarge(&names[1], NULL);
4938 rights.names = names;
4940 r.in.handle = lsa_handle;
4941 r.in.sid = user_sid;
4942 r.in.rights = &rights;
4944 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_AddAccountRights_r(lb, tctx, &r),
4945 "lsa_AddAccountRights failed");
4946 torture_assert_ntstatus_ok(tctx, r.out.result,
4947 "Failed to add privileges");
4951 struct lsa_RightSet rights;
4952 struct lsa_StringLarge names[2];
4953 struct lsa_AddAccountRights r;
4955 torture_comment(tctx, "Testing LSA AddAccountRights 1\n");
4957 init_lsa_StringLarge(&names[0], "SeInteractiveLogonRight");
4958 init_lsa_StringLarge(&names[1], NULL);
4961 rights.names = names;
4963 r.in.handle = lsa_handle;
4964 r.in.sid = user_sid;
4965 r.in.rights = &rights;
4967 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_AddAccountRights_r(lb, tctx, &r),
4968 "lsa_AddAccountRights 1 failed");
4970 if (torture_setting_bool(tctx, "nt4_dc", false)) {
4972 * The NT4 DC doesn't implement Rights.
4974 torture_assert_ntstatus_equal(tctx, r.out.result,
4975 NT_STATUS_NO_SUCH_PRIVILEGE,
4976 "Add rights failed with incorrect error");
4978 torture_assert_ntstatus_ok(tctx, r.out.result,
4979 "Failed to add rights");
4986 struct lsa_EnumAccounts r;
4987 uint32_t resume_handle = 0;
4988 struct lsa_SidArray lsa_sid_array;
4990 bool found_sid = false;
4992 torture_comment(tctx, "Testing LSA EnumAccounts\n");
4994 r.in.handle = lsa_handle;
4995 r.in.num_entries = 0x1000;
4996 r.in.resume_handle = &resume_handle;
4997 r.out.sids = &lsa_sid_array;
4998 r.out.resume_handle = &resume_handle;
5000 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(lb, tctx, &r),
5001 "lsa_EnumAccounts failed");
5002 torture_assert_ntstatus_ok(tctx, r.out.result,
5003 "Failed to enum accounts");
5005 for (i=0; i < lsa_sid_array.num_sids; i++) {
5006 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
5011 torture_assert(tctx, found_sid,
5012 "failed to list privileged account");
5016 struct lsa_EnumAccountRights r;
5017 struct lsa_RightSet user_rights;
5018 uint32_t expected_count = 2;
5020 if (torture_setting_bool(tctx, "nt4_dc", false)) {
5022 * NT4 DC doesn't store rights.
5027 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
5029 r.in.handle = lsa_handle;
5030 r.in.sid = user_sid;
5031 r.out.rights = &user_rights;
5033 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
5034 "lsa_EnumAccountRights failed");
5035 torture_assert_ntstatus_ok(tctx, r.out.result,
5036 "Failed to enum rights for account");
5038 if (user_rights.count < expected_count) {
5039 torture_result(tctx, TORTURE_FAIL, "failed to find newly added rights");
5045 struct lsa_OpenAccount r;
5047 torture_comment(tctx, "Testing LSA OpenAccount\n");
5049 r.in.handle = lsa_handle;
5050 r.in.sid = user_sid;
5051 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5052 r.out.acct_handle = &lsa_acct_handle;
5054 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenAccount_r(lb, tctx, &r),
5055 "lsa_OpenAccount failed");
5056 torture_assert_ntstatus_ok(tctx, r.out.result,
5057 "Failed to open lsa account");
5061 struct lsa_GetSystemAccessAccount r;
5062 uint32_t access_mask;
5064 torture_comment(tctx, "Testing LSA GetSystemAccessAccount\n");
5066 r.in.handle = &lsa_acct_handle;
5067 r.out.access_mask = &access_mask;
5069 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetSystemAccessAccount_r(lb, tctx, &r),
5070 "lsa_GetSystemAccessAccount failed");
5071 torture_assert_ntstatus_ok(tctx, r.out.result,
5072 "Failed to get lsa system access account");
5078 torture_comment(tctx, "Testing LSA Close\n");
5080 r.in.handle = &lsa_acct_handle;
5081 r.out.handle = &lsa_acct_handle;
5083 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_Close_r(lb, tctx, &r),
5084 "lsa_Close failed");
5085 torture_assert_ntstatus_ok(tctx, r.out.result,
5086 "Failed to close lsa");
5090 struct samr_DeleteUser r;
5092 torture_comment(tctx, "Testing SAMR DeleteUser\n");
5094 r.in.user_handle = user_handle;
5095 r.out.user_handle = user_handle;
5097 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, tctx, &r),
5098 "DeleteUser failed");
5099 torture_assert_ntstatus_ok(tctx, r.out.result,
5100 "DeleteUser failed");
5104 struct lsa_EnumAccounts r;
5105 uint32_t resume_handle = 0;
5106 struct lsa_SidArray lsa_sid_array;
5108 bool found_sid = false;
5110 torture_comment(tctx, "Testing LSA EnumAccounts\n");
5112 r.in.handle = lsa_handle;
5113 r.in.num_entries = 0x1000;
5114 r.in.resume_handle = &resume_handle;
5115 r.out.sids = &lsa_sid_array;
5116 r.out.resume_handle = &resume_handle;
5118 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(lb, tctx, &r),
5119 "lsa_EnumAccounts failed");
5120 torture_assert_ntstatus_ok(tctx, r.out.result,
5121 "Failed to enum accounts");
5123 for (i=0; i < lsa_sid_array.num_sids; i++) {
5124 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
5129 torture_assert(tctx, found_sid,
5130 "failed to list privileged account");
5134 struct lsa_EnumAccountRights r;
5135 struct lsa_RightSet user_rights;
5137 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
5139 r.in.handle = lsa_handle;
5140 r.in.sid = user_sid;
5141 r.out.rights = &user_rights;
5143 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
5144 "lsa_EnumAccountRights failed");
5145 torture_assert_ntstatus_ok(tctx, r.out.result,
5146 "Failed to enum rights for account");
5148 if (user_rights.count < 1) {
5149 torture_result(tctx, TORTURE_FAIL, "failed to find newly added rights");
5155 struct lsa_OpenAccount r;
5157 torture_comment(tctx, "Testing LSA OpenAccount\n");
5159 r.in.handle = lsa_handle;
5160 r.in.sid = user_sid;
5161 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5162 r.out.acct_handle = &lsa_acct_handle;
5164 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenAccount_r(lb, tctx, &r),
5165 "lsa_OpenAccount failed");
5166 torture_assert_ntstatus_ok(tctx, r.out.result,
5167 "Failed to open lsa account");
5171 struct lsa_GetSystemAccessAccount r;
5172 uint32_t access_mask;
5174 torture_comment(tctx, "Testing LSA GetSystemAccessAccount\n");
5176 r.in.handle = &lsa_acct_handle;
5177 r.out.access_mask = &access_mask;
5179 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetSystemAccessAccount_r(lb, tctx, &r),
5180 "lsa_GetSystemAccessAccount failed");
5181 torture_assert_ntstatus_ok(tctx, r.out.result,
5182 "Failed to get lsa system access account");
5186 struct lsa_DeleteObject r;
5188 torture_comment(tctx, "Testing LSA DeleteObject\n");
5190 r.in.handle = &lsa_acct_handle;
5191 r.out.handle = &lsa_acct_handle;
5193 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_DeleteObject_r(lb, tctx, &r),
5194 "lsa_DeleteObject failed");
5195 torture_assert_ntstatus_ok(tctx, r.out.result,
5196 "Failed to delete object");
5200 struct lsa_EnumAccounts r;
5201 uint32_t resume_handle = 0;
5202 struct lsa_SidArray lsa_sid_array;
5204 bool found_sid = false;
5206 torture_comment(tctx, "Testing LSA EnumAccounts\n");
5208 r.in.handle = lsa_handle;
5209 r.in.num_entries = 0x1000;
5210 r.in.resume_handle = &resume_handle;
5211 r.out.sids = &lsa_sid_array;
5212 r.out.resume_handle = &resume_handle;
5214 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(lb, tctx, &r),
5215 "lsa_EnumAccounts failed");
5216 torture_assert_ntstatus_ok(tctx, r.out.result,
5217 "Failed to enum accounts");
5219 for (i=0; i < lsa_sid_array.num_sids; i++) {
5220 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
5225 torture_assert(tctx, !found_sid,
5226 "should not have listed privileged account");
5230 struct lsa_EnumAccountRights r;
5231 struct lsa_RightSet user_rights;
5233 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
5235 r.in.handle = lsa_handle;
5236 r.in.sid = user_sid;
5237 r.out.rights = &user_rights;
5239 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
5240 "lsa_EnumAccountRights failed");
5241 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND,
5242 "Failed to enum rights for account");
5248 static bool test_user_ops(struct dcerpc_pipe *p,
5249 struct torture_context *tctx,
5250 struct policy_handle *user_handle,
5251 struct policy_handle *domain_handle,
5252 const struct dom_sid *domain_sid,
5253 uint32_t base_acct_flags,
5254 const char *base_acct_name, enum torture_samr_choice which_ops,
5255 struct cli_credentials *machine_credentials)
5257 char *password = NULL;
5258 struct samr_QueryUserInfo q;
5259 union samr_UserInfo *info;
5261 struct dcerpc_binding_handle *b = p->binding_handle;
5266 const uint32_t password_fields[] = {
5267 SAMR_FIELD_NT_PASSWORD_PRESENT,
5268 SAMR_FIELD_LM_PASSWORD_PRESENT,
5269 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
5273 status = test_LookupName(b, tctx, domain_handle, base_acct_name, &rid);
5274 if (!NT_STATUS_IS_OK(status)) {
5278 switch (which_ops) {
5279 case TORTURE_SAMR_USER_ATTRIBUTES:
5280 if (!test_QuerySecurity(b, tctx, user_handle)) {
5284 if (!test_QueryUserInfo(b, tctx, user_handle)) {
5288 if (!test_QueryUserInfo2(b, tctx, user_handle)) {
5292 if (!test_SetUserInfo(b, tctx, user_handle, base_acct_flags,
5297 if (!test_GetUserPwInfo(b, tctx, user_handle)) {
5301 if (!test_TestPrivateFunctionsUser(b, tctx, user_handle)) {
5305 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
5309 case TORTURE_SAMR_PASSWORDS:
5310 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
5311 char simple_pass[9];
5312 char *v = generate_random_str(tctx, 1);
5314 ZERO_STRUCT(simple_pass);
5315 memset(simple_pass, *v, sizeof(simple_pass) - 1);
5317 torture_comment(tctx, "Testing machine account password policy rules\n");
5319 /* Workstation trust accounts don't seem to need to honour password quality policy */
5320 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
5324 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
5328 /* reset again, to allow another 'user' password change */
5329 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
5333 /* Try a 'short' password */
5334 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
5338 /* Try a compleatly random password */
5339 if (!test_ChangePasswordRandomBytes(p, tctx, base_acct_name, user_handle, &password)) {
5344 for (i = 0; password_fields[i]; i++) {
5345 if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
5349 /* check it was set right */
5350 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
5355 for (i = 0; password_fields[i]; i++) {
5356 if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
5360 /* check it was set right */
5361 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
5366 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
5370 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
5374 if (!test_SetUserPass_18(p, tctx, user_handle, &password)) {
5378 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
5382 for (i = 0; password_fields[i]; i++) {
5384 if (password_fields[i] == SAMR_FIELD_LM_PASSWORD_PRESENT) {
5385 /* we need to skip as that would break
5386 * the ChangePasswordUser3 verify */
5390 if (!test_SetUserPass_21(p, tctx, user_handle, password_fields[i], &password)) {
5394 /* check it was set right */
5395 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
5400 q.in.user_handle = user_handle;
5404 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
5405 "QueryUserInfo failed");
5406 if (!NT_STATUS_IS_OK(q.out.result)) {
5407 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level %u failed - %s\n",
5408 q.in.level, nt_errstr(q.out.result));
5411 uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
5412 if ((info->info5.acct_flags) != expected_flags) {
5414 if (!torture_setting_bool(tctx, "samba3", false)) {
5415 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
5416 info->info5.acct_flags,
5421 if (info->info5.rid != rid) {
5422 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
5423 info->info5.rid, rid);
5430 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
5432 /* test last password change timestamp behaviour */
5433 torture_assert(tctx, test_SetPassword_pwdlastset(p, tctx, base_acct_flags,
5435 user_handle, &password,
5436 machine_credentials),
5437 "pwdLastSet test failed\n");
5440 case TORTURE_SAMR_PASSWORDS_BADPWDCOUNT:
5442 /* test bad pwd count change behaviour */
5443 torture_assert(tctx, test_Password_badpwdcount_wrap(p, tctx, base_acct_flags,
5446 user_handle, &password,
5447 machine_credentials),
5448 "badPwdCount test failed\n");
5451 case TORTURE_SAMR_PASSWORDS_LOCKOUT:
5453 torture_assert(tctx, test_Password_lockout_wrap(p, tctx, base_acct_flags,
5456 user_handle, &password,
5457 machine_credentials),
5458 "Lockout test failed");
5462 case TORTURE_SAMR_USER_PRIVILEGES: {
5464 struct dcerpc_pipe *lp;
5465 struct policy_handle *lsa_handle;
5466 struct dcerpc_binding_handle *lb;
5468 status = torture_rpc_connection(tctx, &lp, &ndr_table_lsarpc);
5469 torture_assert_ntstatus_ok(tctx, status, "Failed to open LSA pipe");
5470 lb = lp->binding_handle;
5472 if (!test_lsa_OpenPolicy2(lb, tctx, &lsa_handle)) {
5476 if (!test_DeleteUser_with_privs(p, lp, tctx,
5477 domain_handle, lsa_handle, user_handle,
5479 machine_credentials)) {
5483 if (!test_lsa_Close(lb, tctx, lsa_handle)) {
5488 torture_result(tctx, TORTURE_FAIL, "privileged user delete test failed\n");
5493 case TORTURE_SAMR_OTHER:
5494 case TORTURE_SAMR_MANY_ACCOUNTS:
5495 case TORTURE_SAMR_MANY_GROUPS:
5496 case TORTURE_SAMR_MANY_ALIASES:
5497 /* We just need the account to exist */
5503 static bool test_alias_ops(struct dcerpc_binding_handle *b,
5504 struct torture_context *tctx,
5505 struct policy_handle *alias_handle,
5506 const struct dom_sid *domain_sid)
5510 if (!torture_setting_bool(tctx, "samba3", false)) {
5511 if (!test_QuerySecurity(b, tctx, alias_handle)) {
5516 if (!test_QueryAliasInfo(b, tctx, alias_handle)) {
5520 if (!test_SetAliasInfo(b, tctx, alias_handle)) {
5524 if (!test_AddMemberToAlias(b, tctx, alias_handle, domain_sid)) {
5528 if (torture_setting_bool(tctx, "samba3", false) ||
5529 torture_setting_bool(tctx, "samba4", false)) {
5530 torture_comment(tctx, "skipping MultipleMembers Alias tests against Samba\n");
5534 if (!test_AddMultipleMembersToAlias(b, tctx, alias_handle)) {
5542 static bool test_DeleteUser(struct dcerpc_binding_handle *b,
5543 struct torture_context *tctx,
5544 struct policy_handle *user_handle)
5546 struct samr_DeleteUser d;
5547 torture_comment(tctx, "Testing DeleteUser\n");
5549 d.in.user_handle = user_handle;
5550 d.out.user_handle = user_handle;
5552 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, tctx, &d),
5553 "DeleteUser failed");
5554 torture_assert_ntstatus_ok(tctx, d.out.result, "DeleteUser");
5559 bool test_DeleteUser_byname(struct dcerpc_binding_handle *b,
5560 struct torture_context *tctx,
5561 struct policy_handle *handle, const char *name)
5564 struct samr_DeleteUser d;
5565 struct policy_handle user_handle;
5568 status = test_LookupName(b, tctx, handle, name, &rid);
5569 if (!NT_STATUS_IS_OK(status)) {
5573 status = test_OpenUser_byname(b, tctx, handle, name, &user_handle);
5574 if (!NT_STATUS_IS_OK(status)) {
5578 d.in.user_handle = &user_handle;
5579 d.out.user_handle = &user_handle;
5580 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, tctx, &d),
5581 "DeleteUser failed");
5582 if (!NT_STATUS_IS_OK(d.out.result)) {
5583 status = d.out.result;
5590 torture_result(tctx, TORTURE_FAIL, "DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
5595 static bool test_DeleteGroup_byname(struct dcerpc_binding_handle *b,
5596 struct torture_context *tctx,
5597 struct policy_handle *handle, const char *name)
5600 struct samr_OpenGroup r;
5601 struct samr_DeleteDomainGroup d;
5602 struct policy_handle group_handle;
5605 status = test_LookupName(b, tctx, handle, name, &rid);
5606 if (!NT_STATUS_IS_OK(status)) {
5610 r.in.domain_handle = handle;
5611 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5613 r.out.group_handle = &group_handle;
5614 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenGroup_r(b, tctx, &r),
5615 "OpenGroup failed");
5616 if (!NT_STATUS_IS_OK(r.out.result)) {
5617 status = r.out.result;
5621 d.in.group_handle = &group_handle;
5622 d.out.group_handle = &group_handle;
5623 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomainGroup_r(b, tctx, &d),
5624 "DeleteDomainGroup failed");
5625 if (!NT_STATUS_IS_OK(d.out.result)) {
5626 status = d.out.result;
5633 torture_result(tctx, TORTURE_FAIL, "DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
5638 static bool test_DeleteAlias_byname(struct dcerpc_binding_handle *b,
5639 struct torture_context *tctx,
5640 struct policy_handle *domain_handle,
5644 struct samr_OpenAlias r;
5645 struct samr_DeleteDomAlias d;
5646 struct policy_handle alias_handle;
5649 torture_comment(tctx, "Testing DeleteAlias_byname\n");
5651 status = test_LookupName(b, tctx, domain_handle, name, &rid);
5652 if (!NT_STATUS_IS_OK(status)) {
5656 r.in.domain_handle = domain_handle;
5657 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5659 r.out.alias_handle = &alias_handle;
5660 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenAlias_r(b, tctx, &r),
5661 "OpenAlias failed");
5662 if (!NT_STATUS_IS_OK(r.out.result)) {
5663 status = r.out.result;
5667 d.in.alias_handle = &alias_handle;
5668 d.out.alias_handle = &alias_handle;
5669 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomAlias_r(b, tctx, &d),
5670 "DeleteDomAlias failed");
5671 if (!NT_STATUS_IS_OK(d.out.result)) {
5672 status = d.out.result;
5679 torture_result(tctx, TORTURE_FAIL, "DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
5683 static bool test_DeleteAlias(struct dcerpc_binding_handle *b,
5684 struct torture_context *tctx,
5685 struct policy_handle *alias_handle)
5687 struct samr_DeleteDomAlias d;
5690 torture_comment(tctx, "Testing DeleteAlias\n");
5692 d.in.alias_handle = alias_handle;
5693 d.out.alias_handle = alias_handle;
5695 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomAlias_r(b, tctx, &d),
5696 "DeleteDomAlias failed");
5697 if (!NT_STATUS_IS_OK(d.out.result)) {
5698 torture_result(tctx, TORTURE_FAIL, "DeleteAlias failed - %s\n", nt_errstr(d.out.result));
5705 static bool test_CreateAlias(struct dcerpc_binding_handle *b,
5706 struct torture_context *tctx,
5707 struct policy_handle *domain_handle,
5708 const char *alias_name,
5709 struct policy_handle *alias_handle,
5710 const struct dom_sid *domain_sid,
5713 struct samr_CreateDomAlias r;
5714 struct lsa_String name;
5718 init_lsa_String(&name, alias_name);
5719 r.in.domain_handle = domain_handle;
5720 r.in.alias_name = &name;
5721 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5722 r.out.alias_handle = alias_handle;
5725 torture_comment(tctx, "Testing CreateAlias (%s)\n", r.in.alias_name->string);
5727 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomAlias_r(b, tctx, &r),
5728 "CreateDomAlias failed");
5730 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5731 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED)) {
5732 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.alias_name->string);
5735 torture_result(tctx, TORTURE_FAIL, "Server should have refused create of '%s', got %s instead\n", r.in.alias_name->string,
5736 nt_errstr(r.out.result));
5741 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ALIAS_EXISTS)) {
5742 if (!test_DeleteAlias_byname(b, tctx, domain_handle, r.in.alias_name->string)) {
5745 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomAlias_r(b, tctx, &r),
5746 "CreateDomAlias failed");
5749 if (!NT_STATUS_IS_OK(r.out.result)) {
5750 torture_result(tctx, TORTURE_FAIL, "CreateAlias failed - %s\n", nt_errstr(r.out.result));
5758 if (!test_alias_ops(b, tctx, alias_handle, domain_sid)) {
5765 static bool test_ChangePassword(struct dcerpc_pipe *p,
5766 struct torture_context *tctx,
5767 const char *acct_name,
5768 struct policy_handle *domain_handle, char **password)
5771 struct dcerpc_binding_handle *b = p->binding_handle;
5777 if (!test_ChangePasswordUser(b, tctx, acct_name, domain_handle, password)) {
5781 if (!test_ChangePasswordUser2(p, tctx, acct_name, password, 0, true)) {
5785 if (!test_OemChangePasswordUser2(p, tctx, acct_name, domain_handle, password)) {
5789 /* test what happens when setting the old password again */
5790 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, *password, 0, true)) {
5795 char simple_pass[9];
5796 char *v = generate_random_str(tctx, 1);
5798 ZERO_STRUCT(simple_pass);
5799 memset(simple_pass, *v, sizeof(simple_pass) - 1);
5801 /* test what happens when picking a simple password */
5802 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, simple_pass, 0, true)) {
5807 /* set samr_SetDomainInfo level 1 with min_length 5 */
5809 struct samr_QueryDomainInfo r;
5810 union samr_DomainInfo *info = NULL;
5811 struct samr_SetDomainInfo s;
5812 uint16_t len_old, len;
5813 uint32_t pwd_prop_old;
5814 int64_t min_pwd_age_old;
5818 r.in.domain_handle = domain_handle;
5822 torture_comment(tctx, "Testing samr_QueryDomainInfo level 1\n");
5823 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &r),
5824 "QueryDomainInfo failed");
5825 if (!NT_STATUS_IS_OK(r.out.result)) {
5829 s.in.domain_handle = domain_handle;
5833 /* remember the old min length, so we can reset it */
5834 len_old = s.in.info->info1.min_password_length;
5835 s.in.info->info1.min_password_length = len;
5836 pwd_prop_old = s.in.info->info1.password_properties;
5837 /* turn off password complexity checks for this test */
5838 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
5840 min_pwd_age_old = s.in.info->info1.min_password_age;
5841 s.in.info->info1.min_password_age = 0;
5843 torture_comment(tctx, "Testing samr_SetDomainInfo level 1\n");
5844 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
5845 "SetDomainInfo failed");
5846 if (!NT_STATUS_IS_OK(s.out.result)) {
5850 torture_comment(tctx, "calling test_ChangePasswordUser3 with too short password\n");
5852 if (!test_ChangePasswordUser3(p, tctx, acct_name, len - 1, password, NULL, 0, true)) {
5856 s.in.info->info1.min_password_length = len_old;
5857 s.in.info->info1.password_properties = pwd_prop_old;
5858 s.in.info->info1.min_password_age = min_pwd_age_old;
5860 torture_comment(tctx, "Testing samr_SetDomainInfo level 1\n");
5861 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
5862 "SetDomainInfo failed");
5863 if (!NT_STATUS_IS_OK(s.out.result)) {
5870 struct samr_OpenUser r;
5871 struct samr_QueryUserInfo q;
5872 union samr_UserInfo *info;
5873 struct samr_LookupNames n;
5874 struct policy_handle user_handle;
5875 struct samr_Ids rids, types;
5877 n.in.domain_handle = domain_handle;
5879 n.in.names = talloc_array(tctx, struct lsa_String, 1);
5880 n.in.names[0].string = acct_name;
5882 n.out.types = &types;
5884 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupNames_r(b, tctx, &n),
5885 "LookupNames failed");
5886 if (!NT_STATUS_IS_OK(n.out.result)) {
5887 torture_result(tctx, TORTURE_FAIL, "LookupNames failed - %s\n", nt_errstr(n.out.result));
5891 r.in.domain_handle = domain_handle;
5892 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5893 r.in.rid = n.out.rids->ids[0];
5894 r.out.user_handle = &user_handle;
5896 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
5898 if (!NT_STATUS_IS_OK(r.out.result)) {
5899 torture_result(tctx, TORTURE_FAIL, "OpenUser(%u) failed - %s\n", n.out.rids->ids[0], nt_errstr(r.out.result));
5903 q.in.user_handle = &user_handle;
5907 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
5908 "QueryUserInfo failed");
5909 if (!NT_STATUS_IS_OK(q.out.result)) {
5910 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo failed - %s\n", nt_errstr(q.out.result));
5914 torture_comment(tctx, "calling test_ChangePasswordUser3 with too early password change\n");
5916 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL,
5917 info->info5.last_password_change, true)) {
5922 /* we change passwords twice - this has the effect of verifying
5923 they were changed correctly for the final call */
5924 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
5928 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
5935 static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
5936 struct policy_handle *domain_handle,
5937 const char *user_name,
5938 struct policy_handle *user_handle_out,
5939 struct dom_sid *domain_sid,
5940 enum torture_samr_choice which_ops,
5941 struct cli_credentials *machine_credentials,
5945 TALLOC_CTX *user_ctx;
5947 struct samr_CreateUser r;
5948 struct samr_QueryUserInfo q;
5949 union samr_UserInfo *info;
5950 struct samr_DeleteUser d;
5953 /* This call creates a 'normal' account - check that it really does */
5954 const uint32_t acct_flags = ACB_NORMAL;
5955 struct lsa_String name;
5957 struct dcerpc_binding_handle *b = p->binding_handle;
5959 struct policy_handle user_handle;
5960 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
5961 init_lsa_String(&name, user_name);
5963 r.in.domain_handle = domain_handle;
5964 r.in.account_name = &name;
5965 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5966 r.out.user_handle = &user_handle;
5969 torture_comment(tctx, "Testing CreateUser(%s)\n", r.in.account_name->string);
5971 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser_r(b, user_ctx, &r),
5972 "CreateUser failed");
5974 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5975 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
5976 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.account_name->string);
5979 torture_result(tctx, TORTURE_FAIL, "Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
5980 nt_errstr(r.out.result));
5985 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_USER_EXISTS)) {
5986 if (!test_DeleteUser_byname(b, tctx, domain_handle, r.in.account_name->string)) {
5987 talloc_free(user_ctx);
5990 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser_r(b, user_ctx, &r),
5991 "CreateUser failed");
5994 if (!NT_STATUS_IS_OK(r.out.result)) {
5995 talloc_free(user_ctx);
5996 torture_result(tctx, TORTURE_FAIL, "CreateUser failed - %s\n", nt_errstr(r.out.result));
6001 if (user_handle_out) {
6002 *user_handle_out = user_handle;
6008 q.in.user_handle = &user_handle;
6012 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, user_ctx, &q),
6013 "QueryUserInfo failed");
6014 if (!NT_STATUS_IS_OK(q.out.result)) {
6015 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level %u failed - %s\n",
6016 q.in.level, nt_errstr(q.out.result));
6019 if ((info->info16.acct_flags & acct_flags) != acct_flags) {
6020 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
6021 info->info16.acct_flags,
6027 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
6028 domain_sid, acct_flags, name.string, which_ops,
6029 machine_credentials)) {
6033 if (user_handle_out) {
6034 *user_handle_out = user_handle;
6036 torture_comment(tctx, "Testing DeleteUser (createuser test)\n");
6038 d.in.user_handle = &user_handle;
6039 d.out.user_handle = &user_handle;
6041 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, user_ctx, &d),
6042 "DeleteUser failed");
6043 if (!NT_STATUS_IS_OK(d.out.result)) {
6044 torture_result(tctx, TORTURE_FAIL, "DeleteUser failed - %s\n", nt_errstr(d.out.result));
6051 talloc_free(user_ctx);
6057 static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
6058 struct policy_handle *domain_handle,
6059 struct dom_sid *domain_sid,
6060 enum torture_samr_choice which_ops,
6061 struct cli_credentials *machine_credentials)
6063 struct samr_CreateUser2 r;
6064 struct samr_QueryUserInfo q;
6065 union samr_UserInfo *info;
6066 struct samr_DeleteUser d;
6067 struct policy_handle user_handle;
6069 struct lsa_String name;
6072 struct dcerpc_binding_handle *b = p->binding_handle;
6075 uint32_t acct_flags;
6076 const char *account_name;
6078 } account_types[] = {
6079 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
6080 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
6081 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
6082 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
6083 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
6084 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
6085 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
6086 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
6087 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
6088 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_ACCESS_DENIED },
6089 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
6090 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
6091 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
6092 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
6093 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
6096 for (i = 0; account_types[i].account_name; i++) {
6097 TALLOC_CTX *user_ctx;
6098 uint32_t acct_flags = account_types[i].acct_flags;
6099 uint32_t access_granted;
6100 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
6101 init_lsa_String(&name, account_types[i].account_name);
6103 r.in.domain_handle = domain_handle;
6104 r.in.account_name = &name;
6105 r.in.acct_flags = acct_flags;
6106 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6107 r.out.user_handle = &user_handle;
6108 r.out.access_granted = &access_granted;
6111 torture_comment(tctx, "Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
6113 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser2_r(b, user_ctx, &r),
6114 "CreateUser2 failed");
6116 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
6117 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
6118 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.account_name->string);
6121 torture_result(tctx, TORTURE_FAIL, "Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
6122 nt_errstr(r.out.result));
6128 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_USER_EXISTS)) {
6129 if (!test_DeleteUser_byname(b, tctx, domain_handle, r.in.account_name->string)) {
6130 talloc_free(user_ctx);
6134 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser2_r(b, user_ctx, &r),
6135 "CreateUser2 failed");
6138 if (!NT_STATUS_EQUAL(r.out.result, account_types[i].nt_status)) {
6139 torture_result(tctx, TORTURE_FAIL, "CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
6140 nt_errstr(r.out.result), nt_errstr(account_types[i].nt_status));
6144 if (NT_STATUS_IS_OK(r.out.result)) {
6145 q.in.user_handle = &user_handle;
6149 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, user_ctx, &q),
6150 "QueryUserInfo failed");
6151 if (!NT_STATUS_IS_OK(q.out.result)) {
6152 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level %u failed - %s\n",
6153 q.in.level, nt_errstr(q.out.result));
6156 uint32_t expected_flags = (acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
6157 if (acct_flags == ACB_NORMAL) {
6158 expected_flags |= ACB_PW_EXPIRED;
6160 if ((info->info5.acct_flags) != expected_flags) {
6161 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
6162 info->info5.acct_flags,
6166 switch (acct_flags) {
6168 if (info->info5.primary_gid != DOMAIN_RID_DCS) {
6169 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level 5: DC should have had Primary Group %d, got %d\n",
6170 DOMAIN_RID_DCS, info->info5.primary_gid);
6175 if (info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
6176 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
6177 DOMAIN_RID_DOMAIN_MEMBERS, info->info5.primary_gid);
6182 if (info->info5.primary_gid != DOMAIN_RID_USERS) {
6183 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level 5: Users should have had Primary Group %d, got %d\n",
6184 DOMAIN_RID_USERS, info->info5.primary_gid);
6191 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
6192 domain_sid, acct_flags, name.string, which_ops,
6193 machine_credentials)) {
6197 if (!ndr_policy_handle_empty(&user_handle)) {
6198 torture_comment(tctx, "Testing DeleteUser (createuser2 test)\n");
6200 d.in.user_handle = &user_handle;
6201 d.out.user_handle = &user_handle;
6203 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, user_ctx, &d),
6204 "DeleteUser failed");
6205 if (!NT_STATUS_IS_OK(d.out.result)) {
6206 torture_result(tctx, TORTURE_FAIL, "DeleteUser failed - %s\n", nt_errstr(d.out.result));
6211 talloc_free(user_ctx);
6217 static bool test_QueryAliasInfo(struct dcerpc_binding_handle *b,
6218 struct torture_context *tctx,
6219 struct policy_handle *handle)
6221 struct samr_QueryAliasInfo r;
6222 union samr_AliasInfo *info;
6223 uint16_t levels[] = {1, 2, 3};
6227 for (i=0;i<ARRAY_SIZE(levels);i++) {
6228 torture_comment(tctx, "Testing QueryAliasInfo level %u\n", levels[i]);
6230 r.in.alias_handle = handle;
6231 r.in.level = levels[i];
6234 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryAliasInfo_r(b, tctx, &r),
6235 "QueryAliasInfo failed");
6236 if (!NT_STATUS_IS_OK(r.out.result)) {
6237 torture_result(tctx, TORTURE_FAIL, "QueryAliasInfo level %u failed - %s\n",
6238 levels[i], nt_errstr(r.out.result));
6246 static bool test_QueryGroupInfo(struct dcerpc_binding_handle *b,
6247 struct torture_context *tctx,
6248 struct policy_handle *handle)
6250 struct samr_QueryGroupInfo r;
6251 union samr_GroupInfo *info;
6252 uint16_t levels[] = {1, 2, 3, 4, 5};
6256 for (i=0;i<ARRAY_SIZE(levels);i++) {
6257 torture_comment(tctx, "Testing QueryGroupInfo level %u\n", levels[i]);
6259 r.in.group_handle = handle;
6260 r.in.level = levels[i];
6263 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupInfo_r(b, tctx, &r),
6264 "QueryGroupInfo failed");
6265 if (!NT_STATUS_IS_OK(r.out.result)) {
6266 torture_result(tctx, TORTURE_FAIL, "QueryGroupInfo level %u failed - %s\n",
6267 levels[i], nt_errstr(r.out.result));
6275 static bool test_QueryGroupMember(struct dcerpc_binding_handle *b,
6276 struct torture_context *tctx,
6277 struct policy_handle *handle)
6279 struct samr_QueryGroupMember r;
6280 struct samr_RidAttrArray *rids = NULL;
6283 torture_comment(tctx, "Testing QueryGroupMember\n");
6285 r.in.group_handle = handle;
6288 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupMember_r(b, tctx, &r),
6289 "QueryGroupMember failed");
6290 if (!NT_STATUS_IS_OK(r.out.result)) {
6291 torture_result(tctx, TORTURE_FAIL, "QueryGroupMember failed - %s\n", nt_errstr(r.out.result));
6299 static bool test_SetGroupInfo(struct dcerpc_binding_handle *b,
6300 struct torture_context *tctx,
6301 struct policy_handle *handle)
6303 struct samr_QueryGroupInfo r;
6304 union samr_GroupInfo *info;
6305 struct samr_SetGroupInfo s;
6306 uint16_t levels[] = {1, 2, 3, 4};
6307 uint16_t set_ok[] = {0, 1, 1, 1};
6311 for (i=0;i<ARRAY_SIZE(levels);i++) {
6312 torture_comment(tctx, "Testing QueryGroupInfo level %u\n", levels[i]);
6314 r.in.group_handle = handle;
6315 r.in.level = levels[i];
6318 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupInfo_r(b, tctx, &r),
6319 "QueryGroupInfo failed");
6320 if (!NT_STATUS_IS_OK(r.out.result)) {
6321 torture_result(tctx, TORTURE_FAIL, "QueryGroupInfo level %u failed - %s\n",
6322 levels[i], nt_errstr(r.out.result));
6326 torture_comment(tctx, "Testing SetGroupInfo level %u\n", levels[i]);
6328 s.in.group_handle = handle;
6329 s.in.level = levels[i];
6330 s.in.info = *r.out.info;
6333 /* disabled this, as it changes the name only from the point of view of samr,
6334 but leaves the name from the point of view of w2k3 internals (and ldap). This means
6335 the name is still reserved, so creating the old name fails, but deleting by the old name
6337 if (s.in.level == 2) {
6338 init_lsa_String(&s.in.info->string, "NewName");
6342 if (s.in.level == 4) {
6343 init_lsa_String(&s.in.info->description, "test description");
6346 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetGroupInfo_r(b, tctx, &s),
6347 "SetGroupInfo failed");
6349 if (!NT_STATUS_IS_OK(s.out.result)) {
6350 torture_result(tctx, TORTURE_FAIL, "SetGroupInfo level %u failed - %s\n",
6351 r.in.level, nt_errstr(s.out.result));
6356 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, s.out.result)) {
6357 torture_result(tctx, TORTURE_FAIL, "SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
6358 r.in.level, nt_errstr(s.out.result));
6368 static bool test_QueryUserInfo(struct dcerpc_binding_handle *b,
6369 struct torture_context *tctx,
6370 struct policy_handle *handle)
6372 struct samr_QueryUserInfo r;
6373 union samr_UserInfo *info;
6374 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
6375 11, 12, 13, 14, 16, 17, 20, 21};
6379 for (i=0;i<ARRAY_SIZE(levels);i++) {
6380 torture_comment(tctx, "Testing QueryUserInfo level %u\n", levels[i]);
6382 r.in.user_handle = handle;
6383 r.in.level = levels[i];
6386 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
6387 "QueryUserInfo failed");
6388 if (!NT_STATUS_IS_OK(r.out.result)) {
6389 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level %u failed - %s\n",
6390 levels[i], nt_errstr(r.out.result));
6398 static bool test_QueryUserInfo2(struct dcerpc_binding_handle *b,
6399 struct torture_context *tctx,
6400 struct policy_handle *handle)
6402 struct samr_QueryUserInfo2 r;
6403 union samr_UserInfo *info;
6404 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
6405 11, 12, 13, 14, 16, 17, 20, 21};
6409 for (i=0;i<ARRAY_SIZE(levels);i++) {
6410 torture_comment(tctx, "Testing QueryUserInfo2 level %u\n", levels[i]);
6412 r.in.user_handle = handle;
6413 r.in.level = levels[i];
6416 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo2_r(b, tctx, &r),
6417 "QueryUserInfo2 failed");
6418 if (!NT_STATUS_IS_OK(r.out.result)) {
6419 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo2 level %u failed - %s\n",
6420 levels[i], nt_errstr(r.out.result));
6428 static bool test_OpenUser(struct dcerpc_binding_handle *b,
6429 struct torture_context *tctx,
6430 struct policy_handle *handle, uint32_t rid)
6432 struct samr_OpenUser r;
6433 struct policy_handle user_handle;
6436 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
6438 r.in.domain_handle = handle;
6439 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6441 r.out.user_handle = &user_handle;
6443 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
6445 if (!NT_STATUS_IS_OK(r.out.result)) {
6446 torture_result(tctx, TORTURE_FAIL, "OpenUser(%u) failed - %s\n", rid, nt_errstr(r.out.result));
6450 if (!test_QuerySecurity(b, tctx, &user_handle)) {
6454 if (!test_QueryUserInfo(b, tctx, &user_handle)) {
6458 if (!test_QueryUserInfo2(b, tctx, &user_handle)) {
6462 if (!test_GetUserPwInfo(b, tctx, &user_handle)) {
6466 if (!test_GetGroupsForUser(b, tctx, &user_handle)) {
6470 if (!test_samr_handle_Close(b, tctx, &user_handle)) {
6477 static bool test_OpenGroup(struct dcerpc_binding_handle *b,
6478 struct torture_context *tctx,
6479 struct policy_handle *handle, uint32_t rid)
6481 struct samr_OpenGroup r;
6482 struct policy_handle group_handle;
6485 torture_comment(tctx, "Testing OpenGroup(%u)\n", rid);
6487 r.in.domain_handle = handle;
6488 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6490 r.out.group_handle = &group_handle;
6492 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenGroup_r(b, tctx, &r),
6493 "OpenGroup failed");
6494 if (!NT_STATUS_IS_OK(r.out.result)) {
6495 torture_result(tctx, TORTURE_FAIL, "OpenGroup(%u) failed - %s\n", rid, nt_errstr(r.out.result));
6499 if (!torture_setting_bool(tctx, "samba3", false)) {
6500 if (!test_QuerySecurity(b, tctx, &group_handle)) {
6505 if (!test_QueryGroupInfo(b, tctx, &group_handle)) {
6509 if (!test_QueryGroupMember(b, tctx, &group_handle)) {
6513 if (!test_samr_handle_Close(b, tctx, &group_handle)) {
6520 static bool test_OpenAlias(struct dcerpc_binding_handle *b,
6521 struct torture_context *tctx,
6522 struct policy_handle *handle, uint32_t rid)
6524 struct samr_OpenAlias r;
6525 struct policy_handle alias_handle;
6528 torture_comment(tctx, "Testing OpenAlias(%u)\n", rid);
6530 r.in.domain_handle = handle;
6531 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6533 r.out.alias_handle = &alias_handle;
6535 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenAlias_r(b, tctx, &r),
6536 "OpenAlias failed");
6537 if (!NT_STATUS_IS_OK(r.out.result)) {
6538 torture_result(tctx, TORTURE_FAIL, "OpenAlias(%u) failed - %s\n", rid, nt_errstr(r.out.result));
6542 if (!torture_setting_bool(tctx, "samba3", false)) {
6543 if (!test_QuerySecurity(b, tctx, &alias_handle)) {
6548 if (!test_QueryAliasInfo(b, tctx, &alias_handle)) {
6552 if (!test_GetMembersInAlias(b, tctx, &alias_handle)) {
6556 if (!test_samr_handle_Close(b, tctx, &alias_handle)) {
6563 static bool check_mask(struct dcerpc_binding_handle *b,
6564 struct torture_context *tctx,
6565 struct policy_handle *handle, uint32_t rid,
6566 uint32_t acct_flag_mask)
6568 struct samr_OpenUser r;
6569 struct samr_QueryUserInfo q;
6570 union samr_UserInfo *info;
6571 struct policy_handle user_handle;
6574 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
6576 r.in.domain_handle = handle;
6577 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6579 r.out.user_handle = &user_handle;
6581 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
6583 if (!NT_STATUS_IS_OK(r.out.result)) {
6584 torture_result(tctx, TORTURE_FAIL, "OpenUser(%u) failed - %s\n", rid, nt_errstr(r.out.result));
6588 q.in.user_handle = &user_handle;
6592 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
6593 "QueryUserInfo failed");
6594 if (!NT_STATUS_IS_OK(q.out.result)) {
6595 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level 16 failed - %s\n",
6596 nt_errstr(q.out.result));
6599 if ((acct_flag_mask & info->info16.acct_flags) == 0) {
6600 torture_result(tctx, TORTURE_FAIL, "Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
6601 acct_flag_mask, info->info16.acct_flags, rid);
6606 if (!test_samr_handle_Close(b, tctx, &user_handle)) {
6613 static bool test_EnumDomainUsers_all(struct dcerpc_binding_handle *b,
6614 struct torture_context *tctx,
6615 struct policy_handle *handle)
6617 struct samr_EnumDomainUsers r;
6618 uint32_t mask, resume_handle=0;
6621 struct samr_LookupNames n;
6622 struct samr_LookupRids lr ;
6623 struct lsa_Strings names;
6624 struct samr_Ids rids, types;
6625 struct samr_SamArray *sam = NULL;
6626 uint32_t num_entries = 0;
6628 uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
6629 ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
6630 ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
6633 torture_comment(tctx, "Testing EnumDomainUsers\n");
6635 for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
6636 r.in.domain_handle = handle;
6637 r.in.resume_handle = &resume_handle;
6638 r.in.acct_flags = mask = masks[mask_idx];
6639 r.in.max_size = (uint32_t)-1;
6640 r.out.resume_handle = &resume_handle;
6641 r.out.num_entries = &num_entries;
6644 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainUsers_r(b, tctx, &r),
6645 "EnumDomainUsers failed");
6646 if (!NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) &&
6647 !NT_STATUS_IS_OK(r.out.result)) {
6648 torture_result(tctx, TORTURE_FAIL, "EnumDomainUsers failed - %s\n", nt_errstr(r.out.result));
6652 torture_assert(tctx, sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
6654 if (sam->count == 0) {
6658 for (i=0;i<sam->count;i++) {
6660 if (!check_mask(b, tctx, handle, sam->entries[i].idx, mask)) {
6663 } else if (!test_OpenUser(b, tctx, handle, sam->entries[i].idx)) {
6669 torture_comment(tctx, "Testing LookupNames\n");
6670 n.in.domain_handle = handle;
6671 n.in.num_names = sam->count;
6672 n.in.names = talloc_array(tctx, struct lsa_String, sam->count);
6674 n.out.types = &types;
6675 for (i=0;i<sam->count;i++) {
6676 n.in.names[i].string = sam->entries[i].name.string;
6678 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupNames_r(b, tctx, &n),
6679 "LookupNames failed");
6680 if (!NT_STATUS_IS_OK(n.out.result)) {
6681 torture_result(tctx, TORTURE_FAIL, "LookupNames failed - %s\n", nt_errstr(n.out.result));
6686 torture_comment(tctx, "Testing LookupRids\n");
6687 lr.in.domain_handle = handle;
6688 lr.in.num_rids = sam->count;
6689 lr.in.rids = talloc_array(tctx, uint32_t, sam->count);
6690 lr.out.names = &names;
6691 lr.out.types = &types;
6692 for (i=0;i<sam->count;i++) {
6693 lr.in.rids[i] = sam->entries[i].idx;
6695 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupRids_r(b, tctx, &lr),
6696 "LookupRids failed");
6697 torture_assert_ntstatus_ok(tctx, lr.out.result, "LookupRids");
6703 try blasting the server with a bunch of sync requests
6705 static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, struct torture_context *tctx,
6706 struct policy_handle *handle)
6708 struct samr_EnumDomainUsers r;
6709 uint32_t resume_handle=0;
6711 #define ASYNC_COUNT 100
6712 struct tevent_req *req[ASYNC_COUNT];
6714 if (!torture_setting_bool(tctx, "dangerous", false)) {
6715 torture_skip(tctx, "samr async test disabled - enable dangerous tests to use\n");
6718 torture_comment(tctx, "Testing EnumDomainUsers_async\n");
6720 r.in.domain_handle = handle;
6721 r.in.resume_handle = &resume_handle;
6722 r.in.acct_flags = 0;
6723 r.in.max_size = (uint32_t)-1;
6724 r.out.resume_handle = &resume_handle;
6726 for (i=0;i<ASYNC_COUNT;i++) {
6727 req[i] = dcerpc_samr_EnumDomainUsers_r_send(tctx, tctx->ev, p->binding_handle, &r);
6730 for (i=0;i<ASYNC_COUNT;i++) {
6731 tevent_req_poll(req[i], tctx->ev);
6732 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainUsers_r_recv(req[i], tctx),
6733 talloc_asprintf(tctx, "EnumDomainUsers[%d] failed - %s\n",
6734 i, nt_errstr(r.out.result)));
6737 torture_comment(tctx, "%d async requests OK\n", i);
6742 static bool test_EnumDomainGroups_all(struct dcerpc_binding_handle *b,
6743 struct torture_context *tctx,
6744 struct policy_handle *handle)
6746 struct samr_EnumDomainGroups r;
6747 uint32_t resume_handle=0;
6748 struct samr_SamArray *sam = NULL;
6749 uint32_t num_entries = 0;
6752 bool universal_group_found = false;
6754 torture_comment(tctx, "Testing EnumDomainGroups\n");
6756 r.in.domain_handle = handle;
6757 r.in.resume_handle = &resume_handle;
6758 r.in.max_size = (uint32_t)-1;
6759 r.out.resume_handle = &resume_handle;
6760 r.out.num_entries = &num_entries;
6763 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainGroups_r(b, tctx, &r),
6764 "EnumDomainGroups failed");
6765 if (!NT_STATUS_IS_OK(r.out.result)) {
6766 torture_result(tctx, TORTURE_FAIL, "EnumDomainGroups failed - %s\n", nt_errstr(r.out.result));
6774 for (i=0;i<sam->count;i++) {
6775 if (!test_OpenGroup(b, tctx, handle, sam->entries[i].idx)) {
6778 if ((ret == true) && (strcasecmp(sam->entries[i].name.string,
6779 "Enterprise Admins") == 0)) {
6780 universal_group_found = true;
6784 /* when we are running this on s4 we should get back at least the
6785 * "Enterprise Admins" universal group. If we don't get a group entry
6786 * at all we probably are performing the test on the builtin domain.
6787 * So ignore this case. */
6788 if (torture_setting_bool(tctx, "samba4", false)) {
6789 if ((sam->count > 0) && (!universal_group_found)) {
6797 static bool test_EnumDomainAliases_all(struct dcerpc_binding_handle *b,
6798 struct torture_context *tctx,
6799 struct policy_handle *handle)
6801 struct samr_EnumDomainAliases r;
6802 uint32_t resume_handle=0;
6803 struct samr_SamArray *sam = NULL;
6804 uint32_t num_entries = 0;
6808 torture_comment(tctx, "Testing EnumDomainAliases\n");
6810 r.in.domain_handle = handle;
6811 r.in.resume_handle = &resume_handle;
6812 r.in.max_size = (uint32_t)-1;
6814 r.out.num_entries = &num_entries;
6815 r.out.resume_handle = &resume_handle;
6817 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainAliases_r(b, tctx, &r),
6818 "EnumDomainAliases failed");
6819 if (!NT_STATUS_IS_OK(r.out.result)) {
6820 torture_result(tctx, TORTURE_FAIL, "EnumDomainAliases failed - %s\n", nt_errstr(r.out.result));
6828 for (i=0;i<sam->count;i++) {
6829 if (!test_OpenAlias(b, tctx, handle, sam->entries[i].idx)) {
6837 static bool test_GetDisplayEnumerationIndex(struct dcerpc_binding_handle *b,
6838 struct torture_context *tctx,
6839 struct policy_handle *handle)
6841 struct samr_GetDisplayEnumerationIndex r;
6843 uint16_t levels[] = {1, 2, 3, 4, 5};
6844 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
6845 struct lsa_String name;
6849 for (i=0;i<ARRAY_SIZE(levels);i++) {
6850 torture_comment(tctx, "Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
6852 init_lsa_String(&name, TEST_ACCOUNT_NAME);
6854 r.in.domain_handle = handle;
6855 r.in.level = levels[i];
6859 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex_r(b, tctx, &r),
6860 "GetDisplayEnumerationIndex failed");
6863 !NT_STATUS_IS_OK(r.out.result) &&
6864 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
6865 torture_result(tctx, TORTURE_FAIL, "GetDisplayEnumerationIndex level %u failed - %s\n",
6866 levels[i], nt_errstr(r.out.result));
6870 init_lsa_String(&name, "zzzzzzzz");
6872 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex_r(b, tctx, &r),
6873 "GetDisplayEnumerationIndex failed");
6875 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
6876 torture_result(tctx, TORTURE_FAIL, "GetDisplayEnumerationIndex level %u failed - %s\n",
6877 levels[i], nt_errstr(r.out.result));
6885 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_binding_handle *b,
6886 struct torture_context *tctx,
6887 struct policy_handle *handle)
6889 struct samr_GetDisplayEnumerationIndex2 r;
6891 uint16_t levels[] = {1, 2, 3, 4, 5};
6892 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
6893 struct lsa_String name;
6897 for (i=0;i<ARRAY_SIZE(levels);i++) {
6898 torture_comment(tctx, "Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
6900 init_lsa_String(&name, TEST_ACCOUNT_NAME);
6902 r.in.domain_handle = handle;
6903 r.in.level = levels[i];
6907 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex2_r(b, tctx, &r),
6908 "GetDisplayEnumerationIndex2 failed");
6910 !NT_STATUS_IS_OK(r.out.result) &&
6911 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
6912 torture_result(tctx, TORTURE_FAIL, "GetDisplayEnumerationIndex2 level %u failed - %s\n",
6913 levels[i], nt_errstr(r.out.result));
6917 init_lsa_String(&name, "zzzzzzzz");
6919 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex2_r(b, tctx, &r),
6920 "GetDisplayEnumerationIndex2 failed");
6921 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
6922 torture_result(tctx, TORTURE_FAIL, "GetDisplayEnumerationIndex2 level %u failed - %s\n",
6923 levels[i], nt_errstr(r.out.result));
6931 #define STRING_EQUAL_QUERY(s1, s2, user) \
6932 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
6933 /* odd, but valid */ \
6934 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
6935 torture_result(tctx, TORTURE_FAIL, "%s mismatch for %s: %s != %s (%s)\n", \
6936 #s1, user.string, s1.string, s2.string, __location__); \
6939 #define INT_EQUAL_QUERY(s1, s2, user) \
6941 torture_result(tctx, TORTURE_FAIL, "%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
6942 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
6946 static bool test_each_DisplayInfo_user(struct dcerpc_binding_handle *b,
6947 struct torture_context *tctx,
6948 struct samr_QueryDisplayInfo *querydisplayinfo,
6949 bool *seen_testuser)
6951 struct samr_OpenUser r;
6952 struct samr_QueryUserInfo q;
6953 union samr_UserInfo *info;
6954 struct policy_handle user_handle;
6956 r.in.domain_handle = querydisplayinfo->in.domain_handle;
6957 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6958 for (i = 0; ; i++) {
6959 switch (querydisplayinfo->in.level) {
6961 if (i >= querydisplayinfo->out.info->info1.count) {
6964 r.in.rid = querydisplayinfo->out.info->info1.entries[i].rid;
6967 if (i >= querydisplayinfo->out.info->info2.count) {
6970 r.in.rid = querydisplayinfo->out.info->info2.entries[i].rid;
6976 /* Not interested in validating just the account name */
6980 r.out.user_handle = &user_handle;
6982 switch (querydisplayinfo->in.level) {
6985 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
6987 if (!NT_STATUS_IS_OK(r.out.result)) {
6988 torture_result(tctx, TORTURE_FAIL, "OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(r.out.result));
6993 q.in.user_handle = &user_handle;
6996 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
6997 "QueryUserInfo failed");
6998 if (!NT_STATUS_IS_OK(r.out.result)) {
6999 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(r.out.result));
7003 switch (querydisplayinfo->in.level) {
7005 if (seen_testuser && strcmp(info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
7006 *seen_testuser = true;
7008 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].full_name,
7009 info->info21.full_name, info->info21.account_name);
7010 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].account_name,
7011 info->info21.account_name, info->info21.account_name);
7012 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].description,
7013 info->info21.description, info->info21.account_name);
7014 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].rid,
7015 info->info21.rid, info->info21.account_name);
7016 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].acct_flags,
7017 info->info21.acct_flags, info->info21.account_name);
7021 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].account_name,
7022 info->info21.account_name, info->info21.account_name);
7023 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].description,
7024 info->info21.description, info->info21.account_name);
7025 INT_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].rid,
7026 info->info21.rid, info->info21.account_name);
7027 INT_EQUAL_QUERY((querydisplayinfo->out.info->info2.entries[i].acct_flags & ~ACB_NORMAL),
7028 info->info21.acct_flags, info->info21.account_name);
7030 if (!(querydisplayinfo->out.info->info2.entries[i].acct_flags & ACB_NORMAL)) {
7031 torture_result(tctx, TORTURE_FAIL, "Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
7032 info->info21.account_name.string);
7035 if (!(info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
7036 torture_result(tctx, TORTURE_FAIL, "Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
7037 info->info21.account_name.string,
7038 querydisplayinfo->out.info->info2.entries[i].acct_flags,
7039 info->info21.acct_flags);
7046 if (!test_samr_handle_Close(b, tctx, &user_handle)) {
7053 static bool test_QueryDisplayInfo(struct dcerpc_binding_handle *b,
7054 struct torture_context *tctx,
7055 struct policy_handle *handle)
7057 struct samr_QueryDisplayInfo r;
7058 struct samr_QueryDomainInfo dom_info;
7059 union samr_DomainInfo *info = NULL;
7061 uint16_t levels[] = {1, 2, 3, 4, 5};
7063 bool seen_testuser = false;
7064 uint32_t total_size;
7065 uint32_t returned_size;
7066 union samr_DispInfo disp_info;
7069 for (i=0;i<ARRAY_SIZE(levels);i++) {
7070 torture_comment(tctx, "Testing QueryDisplayInfo level %u\n", levels[i]);
7073 r.out.result = STATUS_MORE_ENTRIES;
7074 while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES)) {
7075 r.in.domain_handle = handle;
7076 r.in.level = levels[i];
7077 r.in.max_entries = 2;
7078 r.in.buf_size = (uint32_t)-1;
7079 r.out.total_size = &total_size;
7080 r.out.returned_size = &returned_size;
7081 r.out.info = &disp_info;
7083 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &r),
7084 "QueryDisplayInfo failed");
7085 if (!NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(r.out.result)) {
7086 torture_result(tctx, TORTURE_FAIL, "QueryDisplayInfo level %u failed - %s\n",
7087 levels[i], nt_errstr(r.out.result));
7090 switch (r.in.level) {
7092 if (!test_each_DisplayInfo_user(b, tctx, &r, &seen_testuser)) {
7095 r.in.start_idx += r.out.info->info1.count;
7098 if (!test_each_DisplayInfo_user(b, tctx, &r, NULL)) {
7101 r.in.start_idx += r.out.info->info2.count;
7104 r.in.start_idx += r.out.info->info3.count;
7107 r.in.start_idx += r.out.info->info4.count;
7110 r.in.start_idx += r.out.info->info5.count;
7114 dom_info.in.domain_handle = handle;
7115 dom_info.in.level = 2;
7116 dom_info.out.info = &info;
7118 /* Check number of users returned is correct */
7119 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &dom_info),
7120 "QueryDomainInfo failed");
7121 if (!NT_STATUS_IS_OK(dom_info.out.result)) {
7122 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo level %u failed - %s\n",
7123 r.in.level, nt_errstr(dom_info.out.result));
7127 switch (r.in.level) {
7130 if (info->general.num_users < r.in.start_idx) {
7131 /* On AD deployments this numbers don't match
7132 * since QueryDisplayInfo returns universal and
7133 * global groups, QueryDomainInfo only global
7135 if (torture_setting_bool(tctx, "samba3", false)) {
7136 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
7137 r.in.start_idx, info->general.num_groups,
7138 info->general.domain_name.string);
7142 if (!seen_testuser) {
7143 struct policy_handle user_handle;
7144 if (NT_STATUS_IS_OK(test_OpenUser_byname(b, tctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
7145 torture_result(tctx, TORTURE_FAIL, "Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
7146 info->general.domain_name.string);
7148 test_samr_handle_Close(b, tctx, &user_handle);
7154 if (info->general.num_groups != r.in.start_idx) {
7155 /* On AD deployments this numbers don't match
7156 * since QueryDisplayInfo returns universal and
7157 * global groups, QueryDomainInfo only global
7159 if (torture_setting_bool(tctx, "samba3", false)) {
7160 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
7161 r.in.start_idx, info->general.num_groups,
7162 info->general.domain_name.string);
7175 static bool test_QueryDisplayInfo2(struct dcerpc_binding_handle *b,
7176 struct torture_context *tctx,
7177 struct policy_handle *handle)
7179 struct samr_QueryDisplayInfo2 r;
7181 uint16_t levels[] = {1, 2, 3, 4, 5};
7183 uint32_t total_size;
7184 uint32_t returned_size;
7185 union samr_DispInfo info;
7187 for (i=0;i<ARRAY_SIZE(levels);i++) {
7188 torture_comment(tctx, "Testing QueryDisplayInfo2 level %u\n", levels[i]);
7190 r.in.domain_handle = handle;
7191 r.in.level = levels[i];
7193 r.in.max_entries = 1000;
7194 r.in.buf_size = (uint32_t)-1;
7195 r.out.total_size = &total_size;
7196 r.out.returned_size = &returned_size;
7199 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo2_r(b, tctx, &r),
7200 "QueryDisplayInfo2 failed");
7201 if (!NT_STATUS_IS_OK(r.out.result)) {
7202 torture_result(tctx, TORTURE_FAIL, "QueryDisplayInfo2 level %u failed - %s\n",
7203 levels[i], nt_errstr(r.out.result));
7211 static bool test_QueryDisplayInfo3(struct dcerpc_binding_handle *b,
7212 struct torture_context *tctx,
7213 struct policy_handle *handle)
7215 struct samr_QueryDisplayInfo3 r;
7217 uint16_t levels[] = {1, 2, 3, 4, 5};
7219 uint32_t total_size;
7220 uint32_t returned_size;
7221 union samr_DispInfo info;
7223 for (i=0;i<ARRAY_SIZE(levels);i++) {
7224 torture_comment(tctx, "Testing QueryDisplayInfo3 level %u\n", levels[i]);
7226 r.in.domain_handle = handle;
7227 r.in.level = levels[i];
7229 r.in.max_entries = 1000;
7230 r.in.buf_size = (uint32_t)-1;
7231 r.out.total_size = &total_size;
7232 r.out.returned_size = &returned_size;
7235 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo3_r(b, tctx, &r),
7236 "QueryDisplayInfo3 failed");
7237 if (!NT_STATUS_IS_OK(r.out.result)) {
7238 torture_result(tctx, TORTURE_FAIL, "QueryDisplayInfo3 level %u failed - %s\n",
7239 levels[i], nt_errstr(r.out.result));
7248 static bool test_QueryDisplayInfo_continue(struct dcerpc_binding_handle *b,
7249 struct torture_context *tctx,
7250 struct policy_handle *handle)
7252 struct samr_QueryDisplayInfo r;
7254 uint32_t total_size;
7255 uint32_t returned_size;
7256 union samr_DispInfo info;
7258 torture_comment(tctx, "Testing QueryDisplayInfo continuation\n");
7260 r.in.domain_handle = handle;
7263 r.in.max_entries = 1;
7264 r.in.buf_size = (uint32_t)-1;
7265 r.out.total_size = &total_size;
7266 r.out.returned_size = &returned_size;
7270 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &r),
7271 "QueryDisplayInfo failed");
7272 if (NT_STATUS_IS_OK(r.out.result) && *r.out.returned_size != 0) {
7273 if (r.out.info->info1.entries[0].idx != r.in.start_idx + 1) {
7274 torture_result(tctx, TORTURE_FAIL, "expected idx %d but got %d\n",
7276 r.out.info->info1.entries[0].idx);
7280 if (!NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) &&
7281 !NT_STATUS_IS_OK(r.out.result)) {
7282 torture_result(tctx, TORTURE_FAIL, "QueryDisplayInfo level %u failed - %s\n",
7283 r.in.level, nt_errstr(r.out.result));
7288 } while ((NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) ||
7289 NT_STATUS_IS_OK(r.out.result)) &&
7290 *r.out.returned_size != 0);
7295 static bool test_QueryDomainInfo(struct dcerpc_pipe *p,
7296 struct torture_context *tctx,
7297 struct policy_handle *handle)
7299 struct samr_QueryDomainInfo r;
7300 union samr_DomainInfo *info = NULL;
7301 struct samr_SetDomainInfo s;
7302 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
7303 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
7306 struct dcerpc_binding_handle *b = p->binding_handle;
7307 const char *domain_comment = talloc_asprintf(tctx,
7308 "Tortured by Samba4 RPC-SAMR: %s",
7309 timestring(tctx, time(NULL)));
7311 s.in.domain_handle = handle;
7313 s.in.info = talloc(tctx, union samr_DomainInfo);
7315 s.in.info->oem.oem_information.string = domain_comment;
7316 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
7317 "SetDomainInfo failed");
7318 if (!NT_STATUS_IS_OK(s.out.result)) {
7319 torture_result(tctx, TORTURE_FAIL, "SetDomainInfo level %u (set comment) failed - %s\n",
7320 s.in.level, nt_errstr(s.out.result));
7324 for (i=0;i<ARRAY_SIZE(levels);i++) {
7325 torture_comment(tctx, "Testing QueryDomainInfo level %u\n", levels[i]);
7327 r.in.domain_handle = handle;
7328 r.in.level = levels[i];
7331 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &r),
7332 "QueryDomainInfo failed");
7333 if (!NT_STATUS_IS_OK(r.out.result)) {
7334 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo level %u failed - %s\n",
7335 r.in.level, nt_errstr(r.out.result));
7340 switch (levels[i]) {
7342 if (strcmp(info->general.oem_information.string, domain_comment) != 0) {
7343 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
7344 levels[i], info->general.oem_information.string, domain_comment);
7345 if (!torture_setting_bool(tctx, "samba3", false)) {
7349 if (!info->general.primary.string) {
7350 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo level %u returned no PDC name\n",
7353 } else if (info->general.role == SAMR_ROLE_DOMAIN_PDC) {
7354 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), info->general.primary.string) != 0) {
7355 if (torture_setting_bool(tctx, "samba3", false)) {
7356 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",
7357 levels[i], info->general.primary.string, dcerpc_server_name(p));
7363 if (strcmp(info->oem.oem_information.string, domain_comment) != 0) {
7364 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
7365 levels[i], info->oem.oem_information.string, domain_comment);
7366 if (!torture_setting_bool(tctx, "samba3", false)) {
7372 if (!info->info6.primary.string) {
7373 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo level %u returned no PDC name\n",
7379 if (strcmp(info->general2.general.oem_information.string, domain_comment) != 0) {
7380 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
7381 levels[i], info->general2.general.oem_information.string, domain_comment);
7382 if (!torture_setting_bool(tctx, "samba3", false)) {
7389 torture_comment(tctx, "Testing SetDomainInfo level %u\n", levels[i]);
7391 s.in.domain_handle = handle;
7392 s.in.level = levels[i];
7395 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
7396 "SetDomainInfo failed");
7398 if (!NT_STATUS_IS_OK(s.out.result)) {
7399 torture_result(tctx, TORTURE_FAIL, "SetDomainInfo level %u failed - %s\n",
7400 r.in.level, nt_errstr(s.out.result));
7405 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, s.out.result)) {
7406 torture_result(tctx, TORTURE_FAIL, "SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
7407 r.in.level, nt_errstr(s.out.result));
7413 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &r),
7414 "QueryDomainInfo failed");
7415 if (!NT_STATUS_IS_OK(r.out.result)) {
7416 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo level %u failed - %s\n",
7417 r.in.level, nt_errstr(r.out.result));
7427 static bool test_QueryDomainInfo2(struct dcerpc_binding_handle *b,
7428 struct torture_context *tctx,
7429 struct policy_handle *handle)
7431 struct samr_QueryDomainInfo2 r;
7432 union samr_DomainInfo *info = NULL;
7433 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
7437 for (i=0;i<ARRAY_SIZE(levels);i++) {
7438 torture_comment(tctx, "Testing QueryDomainInfo2 level %u\n", levels[i]);
7440 r.in.domain_handle = handle;
7441 r.in.level = levels[i];
7444 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo2_r(b, tctx, &r),
7445 "QueryDomainInfo2 failed");
7446 if (!NT_STATUS_IS_OK(r.out.result)) {
7447 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo2 level %u failed - %s\n",
7448 r.in.level, nt_errstr(r.out.result));
7457 /* Test whether querydispinfo level 5 and enumdomgroups return the same
7458 set of group names. */
7459 static bool test_GroupList(struct dcerpc_binding_handle *b,
7460 struct torture_context *tctx,
7461 struct dom_sid *domain_sid,
7462 struct policy_handle *handle)
7464 struct samr_EnumDomainGroups q1;
7465 struct samr_QueryDisplayInfo q2;
7467 uint32_t resume_handle=0;
7468 struct samr_SamArray *sam = NULL;
7469 uint32_t num_entries = 0;
7472 uint32_t total_size;
7473 uint32_t returned_size;
7474 union samr_DispInfo info;
7476 size_t num_names = 0;
7477 const char **names = NULL;
7479 bool builtin_domain = dom_sid_compare(domain_sid,
7480 &global_sid_Builtin) == 0;
7482 torture_comment(tctx, "Testing coherency of querydispinfo vs enumdomgroups\n");
7484 q1.in.domain_handle = handle;
7485 q1.in.resume_handle = &resume_handle;
7487 q1.out.resume_handle = &resume_handle;
7488 q1.out.num_entries = &num_entries;
7491 status = STATUS_MORE_ENTRIES;
7492 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
7493 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainGroups_r(b, tctx, &q1),
7494 "EnumDomainGroups failed");
7495 status = q1.out.result;
7497 if (!NT_STATUS_IS_OK(status) &&
7498 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
7501 for (i=0; i<*q1.out.num_entries; i++) {
7502 add_string_to_array(tctx,
7503 sam->entries[i].name.string,
7504 &names, &num_names);
7508 torture_assert_ntstatus_ok(tctx, status, "EnumDomainGroups");
7510 torture_assert(tctx, sam, "EnumDomainGroups failed to return sam");
7512 if (builtin_domain) {
7513 torture_assert(tctx, num_names == 0,
7514 "EnumDomainGroups shouldn't return any group in the builtin domain!");
7517 q2.in.domain_handle = handle;
7519 q2.in.start_idx = 0;
7520 q2.in.max_entries = 5;
7521 q2.in.buf_size = (uint32_t)-1;
7522 q2.out.total_size = &total_size;
7523 q2.out.returned_size = &returned_size;
7524 q2.out.info = &info;
7526 status = STATUS_MORE_ENTRIES;
7527 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
7528 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &q2),
7529 "QueryDisplayInfo failed");
7530 status = q2.out.result;
7531 if (!NT_STATUS_IS_OK(status) &&
7532 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
7535 for (i=0; i<q2.out.info->info5.count; i++) {
7537 const char *name = q2.out.info->info5.entries[i].account_name.string;
7539 for (j=0; j<num_names; j++) {
7540 if (names[j] == NULL)
7542 if (strequal(names[j], name)) {
7549 if ((!found) && (!builtin_domain)) {
7550 torture_result(tctx, TORTURE_FAIL, "QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
7555 q2.in.start_idx += q2.out.info->info5.count;
7558 if (!NT_STATUS_IS_OK(status)) {
7559 torture_result(tctx, TORTURE_FAIL, "QueryDisplayInfo level 5 failed - %s\n",
7564 if (builtin_domain) {
7565 torture_assert(tctx, q2.in.start_idx != 0,
7566 "QueryDisplayInfo should return all domain groups also on the builtin domain handle!");
7569 for (i=0; i<num_names; i++) {
7570 if (names[i] != NULL) {
7571 torture_result(tctx, TORTURE_FAIL, "EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
7580 static bool test_DeleteDomainGroup(struct dcerpc_binding_handle *b,
7581 struct torture_context *tctx,
7582 struct policy_handle *group_handle)
7584 struct samr_DeleteDomainGroup d;
7586 torture_comment(tctx, "Testing DeleteDomainGroup\n");
7588 d.in.group_handle = group_handle;
7589 d.out.group_handle = group_handle;
7591 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomainGroup_r(b, tctx, &d),
7592 "DeleteDomainGroup failed");
7593 torture_assert_ntstatus_ok(tctx, d.out.result, "DeleteDomainGroup");
7598 static bool test_TestPrivateFunctionsDomain(struct dcerpc_binding_handle *b,
7599 struct torture_context *tctx,
7600 struct policy_handle *domain_handle)
7602 struct samr_TestPrivateFunctionsDomain r;
7605 torture_comment(tctx, "Testing TestPrivateFunctionsDomain\n");
7607 r.in.domain_handle = domain_handle;
7609 torture_assert_ntstatus_ok(tctx, dcerpc_samr_TestPrivateFunctionsDomain_r(b, tctx, &r),
7610 "TestPrivateFunctionsDomain failed");
7611 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsDomain");
7616 static bool test_RidToSid(struct dcerpc_binding_handle *b,
7617 struct torture_context *tctx,
7618 struct dom_sid *domain_sid,
7619 struct policy_handle *domain_handle)
7621 struct samr_RidToSid r;
7623 struct dom_sid *calc_sid, *out_sid;
7624 int rids[] = { 0, 42, 512, 10200 };
7627 for (i=0;i<ARRAY_SIZE(rids);i++) {
7628 torture_comment(tctx, "Testing RidToSid\n");
7630 calc_sid = dom_sid_dup(tctx, domain_sid);
7631 r.in.domain_handle = domain_handle;
7633 r.out.sid = &out_sid;
7635 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RidToSid_r(b, tctx, &r),
7637 if (!NT_STATUS_IS_OK(r.out.result)) {
7638 torture_result(tctx, TORTURE_FAIL, "RidToSid for %d failed - %s\n", rids[i], nt_errstr(r.out.result));
7641 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
7643 if (!dom_sid_equal(calc_sid, out_sid)) {
7644 torture_result(tctx, TORTURE_FAIL, "RidToSid for %d failed - got %s, expected %s\n", rids[i],
7645 dom_sid_string(tctx, out_sid),
7646 dom_sid_string(tctx, calc_sid));
7655 static bool test_GetBootKeyInformation(struct dcerpc_binding_handle *b,
7656 struct torture_context *tctx,
7657 struct policy_handle *domain_handle)
7659 struct samr_GetBootKeyInformation r;
7661 uint32_t unknown = 0;
7664 torture_comment(tctx, "Testing GetBootKeyInformation\n");
7666 r.in.domain_handle = domain_handle;
7667 r.out.unknown = &unknown;
7669 status = dcerpc_samr_GetBootKeyInformation_r(b, tctx, &r);
7670 if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_OK(r.out.result)) {
7671 status = r.out.result;
7673 if (!NT_STATUS_IS_OK(status)) {
7674 /* w2k3 seems to fail this sometimes and pass it sometimes */
7675 torture_comment(tctx, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
7681 static bool test_AddGroupMember(struct dcerpc_binding_handle *b,
7682 struct torture_context *tctx,
7683 struct policy_handle *domain_handle,
7684 struct policy_handle *group_handle)
7687 struct samr_AddGroupMember r;
7688 struct samr_DeleteGroupMember d;
7689 struct samr_QueryGroupMember q;
7690 struct samr_RidAttrArray *rids = NULL;
7691 struct samr_SetMemberAttributesOfGroup s;
7693 bool found_member = false;
7696 status = test_LookupName(b, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
7697 torture_assert_ntstatus_ok(tctx, status, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME);
7699 r.in.group_handle = group_handle;
7701 r.in.flags = 0; /* ??? */
7703 torture_comment(tctx, "Testing AddGroupMember, QueryGroupMember and DeleteGroupMember\n");
7705 d.in.group_handle = group_handle;
7708 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteGroupMember_r(b, tctx, &d),
7709 "DeleteGroupMember failed");
7710 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_NOT_IN_GROUP, d.out.result, "DeleteGroupMember");
7712 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddGroupMember_r(b, tctx, &r),
7713 "AddGroupMember failed");
7714 torture_assert_ntstatus_ok(tctx, r.out.result, "AddGroupMember");
7716 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddGroupMember_r(b, tctx, &r),
7717 "AddGroupMember failed");
7718 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_IN_GROUP, r.out.result, "AddGroupMember");
7720 if (torture_setting_bool(tctx, "samba4", false) ||
7721 torture_setting_bool(tctx, "samba3", false)) {
7722 torture_comment(tctx, "skipping SetMemberAttributesOfGroup test against Samba\n");
7724 /* this one is quite strange. I am using random inputs in the
7725 hope of triggering an error that might give us a clue */
7727 s.in.group_handle = group_handle;
7728 s.in.unknown1 = random();
7729 s.in.unknown2 = random();
7731 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetMemberAttributesOfGroup_r(b, tctx, &s),
7732 "SetMemberAttributesOfGroup failed");
7733 torture_assert_ntstatus_ok(tctx, s.out.result, "SetMemberAttributesOfGroup");
7736 q.in.group_handle = group_handle;
7739 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupMember_r(b, tctx, &q),
7740 "QueryGroupMember failed");
7741 torture_assert_ntstatus_ok(tctx, q.out.result, "QueryGroupMember");
7742 torture_assert(tctx, rids, "QueryGroupMember did not fill in rids structure");
7744 for (i=0; i < rids->count; i++) {
7745 if (rids->rids[i] == rid) {
7746 found_member = true;
7750 torture_assert(tctx, found_member, "QueryGroupMember did not list newly added member");
7752 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteGroupMember_r(b, tctx, &d),
7753 "DeleteGroupMember failed");
7754 torture_assert_ntstatus_ok(tctx, d.out.result, "DeleteGroupMember");
7757 found_member = false;
7759 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupMember_r(b, tctx, &q),
7760 "QueryGroupMember failed");
7761 torture_assert_ntstatus_ok(tctx, q.out.result, "QueryGroupMember");
7762 torture_assert(tctx, rids, "QueryGroupMember did not fill in rids structure");
7764 for (i=0; i < rids->count; i++) {
7765 if (rids->rids[i] == rid) {
7766 found_member = true;
7770 torture_assert(tctx, !found_member, "QueryGroupMember does still list removed member");
7772 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddGroupMember_r(b, tctx, &r),
7773 "AddGroupMember failed");
7774 torture_assert_ntstatus_ok(tctx, r.out.result, "AddGroupMember");
7780 static bool test_CreateDomainGroup(struct dcerpc_binding_handle *b,
7781 struct torture_context *tctx,
7782 struct policy_handle *domain_handle,
7783 const char *group_name,
7784 struct policy_handle *group_handle,
7785 struct dom_sid *domain_sid,
7788 struct samr_CreateDomainGroup r;
7790 struct lsa_String name;
7793 init_lsa_String(&name, group_name);
7795 r.in.domain_handle = domain_handle;
7797 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7798 r.out.group_handle = group_handle;
7801 torture_comment(tctx, "Testing CreateDomainGroup(%s)\n", r.in.name->string);
7803 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomainGroup_r(b, tctx, &r),
7804 "CreateDomainGroup failed");
7806 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
7807 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED)) {
7808 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.name->string);
7811 torture_result(tctx, TORTURE_FAIL, "Server should have refused create of '%s', got %s instead\n", r.in.name->string,
7812 nt_errstr(r.out.result));
7817 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_GROUP_EXISTS)) {
7818 if (!test_DeleteGroup_byname(b, tctx, domain_handle, r.in.name->string)) {
7819 torture_result(tctx, TORTURE_FAIL, "CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
7820 nt_errstr(r.out.result));
7823 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomainGroup_r(b, tctx, &r),
7824 "CreateDomainGroup failed");
7826 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_USER_EXISTS)) {
7827 if (!test_DeleteUser_byname(b, tctx, domain_handle, r.in.name->string)) {
7829 torture_result(tctx, TORTURE_FAIL, "CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
7830 nt_errstr(r.out.result));
7833 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomainGroup_r(b, tctx, &r),
7834 "CreateDomainGroup failed");
7836 torture_assert_ntstatus_ok(tctx, r.out.result, "CreateDomainGroup");
7842 if (!test_AddGroupMember(b, tctx, domain_handle, group_handle)) {
7843 torture_result(tctx, TORTURE_FAIL, "CreateDomainGroup failed - %s\n", nt_errstr(r.out.result));
7847 if (!test_SetGroupInfo(b, tctx, group_handle)) {
7856 its not totally clear what this does. It seems to accept any sid you like.
7858 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_binding_handle *b,
7859 struct torture_context *tctx,
7860 struct policy_handle *domain_handle)
7862 struct samr_RemoveMemberFromForeignDomain r;
7864 r.in.domain_handle = domain_handle;
7865 r.in.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-12-34-56-78");
7867 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RemoveMemberFromForeignDomain_r(b, tctx, &r),
7868 "RemoveMemberFromForeignDomain failed");
7869 torture_assert_ntstatus_ok(tctx, r.out.result, "RemoveMemberFromForeignDomain");
7874 static bool test_EnumDomainUsers(struct dcerpc_binding_handle *b,
7875 struct torture_context *tctx,
7876 struct policy_handle *domain_handle,
7877 uint32_t *total_num_entries_p)
7880 struct samr_EnumDomainUsers r;
7881 uint32_t resume_handle = 0;
7882 uint32_t num_entries = 0;
7883 uint32_t total_num_entries = 0;
7884 struct samr_SamArray *sam;
7886 r.in.domain_handle = domain_handle;
7887 r.in.acct_flags = 0;
7888 r.in.max_size = (uint32_t)-1;
7889 r.in.resume_handle = &resume_handle;
7892 r.out.num_entries = &num_entries;
7893 r.out.resume_handle = &resume_handle;
7895 torture_comment(tctx, "Testing EnumDomainUsers\n");
7898 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainUsers_r(b, tctx, &r),
7899 "EnumDomainUsers failed");
7900 if (NT_STATUS_IS_ERR(r.out.result)) {
7901 torture_assert_ntstatus_ok(tctx, r.out.result,
7902 "failed to enumerate users");
7904 status = r.out.result;
7906 total_num_entries += num_entries;
7907 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7909 if (total_num_entries_p) {
7910 *total_num_entries_p = total_num_entries;
7916 static bool test_EnumDomainGroups(struct dcerpc_binding_handle *b,
7917 struct torture_context *tctx,
7918 struct policy_handle *domain_handle,
7919 uint32_t *total_num_entries_p)
7922 struct samr_EnumDomainGroups r;
7923 uint32_t resume_handle = 0;
7924 uint32_t num_entries = 0;
7925 uint32_t total_num_entries = 0;
7926 struct samr_SamArray *sam;
7928 r.in.domain_handle = domain_handle;
7929 r.in.max_size = (uint32_t)-1;
7930 r.in.resume_handle = &resume_handle;
7933 r.out.num_entries = &num_entries;
7934 r.out.resume_handle = &resume_handle;
7936 torture_comment(tctx, "Testing EnumDomainGroups\n");
7939 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainGroups_r(b, tctx, &r),
7940 "EnumDomainGroups failed");
7941 if (NT_STATUS_IS_ERR(r.out.result)) {
7942 torture_assert_ntstatus_ok(tctx, r.out.result,
7943 "failed to enumerate groups");
7945 status = r.out.result;
7947 total_num_entries += num_entries;
7948 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7950 if (total_num_entries_p) {
7951 *total_num_entries_p = total_num_entries;
7957 static bool test_EnumDomainAliases(struct dcerpc_binding_handle *b,
7958 struct torture_context *tctx,
7959 struct policy_handle *domain_handle,
7960 uint32_t *total_num_entries_p)
7963 struct samr_EnumDomainAliases r;
7964 uint32_t resume_handle = 0;
7965 uint32_t num_entries = 0;
7966 uint32_t total_num_entries = 0;
7967 struct samr_SamArray *sam;
7969 r.in.domain_handle = domain_handle;
7970 r.in.max_size = (uint32_t)-1;
7971 r.in.resume_handle = &resume_handle;
7974 r.out.num_entries = &num_entries;
7975 r.out.resume_handle = &resume_handle;
7977 torture_comment(tctx, "Testing EnumDomainAliases\n");
7980 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainAliases_r(b, tctx, &r),
7981 "EnumDomainAliases failed");
7982 if (NT_STATUS_IS_ERR(r.out.result)) {
7983 torture_assert_ntstatus_ok(tctx, r.out.result,
7984 "failed to enumerate aliases");
7986 status = r.out.result;
7988 total_num_entries += num_entries;
7989 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7991 if (total_num_entries_p) {
7992 *total_num_entries_p = total_num_entries;
7998 static bool test_QueryDisplayInfo_level(struct dcerpc_binding_handle *b,
7999 struct torture_context *tctx,
8000 struct policy_handle *handle,
8002 uint32_t *total_num_entries_p)
8005 struct samr_QueryDisplayInfo r;
8006 uint32_t total_num_entries = 0;
8008 r.in.domain_handle = handle;
8011 r.in.max_entries = (uint32_t)-1;
8012 r.in.buf_size = (uint32_t)-1;
8014 torture_comment(tctx, "Testing QueryDisplayInfo\n");
8017 uint32_t total_size;
8018 uint32_t returned_size;
8019 union samr_DispInfo info;
8021 r.out.total_size = &total_size;
8022 r.out.returned_size = &returned_size;
8025 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &r),
8026 "failed to query displayinfo");
8027 if (NT_STATUS_IS_ERR(r.out.result)) {
8028 torture_assert_ntstatus_ok(tctx, r.out.result,
8029 "failed to query displayinfo");
8031 status = r.out.result;
8033 if (*r.out.returned_size == 0) {
8037 switch (r.in.level) {
8039 total_num_entries += info.info1.count;
8040 r.in.start_idx += info.info1.entries[info.info1.count - 1].idx + 1;
8043 total_num_entries += info.info2.count;
8044 r.in.start_idx += info.info2.entries[info.info2.count - 1].idx + 1;
8047 total_num_entries += info.info3.count;
8048 r.in.start_idx += info.info3.entries[info.info3.count - 1].idx + 1;
8051 total_num_entries += info.info4.count;
8052 r.in.start_idx += info.info4.entries[info.info4.count - 1].idx + 1;
8055 total_num_entries += info.info5.count;
8056 r.in.start_idx += info.info5.entries[info.info5.count - 1].idx + 1;
8062 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
8064 if (total_num_entries_p) {
8065 *total_num_entries_p = total_num_entries;
8071 static bool test_ManyObjects(struct dcerpc_pipe *p,
8072 struct torture_context *tctx,
8073 struct policy_handle *domain_handle,
8074 struct dom_sid *domain_sid,
8075 struct torture_samr_context *ctx)
8077 uint32_t num_total = ctx->num_objects_large_dc;
8078 uint32_t num_enum = 0;
8079 uint32_t num_disp = 0;
8080 uint32_t num_created = 0;
8081 uint32_t num_anounced = 0;
8083 struct dcerpc_binding_handle *b = p->binding_handle;
8085 struct policy_handle *handles = talloc_zero_array(tctx, struct policy_handle, num_total);
8090 struct samr_QueryDomainInfo2 r;
8091 union samr_DomainInfo *info;
8092 r.in.domain_handle = domain_handle;
8096 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo2_r(b, tctx, &r),
8097 "QueryDomainInfo2 failed");
8098 torture_assert_ntstatus_ok(tctx, r.out.result,
8099 "failed to query domain info");
8101 switch (ctx->choice) {
8102 case TORTURE_SAMR_MANY_ACCOUNTS:
8103 num_anounced = info->general.num_users;
8105 case TORTURE_SAMR_MANY_GROUPS:
8106 num_anounced = info->general.num_groups;
8108 case TORTURE_SAMR_MANY_ALIASES:
8109 num_anounced = info->general.num_aliases;
8118 for (i=0; i < num_total; i++) {
8120 const char *name = NULL;
8122 switch (ctx->choice) {
8123 case TORTURE_SAMR_MANY_ACCOUNTS:
8124 name = talloc_asprintf(tctx, "%s%04d", TEST_ACCOUNT_NAME, i);
8125 torture_assert(tctx,
8126 test_CreateUser(p, tctx, domain_handle, name, &handles[i], domain_sid, 0, NULL, false),
8127 "failed to create user");
8129 case TORTURE_SAMR_MANY_GROUPS:
8130 name = talloc_asprintf(tctx, "%s%04d", TEST_GROUPNAME, i);
8131 torture_assert(tctx,
8132 test_CreateDomainGroup(b, tctx, domain_handle, name, &handles[i], domain_sid, false),
8133 "failed to create group");
8135 case TORTURE_SAMR_MANY_ALIASES:
8136 name = talloc_asprintf(tctx, "%s%04d", TEST_ALIASNAME, i);
8137 torture_assert(tctx,
8138 test_CreateAlias(b, tctx, domain_handle, name, &handles[i], domain_sid, false),
8139 "failed to create alias");
8144 if (!ndr_policy_handle_empty(&handles[i])) {
8151 switch (ctx->choice) {
8152 case TORTURE_SAMR_MANY_ACCOUNTS:
8153 torture_assert(tctx,
8154 test_EnumDomainUsers(b, tctx, domain_handle, &num_enum),
8155 "failed to enum users");
8157 case TORTURE_SAMR_MANY_GROUPS:
8158 torture_assert(tctx,
8159 test_EnumDomainGroups(b, tctx, domain_handle, &num_enum),
8160 "failed to enum groups");
8162 case TORTURE_SAMR_MANY_ALIASES:
8163 torture_assert(tctx,
8164 test_EnumDomainAliases(b, tctx, domain_handle, &num_enum),
8165 "failed to enum aliases");
8173 switch (ctx->choice) {
8174 case TORTURE_SAMR_MANY_ACCOUNTS:
8175 torture_assert(tctx,
8176 test_QueryDisplayInfo_level(b, tctx, domain_handle, 1, &num_disp),
8177 "failed to query display info");
8179 case TORTURE_SAMR_MANY_GROUPS:
8180 torture_assert(tctx,
8181 test_QueryDisplayInfo_level(b, tctx, domain_handle, 3, &num_disp),
8182 "failed to query display info");
8184 case TORTURE_SAMR_MANY_ALIASES:
8185 /* no aliases in dispinfo */
8191 /* close or delete */
8193 for (i=0; i < num_total; i++) {
8195 if (ndr_policy_handle_empty(&handles[i])) {
8199 if (torture_setting_bool(tctx, "samba3", false)) {
8200 torture_assert(tctx,
8201 test_samr_handle_Close(b, tctx, &handles[i]),
8202 "failed to close handle");
8204 switch (ctx->choice) {
8205 case TORTURE_SAMR_MANY_ACCOUNTS:
8206 torture_assert(tctx,
8207 test_DeleteUser(b, tctx, &handles[i]),
8208 "failed to delete user");
8210 case TORTURE_SAMR_MANY_GROUPS:
8211 torture_assert(tctx,
8212 test_DeleteDomainGroup(b, tctx, &handles[i]),
8213 "failed to delete group");
8215 case TORTURE_SAMR_MANY_ALIASES:
8216 torture_assert(tctx,
8217 test_DeleteAlias(b, tctx, &handles[i]),
8218 "failed to delete alias");
8226 talloc_free(handles);
8228 if (ctx->choice == TORTURE_SAMR_MANY_ACCOUNTS && num_enum != num_anounced + num_created) {
8229 torture_comment(tctx,
8230 "unexpected number of results (%u) returned in enum call, expected %u\n",
8231 num_enum, num_anounced + num_created);
8233 torture_comment(tctx,
8234 "unexpected number of results (%u) returned in dispinfo, call, expected %u\n",
8235 num_disp, num_anounced + num_created);
8241 static bool test_Connect(struct dcerpc_binding_handle *b,
8242 struct torture_context *tctx,
8243 struct policy_handle *handle);
8245 static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
8246 struct torture_samr_context *ctx, struct dom_sid *sid)
8248 struct samr_OpenDomain r;
8249 struct policy_handle domain_handle;
8250 struct policy_handle alias_handle;
8251 struct policy_handle user_handle;
8252 struct policy_handle group_handle;
8254 struct dcerpc_binding_handle *b = p->binding_handle;
8256 ZERO_STRUCT(alias_handle);
8257 ZERO_STRUCT(user_handle);
8258 ZERO_STRUCT(group_handle);
8259 ZERO_STRUCT(domain_handle);
8261 torture_comment(tctx, "Testing OpenDomain of %s\n", dom_sid_string(tctx, sid));
8263 r.in.connect_handle = &ctx->handle;
8264 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
8266 r.out.domain_handle = &domain_handle;
8268 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenDomain_r(b, tctx, &r),
8269 "OpenDomain failed");
8270 torture_assert_ntstatus_ok(tctx, r.out.result, "OpenDomain failed");
8272 /* run the domain tests with the main handle closed - this tests
8273 the servers reference counting */
8274 torture_assert(tctx, test_samr_handle_Close(b, tctx, &ctx->handle), "Failed to close SAMR handle");
8276 switch (ctx->choice) {
8277 case TORTURE_SAMR_PASSWORDS:
8278 case TORTURE_SAMR_USER_PRIVILEGES:
8279 if (!torture_setting_bool(tctx, "samba3", false)) {
8280 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, NULL);
8282 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
8284 torture_result(tctx, TORTURE_FAIL, "Testing PASSWORDS or PRIVILEGES on domain %s failed!\n", dom_sid_string(tctx, sid));
8287 case TORTURE_SAMR_USER_ATTRIBUTES:
8288 if (!torture_setting_bool(tctx, "samba3", false)) {
8289 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, NULL);
8291 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
8292 /* This test needs 'complex' users to validate */
8293 ret &= test_QueryDisplayInfo(b, tctx, &domain_handle);
8295 torture_result(tctx, TORTURE_FAIL, "Testing ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
8298 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
8299 case TORTURE_SAMR_PASSWORDS_BADPWDCOUNT:
8300 case TORTURE_SAMR_PASSWORDS_LOCKOUT:
8301 if (!torture_setting_bool(tctx, "samba3", false)) {
8302 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, ctx->machine_credentials);
8304 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, ctx->machine_credentials, true);
8306 torture_result(tctx, TORTURE_FAIL, "Testing PASSWORDS PWDLASTSET or BADPWDCOUNT on domain %s failed!\n", dom_sid_string(tctx, sid));
8309 case TORTURE_SAMR_MANY_ACCOUNTS:
8310 case TORTURE_SAMR_MANY_GROUPS:
8311 case TORTURE_SAMR_MANY_ALIASES:
8312 ret &= test_ManyObjects(p, tctx, &domain_handle, sid, ctx);
8314 torture_result(tctx, TORTURE_FAIL, "Testing MANY-{ACCOUNTS,GROUPS,ALIASES} on domain %s failed!\n", dom_sid_string(tctx, sid));
8317 case TORTURE_SAMR_OTHER:
8318 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
8320 torture_result(tctx, TORTURE_FAIL, "Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid));
8322 if (!torture_setting_bool(tctx, "samba3", false)) {
8323 ret &= test_QuerySecurity(b, tctx, &domain_handle);
8325 ret &= test_RemoveMemberFromForeignDomain(b, tctx, &domain_handle);
8326 ret &= test_CreateAlias(b, tctx, &domain_handle, TEST_ALIASNAME, &alias_handle, sid, true);
8327 ret &= test_CreateDomainGroup(b, tctx, &domain_handle, TEST_GROUPNAME, &group_handle, sid, true);
8328 ret &= test_GetAliasMembership(b, tctx, &domain_handle);
8329 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
8330 ret &= test_QueryDomainInfo2(b, tctx, &domain_handle);
8331 ret &= test_EnumDomainUsers_all(b, tctx, &domain_handle);
8332 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
8333 ret &= test_EnumDomainGroups_all(b, tctx, &domain_handle);
8334 ret &= test_EnumDomainAliases_all(b, tctx, &domain_handle);
8335 ret &= test_QueryDisplayInfo2(b, tctx, &domain_handle);
8336 ret &= test_QueryDisplayInfo3(b, tctx, &domain_handle);
8337 ret &= test_QueryDisplayInfo_continue(b, tctx, &domain_handle);
8339 if (torture_setting_bool(tctx, "samba4", false)) {
8340 torture_comment(tctx, "skipping GetDisplayEnumerationIndex test against Samba4\n");
8342 ret &= test_GetDisplayEnumerationIndex(b, tctx, &domain_handle);
8343 ret &= test_GetDisplayEnumerationIndex2(b, tctx, &domain_handle);
8345 ret &= test_GroupList(b, tctx, sid, &domain_handle);
8346 ret &= test_TestPrivateFunctionsDomain(b, tctx, &domain_handle);
8347 ret &= test_RidToSid(b, tctx, sid, &domain_handle);
8348 ret &= test_GetBootKeyInformation(b, tctx, &domain_handle);
8350 torture_comment(tctx, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx, sid));
8355 if (!ndr_policy_handle_empty(&user_handle) &&
8356 !test_DeleteUser(b, tctx, &user_handle)) {
8360 if (!ndr_policy_handle_empty(&alias_handle) &&
8361 !test_DeleteAlias(b, tctx, &alias_handle)) {
8365 if (!ndr_policy_handle_empty(&group_handle) &&
8366 !test_DeleteDomainGroup(b, tctx, &group_handle)) {
8370 torture_assert(tctx, test_samr_handle_Close(b, tctx, &domain_handle), "Failed to close SAMR domain handle");
8372 torture_assert(tctx, test_Connect(b, tctx, &ctx->handle), "Faile to re-connect SAMR handle");
8373 /* reconnect the main handle */
8376 torture_result(tctx, TORTURE_FAIL, "Testing domain %s failed!\n", dom_sid_string(tctx, sid));
8382 static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
8383 struct torture_samr_context *ctx, const char *domain)
8385 struct samr_LookupDomain r;
8386 struct dom_sid2 *sid = NULL;
8387 struct lsa_String n1;
8388 struct lsa_String n2;
8390 struct dcerpc_binding_handle *b = p->binding_handle;
8392 torture_comment(tctx, "Testing LookupDomain(%s)\n", domain);
8394 /* check for correct error codes */
8395 r.in.connect_handle = &ctx->handle;
8396 r.in.domain_name = &n2;
8400 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupDomain_r(b, tctx, &r),
8401 "LookupDomain failed");
8402 torture_assert_ntstatus_equal(tctx, NT_STATUS_INVALID_PARAMETER, r.out.result, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
8404 init_lsa_String(&n2, "xxNODOMAINxx");
8406 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupDomain_r(b, tctx, &r),
8407 "LookupDomain failed");
8408 torture_assert_ntstatus_equal(tctx, NT_STATUS_NO_SUCH_DOMAIN, r.out.result, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
8410 r.in.connect_handle = &ctx->handle;
8412 init_lsa_String(&n1, domain);
8413 r.in.domain_name = &n1;
8415 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupDomain_r(b, tctx, &r),
8416 "LookupDomain failed");
8417 torture_assert_ntstatus_ok(tctx, r.out.result, "LookupDomain");
8419 if (!test_GetDomPwInfo(p, tctx, &n1)) {
8423 if (!test_OpenDomain(p, tctx, ctx, *r.out.sid)) {
8431 static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
8432 struct torture_samr_context *ctx)
8434 struct samr_EnumDomains r;
8435 uint32_t resume_handle = 0;
8436 uint32_t num_entries = 0;
8437 struct samr_SamArray *sam = NULL;
8440 struct dcerpc_binding_handle *b = p->binding_handle;
8442 r.in.connect_handle = &ctx->handle;
8443 r.in.resume_handle = &resume_handle;
8444 r.in.buf_size = (uint32_t)-1;
8445 r.out.resume_handle = &resume_handle;
8446 r.out.num_entries = &num_entries;
8449 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomains_r(b, tctx, &r),
8450 "EnumDomains failed");
8451 torture_assert_ntstatus_ok(tctx, r.out.result, "EnumDomains failed");
8457 for (i=0;i<sam->count;i++) {
8458 if (!test_LookupDomain(p, tctx, ctx,
8459 sam->entries[i].name.string)) {
8464 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomains_r(b, tctx, &r),
8465 "EnumDomains failed");
8466 torture_assert_ntstatus_ok(tctx, r.out.result, "EnumDomains failed");
8472 static bool test_Connect(struct dcerpc_binding_handle *b,
8473 struct torture_context *tctx,
8474 struct policy_handle *handle)
8476 struct samr_Connect r;
8477 struct samr_Connect2 r2;
8478 struct samr_Connect3 r3;
8479 struct samr_Connect4 r4;
8480 struct samr_Connect5 r5;
8481 union samr_ConnectInfo info;
8482 struct policy_handle h;
8483 uint32_t level_out = 0;
8484 bool ret = true, got_handle = false;
8486 torture_comment(tctx, "Testing samr_Connect\n");
8488 r.in.system_name = NULL;
8489 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
8490 r.out.connect_handle = &h;
8492 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect_r(b, tctx, &r),
8494 if (!NT_STATUS_IS_OK(r.out.result)) {
8495 torture_comment(tctx, "Connect failed - %s\n", nt_errstr(r.out.result));
8502 torture_comment(tctx, "Testing samr_Connect2\n");
8504 r2.in.system_name = NULL;
8505 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
8506 r2.out.connect_handle = &h;
8508 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect2_r(b, tctx, &r2),
8510 if (!NT_STATUS_IS_OK(r2.out.result)) {
8511 torture_comment(tctx, "Connect2 failed - %s\n", nt_errstr(r2.out.result));
8515 test_samr_handle_Close(b, tctx, handle);
8521 torture_comment(tctx, "Testing samr_Connect3\n");
8523 r3.in.system_name = NULL;
8525 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
8526 r3.out.connect_handle = &h;
8528 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect3_r(b, tctx, &r3),
8530 if (!NT_STATUS_IS_OK(r3.out.result)) {
8531 torture_result(tctx, TORTURE_FAIL, "Connect3 failed - %s\n", nt_errstr(r3.out.result));
8535 test_samr_handle_Close(b, tctx, handle);
8541 torture_comment(tctx, "Testing samr_Connect4\n");
8543 r4.in.system_name = "";
8544 r4.in.client_version = 0;
8545 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
8546 r4.out.connect_handle = &h;
8548 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect4_r(b, tctx, &r4),
8550 if (!NT_STATUS_IS_OK(r4.out.result)) {
8551 torture_result(tctx, TORTURE_FAIL, "Connect4 failed - %s\n", nt_errstr(r4.out.result));
8555 test_samr_handle_Close(b, tctx, handle);
8561 torture_comment(tctx, "Testing samr_Connect5\n");
8563 info.info1.client_version = 0;
8564 info.info1.unknown2 = 0;
8566 r5.in.system_name = "";
8567 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
8569 r5.out.level_out = &level_out;
8570 r5.in.info_in = &info;
8571 r5.out.info_out = &info;
8572 r5.out.connect_handle = &h;
8574 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect5_r(b, tctx, &r5),
8576 if (!NT_STATUS_IS_OK(r5.out.result)) {
8577 torture_result(tctx, TORTURE_FAIL, "Connect5 failed - %s\n", nt_errstr(r5.out.result));
8581 test_samr_handle_Close(b, tctx, handle);
8591 static bool test_samr_ValidatePassword(struct torture_context *tctx,
8592 struct dcerpc_pipe *p)
8594 struct samr_ValidatePassword r;
8595 union samr_ValidatePasswordReq req;
8596 union samr_ValidatePasswordRep *repp = NULL;
8598 const char *passwords[] = { "penguin", "p@ssw0rd", "p@ssw0rd123$", NULL };
8600 struct dcerpc_binding_handle *b = p->binding_handle;
8602 torture_comment(tctx, "Testing samr_ValidatePassword\n");
8604 if (p->conn->transport.transport != NCACN_IP_TCP) {
8605 torture_comment(tctx, "samr_ValidatePassword only should succeed over NCACN_IP_TCP!\n");
8609 r.in.level = NetValidatePasswordReset;
8614 req.req3.account.string = "non-existent-account-aklsdji";
8616 for (i=0; passwords[i]; i++) {
8617 req.req3.password.string = passwords[i];
8619 status = dcerpc_samr_ValidatePassword_r(b, tctx, &r);
8620 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE)) {
8621 torture_skip(tctx, "ValidatePassword not supported by server\n");
8623 torture_assert_ntstatus_ok(tctx, status,
8624 "samr_ValidatePassword failed");
8625 torture_assert_ntstatus_ok(tctx, r.out.result,
8626 "samr_ValidatePassword failed");
8627 torture_comment(tctx, "Server %s password '%s' with code %i\n",
8628 repp->ctr3.status==SAMR_VALIDATION_STATUS_SUCCESS?"allowed":"refused",
8629 req.req3.password.string, repp->ctr3.status);
8635 bool torture_rpc_samr(struct torture_context *torture)
8638 struct dcerpc_pipe *p;
8640 struct torture_samr_context *ctx;
8641 struct dcerpc_binding_handle *b;
8643 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8644 if (!NT_STATUS_IS_OK(status)) {
8647 b = p->binding_handle;
8649 ctx = talloc_zero(torture, struct torture_samr_context);
8651 ctx->choice = TORTURE_SAMR_OTHER;
8653 ret &= test_Connect(b, torture, &ctx->handle);
8655 if (!torture_setting_bool(torture, "samba3", false)) {
8656 ret &= test_QuerySecurity(b, torture, &ctx->handle);
8659 ret &= test_EnumDomains(p, torture, ctx);
8661 ret &= test_SetDsrmPassword(b, torture, &ctx->handle);
8663 ret &= test_Shutdown(b, torture, &ctx->handle);
8665 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8671 bool torture_rpc_samr_users(struct torture_context *torture)
8674 struct dcerpc_pipe *p;
8676 struct torture_samr_context *ctx;
8677 struct dcerpc_binding_handle *b;
8679 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8680 if (!NT_STATUS_IS_OK(status)) {
8683 b = p->binding_handle;
8685 ctx = talloc_zero(torture, struct torture_samr_context);
8687 ctx->choice = TORTURE_SAMR_USER_ATTRIBUTES;
8689 ret &= test_Connect(b, torture, &ctx->handle);
8691 if (!torture_setting_bool(torture, "samba3", false)) {
8692 ret &= test_QuerySecurity(b, torture, &ctx->handle);
8695 ret &= test_EnumDomains(p, torture, ctx);
8697 ret &= test_SetDsrmPassword(b, torture, &ctx->handle);
8699 ret &= test_Shutdown(b, torture, &ctx->handle);
8701 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8707 bool torture_rpc_samr_passwords(struct torture_context *torture)
8710 struct dcerpc_pipe *p;
8712 struct torture_samr_context *ctx;
8713 struct dcerpc_binding_handle *b;
8715 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8716 if (!NT_STATUS_IS_OK(status)) {
8719 b = p->binding_handle;
8721 ctx = talloc_zero(torture, struct torture_samr_context);
8723 ctx->choice = TORTURE_SAMR_PASSWORDS;
8725 ret &= test_Connect(b, torture, &ctx->handle);
8727 ret &= test_EnumDomains(p, torture, ctx);
8729 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8734 static bool torture_rpc_samr_pwdlastset(struct torture_context *torture,
8735 struct dcerpc_pipe *p2,
8736 struct cli_credentials *machine_credentials)
8739 struct dcerpc_pipe *p;
8741 struct torture_samr_context *ctx;
8742 struct dcerpc_binding_handle *b;
8744 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8745 if (!NT_STATUS_IS_OK(status)) {
8748 b = p->binding_handle;
8750 ctx = talloc_zero(torture, struct torture_samr_context);
8752 ctx->choice = TORTURE_SAMR_PASSWORDS_PWDLASTSET;
8753 ctx->machine_credentials = machine_credentials;
8755 ret &= test_Connect(b, torture, &ctx->handle);
8757 ret &= test_EnumDomains(p, torture, ctx);
8759 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8764 struct torture_suite *torture_rpc_samr_passwords_pwdlastset(TALLOC_CTX *mem_ctx)
8766 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.passwords.pwdlastset");
8767 struct torture_rpc_tcase *tcase;
8769 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8771 TEST_ACCOUNT_NAME_PWD);
8773 torture_rpc_tcase_add_test_creds(tcase, "pwdLastSet",
8774 torture_rpc_samr_pwdlastset);
8779 static bool torture_rpc_samr_users_privileges_delete_user(struct torture_context *torture,
8780 struct dcerpc_pipe *p2,
8781 struct cli_credentials *machine_credentials)
8784 struct dcerpc_pipe *p;
8786 struct torture_samr_context *ctx;
8787 struct dcerpc_binding_handle *b;
8789 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8790 if (!NT_STATUS_IS_OK(status)) {
8793 b = p->binding_handle;
8795 ctx = talloc_zero(torture, struct torture_samr_context);
8797 ctx->choice = TORTURE_SAMR_USER_PRIVILEGES;
8798 ctx->machine_credentials = machine_credentials;
8800 ret &= test_Connect(b, torture, &ctx->handle);
8802 ret &= test_EnumDomains(p, torture, ctx);
8804 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8809 struct torture_suite *torture_rpc_samr_user_privileges(TALLOC_CTX *mem_ctx)
8811 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.users.privileges");
8812 struct torture_rpc_tcase *tcase;
8814 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8816 TEST_ACCOUNT_NAME_PWD);
8818 torture_rpc_tcase_add_test_creds(tcase, "delete_privileged_user",
8819 torture_rpc_samr_users_privileges_delete_user);
8824 static bool torture_rpc_samr_many_accounts(struct torture_context *torture,
8825 struct dcerpc_pipe *p2,
8829 struct dcerpc_pipe *p;
8831 struct torture_samr_context *ctx =
8832 talloc_get_type_abort(data, struct torture_samr_context);
8833 struct dcerpc_binding_handle *b;
8835 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8836 if (!NT_STATUS_IS_OK(status)) {
8839 b = p->binding_handle;
8841 ctx->choice = TORTURE_SAMR_MANY_ACCOUNTS;
8842 ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
8843 ctx->num_objects_large_dc);
8845 ret &= test_Connect(b, torture, &ctx->handle);
8847 ret &= test_EnumDomains(p, torture, ctx);
8849 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8854 static bool torture_rpc_samr_many_groups(struct torture_context *torture,
8855 struct dcerpc_pipe *p2,
8859 struct dcerpc_pipe *p;
8861 struct torture_samr_context *ctx =
8862 talloc_get_type_abort(data, struct torture_samr_context);
8863 struct dcerpc_binding_handle *b;
8865 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8866 if (!NT_STATUS_IS_OK(status)) {
8869 b = p->binding_handle;
8871 ctx->choice = TORTURE_SAMR_MANY_GROUPS;
8872 ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
8873 ctx->num_objects_large_dc);
8875 ret &= test_Connect(b, torture, &ctx->handle);
8877 ret &= test_EnumDomains(p, torture, ctx);
8879 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8884 static bool torture_rpc_samr_many_aliases(struct torture_context *torture,
8885 struct dcerpc_pipe *p2,
8889 struct dcerpc_pipe *p;
8891 struct torture_samr_context *ctx =
8892 talloc_get_type_abort(data, struct torture_samr_context);
8893 struct dcerpc_binding_handle *b;
8895 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8896 if (!NT_STATUS_IS_OK(status)) {
8899 b = p->binding_handle;
8901 ctx->choice = TORTURE_SAMR_MANY_ALIASES;
8902 ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
8903 ctx->num_objects_large_dc);
8905 ret &= test_Connect(b, torture, &ctx->handle);
8907 ret &= test_EnumDomains(p, torture, ctx);
8909 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8914 struct torture_suite *torture_rpc_samr_large_dc(TALLOC_CTX *mem_ctx)
8916 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.large-dc");
8917 struct torture_rpc_tcase *tcase;
8918 struct torture_samr_context *ctx;
8920 tcase = torture_suite_add_rpc_iface_tcase(suite, "samr", &ndr_table_samr);
8922 ctx = talloc_zero(suite, struct torture_samr_context);
8923 ctx->num_objects_large_dc = 150;
8925 torture_rpc_tcase_add_test_ex(tcase, "many_aliases",
8926 torture_rpc_samr_many_aliases, ctx);
8927 torture_rpc_tcase_add_test_ex(tcase, "many_groups",
8928 torture_rpc_samr_many_groups, ctx);
8929 torture_rpc_tcase_add_test_ex(tcase, "many_accounts",
8930 torture_rpc_samr_many_accounts, ctx);
8935 static bool torture_rpc_samr_badpwdcount(struct torture_context *torture,
8936 struct dcerpc_pipe *p2,
8937 struct cli_credentials *machine_credentials)
8940 struct dcerpc_pipe *p;
8942 struct torture_samr_context *ctx;
8943 struct dcerpc_binding_handle *b;
8945 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8946 if (!NT_STATUS_IS_OK(status)) {
8949 b = p->binding_handle;
8951 ctx = talloc_zero(torture, struct torture_samr_context);
8953 ctx->choice = TORTURE_SAMR_PASSWORDS_BADPWDCOUNT;
8954 ctx->machine_credentials = machine_credentials;
8956 ret &= test_Connect(b, torture, &ctx->handle);
8958 ret &= test_EnumDomains(p, torture, ctx);
8960 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8965 struct torture_suite *torture_rpc_samr_passwords_badpwdcount(TALLOC_CTX *mem_ctx)
8967 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.passwords.badpwdcount");
8968 struct torture_rpc_tcase *tcase;
8970 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8972 TEST_ACCOUNT_NAME_PWD);
8974 torture_rpc_tcase_add_test_creds(tcase, "badPwdCount",
8975 torture_rpc_samr_badpwdcount);
8980 static bool torture_rpc_samr_lockout(struct torture_context *torture,
8981 struct dcerpc_pipe *p2,
8982 struct cli_credentials *machine_credentials)
8985 struct dcerpc_pipe *p;
8987 struct torture_samr_context *ctx;
8988 struct dcerpc_binding_handle *b;
8990 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8991 if (!NT_STATUS_IS_OK(status)) {
8994 b = p->binding_handle;
8996 ctx = talloc_zero(torture, struct torture_samr_context);
8998 ctx->choice = TORTURE_SAMR_PASSWORDS_LOCKOUT;
8999 ctx->machine_credentials = machine_credentials;
9001 ret &= test_Connect(b, torture, &ctx->handle);
9003 ret &= test_EnumDomains(p, torture, ctx);
9005 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
9010 struct torture_suite *torture_rpc_samr_passwords_lockout(TALLOC_CTX *mem_ctx)
9012 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.passwords.lockout");
9013 struct torture_rpc_tcase *tcase;
9015 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
9017 TEST_ACCOUNT_NAME_PWD);
9019 torture_rpc_tcase_add_test_creds(tcase, "lockout",
9020 torture_rpc_samr_lockout);
9025 struct torture_suite *torture_rpc_samr_passwords_validate(TALLOC_CTX *mem_ctx)
9027 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.passwords.validate");
9028 struct torture_rpc_tcase *tcase;
9030 tcase = torture_suite_add_rpc_iface_tcase(suite, "samr",
9032 torture_rpc_tcase_add_test(tcase, "validate",
9033 test_samr_ValidatePassword);