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];
2263 struct samr_GetDomPwInfo dom_pw_info;
2264 struct samr_PwInfo info;
2266 struct lsa_String domain_name;
2268 domain_name.string = "";
2269 dom_pw_info.in.domain_name = &domain_name;
2270 dom_pw_info.out.info = &info;
2272 torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name);
2274 torture_assert(tctx, *password != NULL,
2275 "Failing ChangePasswordUser2 as old password was NULL. Previous test failed?");
2276 oldpass = *password;
2279 int policy_min_pw_len = 0;
2280 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDomPwInfo_r(b, tctx, &dom_pw_info),
2281 "GetDomPwInfo failed");
2282 if (NT_STATUS_IS_OK(dom_pw_info.out.result)) {
2283 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
2286 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2289 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2290 init_lsa_String(&account, acct_name);
2292 E_md4hash(oldpass, old_nt_hash);
2293 E_md4hash(newpass, new_nt_hash);
2295 E_deshash(oldpass, old_lm_hash);
2296 E_deshash(newpass, new_lm_hash);
2298 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
2299 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2300 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2302 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2303 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2304 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2306 r.in.server = &server;
2307 r.in.account = &account;
2308 r.in.nt_password = &nt_pass;
2309 r.in.nt_verifier = &nt_verifier;
2311 r.in.lm_password = &lm_pass;
2312 r.in.lm_verifier = &lm_verifier;
2314 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser2_r(b, tctx, &r),
2315 "ChangePasswordUser2 failed");
2316 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2317 __location__, __FUNCTION__,
2318 oldpass, newpass, nt_errstr(r.out.result));
2320 if (allow_password_restriction && NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
2321 torture_comment(tctx, "ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(r.out.result));
2322 } else if (!NT_STATUS_IS_OK(r.out.result)) {
2323 torture_result(tctx, TORTURE_FAIL, "ChangePasswordUser2 failed - %s\n", nt_errstr(r.out.result));
2326 *password = newpass;
2333 static bool test_ChangePasswordUser2_ntstatus(struct dcerpc_pipe *p, struct torture_context *tctx,
2334 const char *acct_name,
2335 const char *password, NTSTATUS status)
2337 struct samr_ChangePasswordUser2 r;
2338 struct lsa_String server, account;
2339 struct samr_CryptPassword nt_pass, lm_pass;
2340 struct samr_Password nt_verifier, lm_verifier;
2341 const char *oldpass;
2342 struct dcerpc_binding_handle *b = p->binding_handle;
2343 uint8_t old_nt_hash[16], new_nt_hash[16];
2344 uint8_t old_lm_hash[16], new_lm_hash[16];
2346 struct samr_GetDomPwInfo dom_pw_info;
2347 struct samr_PwInfo info;
2349 struct lsa_String domain_name;
2351 int policy_min_pw_len = 0;
2353 domain_name.string = "";
2354 dom_pw_info.in.domain_name = &domain_name;
2355 dom_pw_info.out.info = &info;
2357 torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name);
2361 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDomPwInfo_r(b, tctx, &dom_pw_info),
2362 "GetDomPwInfo failed");
2363 if (NT_STATUS_IS_OK(dom_pw_info.out.result)) {
2364 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
2367 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2369 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2370 init_lsa_String(&account, acct_name);
2372 E_md4hash(oldpass, old_nt_hash);
2373 E_md4hash(newpass, new_nt_hash);
2375 E_deshash(oldpass, old_lm_hash);
2376 E_deshash(newpass, new_lm_hash);
2378 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
2379 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2380 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2382 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2383 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2384 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2386 r.in.server = &server;
2387 r.in.account = &account;
2388 r.in.nt_password = &nt_pass;
2389 r.in.nt_verifier = &nt_verifier;
2391 r.in.lm_password = &lm_pass;
2392 r.in.lm_verifier = &lm_verifier;
2394 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser2_r(b, tctx, &r),
2395 "ChangePasswordUser2 failed");
2396 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2397 __location__, __FUNCTION__,
2398 oldpass, newpass, nt_errstr(r.out.result));
2400 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
2401 torture_comment(tctx, "ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(r.out.result));
2403 torture_assert_ntstatus_equal(tctx, r.out.result, status, "ChangePasswordUser2 returned unexpected value");
2410 bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tctx,
2411 const char *account_string,
2412 int policy_min_pw_len,
2414 const char *newpass,
2415 NTTIME last_password_change,
2416 bool handle_reject_reason)
2418 struct samr_ChangePasswordUser3 r;
2420 struct lsa_String server, account, account_bad;
2421 struct samr_CryptPassword nt_pass, lm_pass;
2422 struct samr_Password nt_verifier, lm_verifier;
2424 struct dcerpc_binding_handle *b = p->binding_handle;
2425 uint8_t old_nt_hash[16], new_nt_hash[16];
2426 uint8_t old_lm_hash[16], new_lm_hash[16];
2428 struct samr_DomInfo1 *dominfo = NULL;
2429 struct userPwdChangeFailureInformation *reject = NULL;
2431 torture_comment(tctx, "Testing ChangePasswordUser3\n");
2433 if (newpass == NULL) {
2435 if (policy_min_pw_len == 0) {
2436 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2438 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len);
2440 } while (check_password_quality(newpass) == false);
2442 torture_comment(tctx, "Using password '%s'\n", newpass);
2445 torture_assert(tctx, *password != NULL,
2446 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2448 oldpass = *password;
2449 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2450 init_lsa_String(&account, account_string);
2452 E_md4hash(oldpass, old_nt_hash);
2453 E_md4hash(newpass, new_nt_hash);
2455 E_deshash(oldpass, old_lm_hash);
2456 E_deshash(newpass, new_lm_hash);
2458 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2459 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2460 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2462 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2463 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2464 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2466 /* Break the verification */
2467 nt_verifier.hash[0]++;
2469 r.in.server = &server;
2470 r.in.account = &account;
2471 r.in.nt_password = &nt_pass;
2472 r.in.nt_verifier = &nt_verifier;
2474 r.in.lm_password = &lm_pass;
2475 r.in.lm_verifier = &lm_verifier;
2476 r.in.password3 = NULL;
2477 r.out.dominfo = &dominfo;
2478 r.out.reject = &reject;
2480 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2481 "ChangePasswordUser3 failed");
2482 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2483 __location__, __FUNCTION__,
2484 oldpass, newpass, nt_errstr(r.out.result));
2485 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION) &&
2486 (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD))) {
2487 torture_result(tctx, TORTURE_FAIL, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
2488 nt_errstr(r.out.result));
2492 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2493 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2494 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2496 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2497 /* Break the NT hash */
2499 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2500 /* Unbreak it again */
2502 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2504 r.in.server = &server;
2505 r.in.account = &account;
2506 r.in.nt_password = &nt_pass;
2507 r.in.nt_verifier = &nt_verifier;
2509 r.in.lm_password = &lm_pass;
2510 r.in.lm_verifier = &lm_verifier;
2511 r.in.password3 = NULL;
2512 r.out.dominfo = &dominfo;
2513 r.out.reject = &reject;
2515 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2516 "ChangePasswordUser3 failed");
2517 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2518 __location__, __FUNCTION__,
2519 oldpass, newpass, nt_errstr(r.out.result));
2520 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION) &&
2521 (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD))) {
2522 torture_result(tctx, TORTURE_FAIL, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
2523 nt_errstr(r.out.result));
2527 /* This shouldn't be a valid name */
2528 init_lsa_String(&account_bad, talloc_asprintf(tctx, "%sXX", account_string));
2530 r.in.account = &account_bad;
2531 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2532 "ChangePasswordUser3 failed");
2533 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2534 __location__, __FUNCTION__,
2535 oldpass, newpass, nt_errstr(r.out.result));
2536 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD)) {
2537 torture_result(tctx, TORTURE_FAIL, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
2538 nt_errstr(r.out.result));
2542 E_md4hash(oldpass, old_nt_hash);
2543 E_md4hash(newpass, new_nt_hash);
2545 E_deshash(oldpass, old_lm_hash);
2546 E_deshash(newpass, new_lm_hash);
2548 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2549 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2550 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2552 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2553 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2554 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2556 r.in.server = &server;
2557 r.in.account = &account;
2558 r.in.nt_password = &nt_pass;
2559 r.in.nt_verifier = &nt_verifier;
2561 r.in.lm_password = &lm_pass;
2562 r.in.lm_verifier = &lm_verifier;
2563 r.in.password3 = NULL;
2564 r.out.dominfo = &dominfo;
2565 r.out.reject = &reject;
2567 unix_to_nt_time(&t, time(NULL));
2569 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2570 "ChangePasswordUser3 failed");
2571 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2572 __location__, __FUNCTION__,
2573 oldpass, newpass, nt_errstr(r.out.result));
2575 torture_comment(tctx, "(%s): dominfo[%s], reject[%s], handle_reject_reason[%s], "
2576 "last_password_change[%s], dominfo->min_password_age[%lld]\n",
2578 (dominfo == NULL)? "NULL" : "present",
2579 reject ? "true" : "false",
2580 handle_reject_reason ? "true" : "false",
2581 null_nttime(last_password_change) ? "null" : "not null",
2582 dominfo ? (long long)dominfo->min_password_age : (long long)0);
2584 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)
2587 && handle_reject_reason
2588 && (!null_nttime(last_password_change) || !dominfo->min_password_age)) {
2589 if (dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
2591 if (reject && (reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR)) {
2592 torture_result(tctx, TORTURE_FAIL, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2593 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2598 /* We tested the order of precendence which is as follows:
2607 if ((dominfo->min_password_age < 0) && !null_nttime(last_password_change) &&
2608 (last_password_change - dominfo->min_password_age > t)) {
2610 if (reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2611 torture_result(tctx, TORTURE_FAIL, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2612 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2616 } else if ((dominfo->min_password_length > 0) &&
2617 (strlen(newpass) < dominfo->min_password_length)) {
2619 if (reject->extendedFailureReason != SAM_PWD_CHANGE_PASSWORD_TOO_SHORT) {
2620 torture_result(tctx, TORTURE_FAIL, "expected SAM_PWD_CHANGE_PASSWORD_TOO_SHORT (%d), got %d\n",
2621 SAM_PWD_CHANGE_PASSWORD_TOO_SHORT, reject->extendedFailureReason);
2625 } else if ((dominfo->password_history_length > 0) &&
2626 strequal(oldpass, newpass)) {
2628 if (reject->extendedFailureReason != SAM_PWD_CHANGE_PWD_IN_HISTORY) {
2629 torture_result(tctx, TORTURE_FAIL, "expected SAM_PWD_CHANGE_PWD_IN_HISTORY (%d), got %d\n",
2630 SAM_PWD_CHANGE_PWD_IN_HISTORY, reject->extendedFailureReason);
2633 } else if (dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
2635 if (reject->extendedFailureReason != SAM_PWD_CHANGE_NOT_COMPLEX) {
2636 torture_result(tctx, TORTURE_FAIL, "expected SAM_PWD_CHANGE_NOT_COMPLEX (%d), got %d\n",
2637 SAM_PWD_CHANGE_NOT_COMPLEX, reject->extendedFailureReason);
2643 if (reject->extendedFailureReason == SAM_PWD_CHANGE_PASSWORD_TOO_SHORT) {
2644 /* retry with adjusted size */
2645 return test_ChangePasswordUser3(p, tctx, account_string,
2646 dominfo->min_password_length,
2647 password, NULL, 0, false);
2651 } else if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
2652 if (reject && reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2653 torture_result(tctx, TORTURE_FAIL, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2654 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2657 /* Perhaps the server has a 'min password age' set? */
2660 torture_assert_ntstatus_ok(tctx, r.out.result, "ChangePasswordUser3");
2662 *password = talloc_strdup(tctx, newpass);
2668 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_context *tctx,
2669 const char *account_string,
2670 struct policy_handle *handle,
2674 struct samr_ChangePasswordUser3 r;
2675 struct samr_SetUserInfo s;
2676 union samr_UserInfo u;
2677 DATA_BLOB session_key;
2678 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
2679 uint8_t confounder[16];
2680 gnutls_hash_hd_t hash_hnd;
2683 struct lsa_String server, account;
2684 struct samr_CryptPassword nt_pass;
2685 struct samr_Password nt_verifier;
2686 DATA_BLOB new_random_pass;
2689 struct dcerpc_binding_handle *b = p->binding_handle;
2690 uint8_t old_nt_hash[16], new_nt_hash[16];
2692 struct samr_DomInfo1 *dominfo = NULL;
2693 struct userPwdChangeFailureInformation *reject = NULL;
2695 new_random_pass = samr_very_rand_pass(tctx, 128);
2697 torture_assert(tctx, *password != NULL,
2698 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2700 oldpass = *password;
2701 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2702 init_lsa_String(&account, account_string);
2704 s.in.user_handle = handle;
2710 u.info25.info.fields_present = SAMR_FIELD_NT_PASSWORD_PRESENT;
2712 set_pw_in_buffer(u.info25.password.data, &new_random_pass);
2714 status = dcerpc_fetch_session_key(p, &session_key);
2715 if (!NT_STATUS_IS_OK(status)) {
2716 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u - no session key - %s\n",
2717 s.in.level, nt_errstr(status));
2721 generate_random_buffer((uint8_t *)confounder, 16);
2723 gnutls_hash_init(&hash_hnd, GNUTLS_DIG_MD5);
2724 gnutls_hash(hash_hnd, confounder, 16);
2725 gnutls_hash(hash_hnd, session_key.data, session_key.length);
2726 gnutls_hash_deinit(hash_hnd, confounded_session_key.data);
2728 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
2729 memcpy(&u.info25.password.data[516], confounder, 16);
2731 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
2733 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
2734 "SetUserInfo failed");
2735 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2736 __location__, __FUNCTION__,
2737 oldpass, "RANDOM", nt_errstr(s.out.result));
2738 if (!NT_STATUS_IS_OK(s.out.result)) {
2739 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u failed - %s\n",
2740 s.in.level, nt_errstr(s.out.result));
2744 torture_comment(tctx, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
2746 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2748 new_random_pass = samr_very_rand_pass(tctx, 128);
2750 mdfour(new_nt_hash, new_random_pass.data, new_random_pass.length);
2752 set_pw_in_buffer(nt_pass.data, &new_random_pass);
2753 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2754 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2756 r.in.server = &server;
2757 r.in.account = &account;
2758 r.in.nt_password = &nt_pass;
2759 r.in.nt_verifier = &nt_verifier;
2761 r.in.lm_password = NULL;
2762 r.in.lm_verifier = NULL;
2763 r.in.password3 = NULL;
2764 r.out.dominfo = &dominfo;
2765 r.out.reject = &reject;
2767 unix_to_nt_time(&t, time(NULL));
2769 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2770 "ChangePasswordUser3 failed");
2771 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2772 __location__, __FUNCTION__,
2773 oldpass, "RANDOM", nt_errstr(r.out.result));
2775 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
2776 if (reject && reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2777 torture_result(tctx, TORTURE_FAIL, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2778 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2781 /* Perhaps the server has a 'min password age' set? */
2783 } else if (!NT_STATUS_IS_OK(r.out.result)) {
2784 torture_result(tctx, TORTURE_FAIL, "ChangePasswordUser3 failed - %s\n", nt_errstr(r.out.result));
2788 newpass = samr_rand_pass(tctx, 128);
2790 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2792 E_md4hash(newpass, new_nt_hash);
2794 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2795 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2796 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2798 r.in.server = &server;
2799 r.in.account = &account;
2800 r.in.nt_password = &nt_pass;
2801 r.in.nt_verifier = &nt_verifier;
2803 r.in.lm_password = NULL;
2804 r.in.lm_verifier = NULL;
2805 r.in.password3 = NULL;
2806 r.out.dominfo = &dominfo;
2807 r.out.reject = &reject;
2809 unix_to_nt_time(&t, time(NULL));
2811 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2812 "ChangePasswordUser3 failed");
2813 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2814 __location__, __FUNCTION__,
2815 oldpass, newpass, nt_errstr(r.out.result));
2817 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
2818 if (reject && reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2819 torture_result(tctx, TORTURE_FAIL, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2820 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2823 /* Perhaps the server has a 'min password age' set? */
2826 torture_assert_ntstatus_ok(tctx, r.out.result, "ChangePasswordUser3 (on second random password)");
2827 *password = talloc_strdup(tctx, newpass);
2834 static bool test_GetMembersInAlias(struct dcerpc_binding_handle *b,
2835 struct torture_context *tctx,
2836 struct policy_handle *alias_handle)
2838 struct samr_GetMembersInAlias r;
2839 struct lsa_SidArray sids;
2841 torture_comment(tctx, "Testing GetMembersInAlias\n");
2843 r.in.alias_handle = alias_handle;
2846 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetMembersInAlias_r(b, tctx, &r),
2847 "GetMembersInAlias failed");
2848 torture_assert_ntstatus_ok(tctx, r.out.result, "GetMembersInAlias failed");
2853 static bool test_AddMemberToAlias(struct dcerpc_binding_handle *b,
2854 struct torture_context *tctx,
2855 struct policy_handle *alias_handle,
2856 const struct dom_sid *domain_sid)
2858 struct samr_AddAliasMember r;
2859 struct samr_DeleteAliasMember d;
2860 struct dom_sid *sid;
2862 sid = dom_sid_add_rid(tctx, domain_sid, 512);
2864 torture_comment(tctx, "Testing AddAliasMember\n");
2865 r.in.alias_handle = alias_handle;
2868 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddAliasMember_r(b, tctx, &r),
2869 "AddAliasMember failed");
2870 torture_assert_ntstatus_ok(tctx, r.out.result, "AddAliasMember failed");
2872 d.in.alias_handle = alias_handle;
2875 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteAliasMember_r(b, tctx, &d),
2876 "DeleteAliasMember failed");
2877 torture_assert_ntstatus_ok(tctx, d.out.result, "DelAliasMember failed");
2882 static bool test_AddMultipleMembersToAlias(struct dcerpc_binding_handle *b,
2883 struct torture_context *tctx,
2884 struct policy_handle *alias_handle)
2886 struct samr_AddMultipleMembersToAlias a;
2887 struct samr_RemoveMultipleMembersFromAlias r;
2888 struct lsa_SidArray sids;
2890 torture_comment(tctx, "Testing AddMultipleMembersToAlias\n");
2891 a.in.alias_handle = alias_handle;
2895 sids.sids = talloc_array(tctx, struct lsa_SidPtr, 3);
2897 sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2898 sids.sids[1].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-2");
2899 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-3");
2901 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddMultipleMembersToAlias_r(b, tctx, &a),
2902 "AddMultipleMembersToAlias failed");
2903 torture_assert_ntstatus_ok(tctx, a.out.result, "AddMultipleMembersToAlias");
2906 torture_comment(tctx, "Testing RemoveMultipleMembersFromAlias\n");
2907 r.in.alias_handle = alias_handle;
2910 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RemoveMultipleMembersFromAlias_r(b, tctx, &r),
2911 "RemoveMultipleMembersFromAlias failed");
2912 torture_assert_ntstatus_ok(tctx, r.out.result, "RemoveMultipleMembersFromAlias failed");
2914 /* strange! removing twice doesn't give any error */
2915 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RemoveMultipleMembersFromAlias_r(b, tctx, &r),
2916 "RemoveMultipleMembersFromAlias failed");
2917 torture_assert_ntstatus_ok(tctx, r.out.result, "RemoveMultipleMembersFromAlias failed");
2919 /* but removing an alias that isn't there does */
2920 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-4");
2922 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RemoveMultipleMembersFromAlias_r(b, tctx, &r),
2923 "RemoveMultipleMembersFromAlias failed");
2924 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND, "RemoveMultipleMembersFromAlias");
2929 static bool test_GetAliasMembership(struct dcerpc_binding_handle *b,
2930 struct torture_context *tctx,
2931 struct policy_handle *domain_handle)
2933 struct samr_GetAliasMembership r;
2934 struct lsa_SidArray sids;
2935 struct samr_Ids rids;
2937 torture_comment(tctx, "Testing GetAliasMembership\n");
2939 r.in.domain_handle = domain_handle;
2944 sids.sids = talloc_zero_array(tctx, struct lsa_SidPtr, sids.num_sids);
2946 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetAliasMembership_r(b, tctx, &r),
2947 "GetAliasMembership failed");
2948 torture_assert_ntstatus_ok(tctx, r.out.result,
2949 "samr_GetAliasMembership failed");
2951 torture_assert_int_equal(tctx, sids.num_sids, rids.count,
2952 "protocol misbehaviour");
2955 sids.sids = talloc_zero_array(tctx, struct lsa_SidPtr, sids.num_sids);
2956 sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2958 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetAliasMembership_r(b, tctx, &r),
2959 "samr_GetAliasMembership failed");
2960 torture_assert_ntstatus_ok(tctx, r.out.result,
2961 "samr_GetAliasMembership failed");
2964 /* only true for w2k8 it seems
2965 * win7, xp, w2k3 will return a 0 length array pointer */
2967 if (rids.ids && (rids.count == 0)) {
2968 torture_fail(tctx, "samr_GetAliasMembership returned 0 count and a rids array");
2971 if (!rids.ids && rids.count) {
2972 torture_fail(tctx, "samr_GetAliasMembership returned non-0 count but no rids");
2978 static bool test_TestPrivateFunctionsUser(struct dcerpc_binding_handle *b,
2979 struct torture_context *tctx,
2980 struct policy_handle *user_handle)
2982 struct samr_TestPrivateFunctionsUser r;
2984 torture_comment(tctx, "Testing TestPrivateFunctionsUser\n");
2986 r.in.user_handle = user_handle;
2988 torture_assert_ntstatus_ok(tctx, dcerpc_samr_TestPrivateFunctionsUser_r(b, tctx, &r),
2989 "TestPrivateFunctionsUser failed");
2990 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsUser");
2995 static bool test_QueryUserInfo_pwdlastset(struct dcerpc_binding_handle *b,
2996 struct torture_context *tctx,
2997 struct policy_handle *handle,
3002 uint16_t levels[] = { /* 3, */ 5, 21 };
3004 /* NTTIME pwdlastset3 = 0; */
3005 NTTIME pwdlastset5 = 0;
3006 NTTIME pwdlastset21 = 0;
3008 torture_comment(tctx, "Testing QueryUserInfo%s level 5 and 21 call ",
3009 use_info2 ? "2":"");
3011 for (i=0; i<ARRAY_SIZE(levels); i++) {
3013 struct samr_QueryUserInfo r;
3014 struct samr_QueryUserInfo2 r2;
3015 union samr_UserInfo *info;
3018 r2.in.user_handle = handle;
3019 r2.in.level = levels[i];
3020 r2.out.info = &info;
3021 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo2_r(b, tctx, &r2),
3022 "QueryUserInfo2 failed");
3023 status = r2.out.result;
3026 r.in.user_handle = handle;
3027 r.in.level = levels[i];
3029 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
3030 "QueryUserInfo failed");
3031 status = r.out.result;
3034 if (!NT_STATUS_IS_OK(status) &&
3035 !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
3036 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo%s level %u failed - %s\n",
3037 use_info2 ? "2":"", levels[i], nt_errstr(status));
3041 switch (levels[i]) {
3043 /* pwdlastset3 = info->info3.last_password_change; */
3046 pwdlastset5 = info->info5.last_password_change;
3049 pwdlastset21 = info->info21.last_password_change;
3055 /* torture_assert_int_equal(tctx, pwdlastset3, pwdlastset5,
3056 "pwdlastset mixup"); */
3057 torture_assert_int_equal(tctx, pwdlastset5, pwdlastset21,
3058 "pwdlastset mixup");
3060 *pwdlastset = pwdlastset21;
3062 torture_comment(tctx, "(pwdlastset: %llu)\n",
3063 (unsigned long long) *pwdlastset);
3068 static bool test_SamLogon(struct torture_context *tctx,
3069 struct dcerpc_pipe *p,
3070 struct cli_credentials *machine_credentials,
3071 struct cli_credentials *test_credentials,
3072 NTSTATUS expected_result,
3076 struct netr_LogonSamLogonEx r;
3077 union netr_LogonLevel logon;
3078 union netr_Validation validation;
3079 uint8_t authoritative;
3080 struct netr_IdentityInfo identity;
3081 struct netr_NetworkInfo ninfo;
3082 struct netr_PasswordInfo pinfo;
3083 DATA_BLOB names_blob, chal, lm_resp, nt_resp;
3084 int flags = CLI_CRED_NTLM_AUTH;
3085 uint32_t samlogon_flags = 0;
3086 struct netlogon_creds_CredentialState *creds;
3087 struct netr_Authenticator a;
3088 struct dcerpc_binding_handle *b = p->binding_handle;
3090 torture_assert(tctx, (creds = cli_credentials_get_netlogon_creds(machine_credentials)), "");
3092 if (lpcfg_client_lanman_auth(tctx->lp_ctx)) {
3093 flags |= CLI_CRED_LANMAN_AUTH;
3096 if (lpcfg_client_ntlmv2_auth(tctx->lp_ctx)) {
3097 flags |= CLI_CRED_NTLMv2_AUTH;
3100 cli_credentials_get_ntlm_username_domain(test_credentials, tctx,
3101 &identity.account_name.string,
3102 &identity.domain_name.string);
3104 identity.parameter_control =
3105 MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT |
3106 MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;
3107 identity.logon_id = 0;
3108 identity.workstation.string = cli_credentials_get_workstation(test_credentials);
3111 netlogon_creds_client_authenticator(creds, &a);
3113 if (!E_deshash(cli_credentials_get_password(test_credentials), pinfo.lmpassword.hash)) {
3114 ZERO_STRUCT(pinfo.lmpassword.hash);
3116 E_md4hash(cli_credentials_get_password(test_credentials), pinfo.ntpassword.hash);
3118 if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
3119 netlogon_creds_aes_encrypt(creds, pinfo.lmpassword.hash, 16);
3120 netlogon_creds_aes_encrypt(creds, pinfo.ntpassword.hash, 16);
3121 } else if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
3122 netlogon_creds_arcfour_crypt(creds, pinfo.lmpassword.hash, 16);
3123 netlogon_creds_arcfour_crypt(creds, pinfo.ntpassword.hash, 16);
3125 netlogon_creds_des_encrypt(creds, &pinfo.lmpassword);
3126 netlogon_creds_des_encrypt(creds, &pinfo.ntpassword);
3129 pinfo.identity_info = identity;
3130 logon.password = &pinfo;
3132 r.in.logon_level = NetlogonInteractiveInformation;
3134 generate_random_buffer(ninfo.challenge,
3135 sizeof(ninfo.challenge));
3136 chal = data_blob_const(ninfo.challenge,
3137 sizeof(ninfo.challenge));
3139 names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(test_credentials),
3140 cli_credentials_get_domain(test_credentials));
3142 status = cli_credentials_get_ntlm_response(test_credentials, tctx,
3145 NULL, /* server_timestamp */
3149 torture_assert_ntstatus_ok(tctx, status, "cli_credentials_get_ntlm_response failed");
3151 ninfo.lm.data = lm_resp.data;
3152 ninfo.lm.length = lm_resp.length;
3154 ninfo.nt.data = nt_resp.data;
3155 ninfo.nt.length = nt_resp.length;
3157 ninfo.identity_info = identity;
3158 logon.network = &ninfo;
3160 r.in.logon_level = NetlogonNetworkInformation;
3163 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3164 r.in.computer_name = cli_credentials_get_workstation(test_credentials);
3165 r.in.logon = &logon;
3166 r.in.flags = &samlogon_flags;
3167 r.out.flags = &samlogon_flags;
3168 r.out.validation = &validation;
3169 r.out.authoritative = &authoritative;
3171 torture_comment(tctx, "Testing LogonSamLogon with name %s\n", identity.account_name.string);
3173 r.in.validation_level = 6;
3175 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogonEx_r(b, tctx, &r),
3176 "netr_LogonSamLogonEx failed");
3177 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_INFO_CLASS)) {
3178 r.in.validation_level = 3;
3179 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogonEx_r(b, tctx, &r),
3180 "netr_LogonSamLogonEx failed");
3182 if (!NT_STATUS_IS_OK(r.out.result)) {
3183 torture_assert_ntstatus_equal(tctx, r.out.result, expected_result, "LogonSamLogonEx failed");
3186 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogonEx failed");
3192 static bool test_SamLogon_with_creds(struct torture_context *tctx,
3193 struct dcerpc_pipe *p,
3194 struct cli_credentials *machine_creds,
3195 const char *acct_name,
3196 const char *password,
3197 NTSTATUS expected_samlogon_result,
3201 struct cli_credentials *test_credentials;
3203 test_credentials = cli_credentials_init(tctx);
3205 cli_credentials_set_workstation(test_credentials,
3206 cli_credentials_get_workstation(machine_creds), CRED_SPECIFIED);
3207 cli_credentials_set_domain(test_credentials,
3208 cli_credentials_get_domain(machine_creds), CRED_SPECIFIED);
3209 cli_credentials_set_username(test_credentials,
3210 acct_name, CRED_SPECIFIED);
3211 cli_credentials_set_password(test_credentials,
3212 password, CRED_SPECIFIED);
3214 torture_comment(tctx, "Testing samlogon (%s) as %s password: %s\n",
3215 interactive ? "interactive" : "network", acct_name, password);
3217 if (!test_SamLogon(tctx, p, machine_creds, test_credentials,
3218 expected_samlogon_result, interactive)) {
3219 torture_result(tctx, TORTURE_FAIL, "new password did not work\n");
3226 static bool test_SetPassword_level(struct dcerpc_pipe *p,
3227 struct dcerpc_pipe *np,
3228 struct torture_context *tctx,
3229 struct policy_handle *handle,
3231 uint32_t fields_present,
3232 uint8_t password_expired,
3233 bool *matched_expected_error,
3235 const char *acct_name,
3237 struct cli_credentials *machine_creds,
3238 bool use_queryinfo2,
3240 NTSTATUS expected_samlogon_result)
3242 const char *fields = NULL;
3244 struct dcerpc_binding_handle *b = p->binding_handle;
3250 fields = talloc_asprintf(tctx, "(fields_present: 0x%08x)",
3257 torture_comment(tctx, "Testing SetUserInfo%s level %d call "
3258 "(password_expired: %d) %s\n",
3259 use_setinfo2 ? "2":"", level, password_expired,
3260 fields ? fields : "");
3262 if (!test_SetUserPass_level_ex(p, tctx, handle, level,
3267 matched_expected_error)) {
3271 if (!test_QueryUserInfo_pwdlastset(b, tctx, handle,
3277 if (*matched_expected_error == true) {
3281 if (!test_SamLogon_with_creds(tctx, np,
3285 expected_samlogon_result,
3293 static bool setup_schannel_netlogon_pipe(struct torture_context *tctx,
3294 struct cli_credentials *credentials,
3295 struct dcerpc_pipe **p)
3297 struct dcerpc_binding *b;
3300 torture_assert_ntstatus_ok(tctx, torture_rpc_binding(tctx, &b),
3301 "failed to get rpc binding");
3303 /* We have to use schannel, otherwise the SamLogonEx fails
3304 * with INTERNAL_ERROR */
3306 status = dcerpc_binding_set_flags(b,
3308 DCERPC_SIGN | DCERPC_SEAL |
3309 DCERPC_SCHANNEL_AUTO,
3310 DCERPC_AUTH_OPTIONS);
3311 torture_assert_ntstatus_ok(tctx, status, "set flags");
3313 torture_assert_ntstatus_ok(tctx,
3314 dcerpc_pipe_connect_b(tctx, p, b, &ndr_table_netlogon,
3315 credentials, tctx->ev, tctx->lp_ctx),
3316 "failed to bind to netlogon");
3321 static bool test_SetPassword_pwdlastset(struct dcerpc_pipe *p,
3322 struct torture_context *tctx,
3323 uint32_t acct_flags,
3324 const char *acct_name,
3325 struct policy_handle *handle,
3327 struct cli_credentials *machine_credentials)
3329 int s = 0, q = 0, f = 0, l = 0, z = 0;
3332 bool set_levels[] = { false, true };
3333 bool query_levels[] = { false, true };
3334 uint32_t levels[] = { 18, 21, 26, 23, 24, 25 }; /* Second half only used when TEST_ALL_LEVELS defined */
3335 uint32_t nonzeros[] = { 1, 24 };
3336 uint32_t fields_present[] = {
3338 SAMR_FIELD_EXPIRED_FLAG,
3339 SAMR_FIELD_LAST_PWD_CHANGE,
3340 SAMR_FIELD_EXPIRED_FLAG | SAMR_FIELD_LAST_PWD_CHANGE,
3342 SAMR_FIELD_NT_PASSWORD_PRESENT,
3343 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
3344 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
3345 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
3346 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
3347 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
3348 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE | SAMR_FIELD_EXPIRED_FLAG
3350 struct dcerpc_pipe *np = NULL;
3352 if (torture_setting_bool(tctx, "samba3", false) ||
3353 torture_setting_bool(tctx, "samba4", false)) {
3355 torture_comment(tctx, "Samba3 has second granularity, setting delay to: %d\n",
3359 torture_assert(tctx, setup_schannel_netlogon_pipe(tctx, machine_credentials, &np), "");
3361 /* set to 1 to enable testing for all possible opcode
3362 (SetUserInfo, SetUserInfo2, QueryUserInfo, QueryUserInfo2)
3365 #define TEST_ALL_LEVELS 1
3366 #define TEST_SET_LEVELS 1
3367 #define TEST_QUERY_LEVELS 1
3369 #ifdef TEST_ALL_LEVELS
3370 for (l=0; l<ARRAY_SIZE(levels); l++) {
3372 for (l=0; l<(ARRAY_SIZE(levels))/2; l++) {
3374 for (z=0; z<ARRAY_SIZE(nonzeros); z++) {
3375 for (f=0; f<ARRAY_SIZE(fields_present); f++) {
3376 #ifdef TEST_SET_LEVELS
3377 for (s=0; s<ARRAY_SIZE(set_levels); s++) {
3379 #ifdef TEST_QUERY_LEVELS
3380 for (q=0; q<ARRAY_SIZE(query_levels); q++) {
3382 NTTIME pwdlastset_old = 0;
3383 NTTIME pwdlastset_new = 0;
3384 bool matched_expected_error = false;
3385 NTSTATUS expected_samlogon_result = NT_STATUS_ACCOUNT_DISABLED;
3387 torture_comment(tctx, "------------------------------\n"
3388 "Testing pwdLastSet attribute for flags: 0x%08x "
3389 "(s: %d (l: %d), q: %d)\n",
3390 acct_flags, s, levels[l], q);
3392 switch (levels[l]) {
3396 if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3397 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT))) {
3398 expected_samlogon_result = NT_STATUS_WRONG_PASSWORD;
3406 /* set a password and force password change (pwdlastset 0) by
3407 * setting the password expired flag to a non-0 value */
3409 if (!test_SetPassword_level(p, np, tctx, handle,
3413 &matched_expected_error,
3417 machine_credentials,
3420 expected_samlogon_result)) {
3424 if (matched_expected_error == true) {
3425 /* skipping on expected failure */
3429 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3430 * set without the SAMR_FIELD_EXPIRED_FLAG */
3432 switch (levels[l]) {
3436 if ((pwdlastset_new != 0) &&
3437 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
3438 torture_comment(tctx, "not considering a non-0 "
3439 "pwdLastSet as a an error as the "
3440 "SAMR_FIELD_EXPIRED_FLAG has not "
3446 if (pwdlastset_new != 0) {
3447 torture_result(tctx, TORTURE_FAIL, "pwdLastSet test failed: "
3448 "expected pwdLastSet 0 but got %llu\n",
3449 (unsigned long long) pwdlastset_old);
3455 switch (levels[l]) {
3459 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3460 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3461 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3462 (pwdlastset_old >= pwdlastset_new)) {
3463 torture_result(tctx, TORTURE_FAIL, "pwdlastset not increasing\n");
3469 pwdlastset_old = pwdlastset_new;
3475 /* set a password, pwdlastset needs to get updated (increased
3476 * value), password_expired value used here is 0 */
3478 if (!test_SetPassword_level(p, np, tctx, handle,
3482 &matched_expected_error,
3486 machine_credentials,
3489 expected_samlogon_result)) {
3493 /* when a password has been changed, pwdlastset must not be 0 afterwards
3494 * and must be larger then the old value */
3496 switch (levels[l]) {
3500 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3501 * password has been changed, old and new pwdlastset
3502 * need to be the same value */
3504 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3505 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3506 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3508 torture_assert_int_equal(tctx, pwdlastset_old,
3509 pwdlastset_new, "pwdlastset must be equal");
3514 if (pwdlastset_old >= pwdlastset_new) {
3515 torture_result(tctx, TORTURE_FAIL, "pwdLastSet test failed: "
3516 "expected last pwdlastset (%llu) < new pwdlastset (%llu)\n",
3517 (unsigned long long) pwdlastset_old,
3518 (unsigned long long) pwdlastset_new);
3521 if (pwdlastset_new == 0) {
3522 torture_result(tctx, TORTURE_FAIL, "pwdLastSet test failed: "
3523 "expected non-0 pwdlastset, got: %llu\n",
3524 (unsigned long long) pwdlastset_new);
3530 switch (levels[l]) {
3534 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3535 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3536 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3537 (pwdlastset_old >= pwdlastset_new)) {
3538 torture_result(tctx, TORTURE_FAIL, "pwdlastset not increasing\n");
3544 pwdlastset_old = pwdlastset_new;
3550 /* set a password, pwdlastset needs to get updated (increased
3551 * value), password_expired value used here is 0 */
3553 if (!test_SetPassword_level(p, np, tctx, handle,
3557 &matched_expected_error,
3561 machine_credentials,
3564 expected_samlogon_result)) {
3568 /* when a password has been changed, pwdlastset must not be 0 afterwards
3569 * and must be larger then the old value */
3571 switch (levels[l]) {
3576 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3577 * password has been changed, old and new pwdlastset
3578 * need to be the same value */
3580 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3581 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3582 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3584 torture_assert_int_equal(tctx, pwdlastset_old,
3585 pwdlastset_new, "pwdlastset must be equal");
3590 if (pwdlastset_old >= pwdlastset_new) {
3591 torture_result(tctx, TORTURE_FAIL, "pwdLastSet test failed: "
3592 "expected last pwdlastset (%llu) < new pwdlastset (%llu)\n",
3593 (unsigned long long) pwdlastset_old,
3594 (unsigned long long) pwdlastset_new);
3597 if (pwdlastset_new == 0) {
3598 torture_result(tctx, TORTURE_FAIL, "pwdLastSet test failed: "
3599 "expected non-0 pwdlastset, got: %llu\n",
3600 (unsigned long long) pwdlastset_new);
3606 switch (levels[l]) {
3610 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3611 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3612 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3613 (pwdlastset_old >= pwdlastset_new)) {
3614 torture_result(tctx, TORTURE_FAIL, "pwdlastset not increasing\n");
3620 pwdlastset_old = pwdlastset_new;
3626 /* set a password and force password change (pwdlastset 0) by
3627 * setting the password expired flag to a non-0 value */
3629 if (!test_SetPassword_level(p, np, tctx, handle,
3633 &matched_expected_error,
3637 machine_credentials,
3640 expected_samlogon_result)) {
3644 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3645 * set without the SAMR_FIELD_EXPIRED_FLAG */
3647 switch (levels[l]) {
3651 if ((pwdlastset_new != 0) &&
3652 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
3653 torture_comment(tctx, "not considering a non-0 "
3654 "pwdLastSet as a an error as the "
3655 "SAMR_FIELD_EXPIRED_FLAG has not "
3660 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3661 * password has been changed, old and new pwdlastset
3662 * need to be the same value */
3664 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3665 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3666 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3668 torture_assert_int_equal(tctx, pwdlastset_old,
3669 pwdlastset_new, "pwdlastset must be equal");
3674 if (pwdlastset_new != 0) {
3675 torture_result(tctx, TORTURE_FAIL, "pwdLastSet test failed: "
3676 "expected pwdLastSet 0, got %llu\n",
3677 (unsigned long long) pwdlastset_old);
3683 switch (levels[l]) {
3687 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3688 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3689 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3690 (pwdlastset_old >= pwdlastset_new)) {
3691 torture_result(tctx, TORTURE_FAIL, "pwdlastset not increasing\n");
3697 /* if the level we are testing does not have a fields_present
3698 * field, skip all fields present tests by setting f to to
3700 switch (levels[l]) {
3704 f = ARRAY_SIZE(fields_present);
3708 #ifdef TEST_QUERY_LEVELS
3711 #ifdef TEST_SET_LEVELS
3714 } /* fields present */
3718 #undef TEST_SET_LEVELS
3719 #undef TEST_QUERY_LEVELS
3726 static bool test_QueryUserInfo_badpwdcount(struct dcerpc_binding_handle *b,
3727 struct torture_context *tctx,
3728 struct policy_handle *handle,
3729 uint32_t *badpwdcount)
3731 union samr_UserInfo *info;
3732 struct samr_QueryUserInfo r;
3734 r.in.user_handle = handle;
3738 torture_comment(tctx, "Testing QueryUserInfo level %d", r.in.level);
3740 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
3741 "failed to query userinfo");
3742 torture_assert_ntstatus_ok(tctx, r.out.result,
3743 "failed to query userinfo");
3745 *badpwdcount = info->info3.bad_password_count;
3747 torture_comment(tctx, " (bad password count: %d)\n", *badpwdcount);
3752 static bool test_SetUserInfo_acct_flags(struct dcerpc_binding_handle *b,
3753 struct torture_context *tctx,
3754 struct policy_handle *user_handle,
3755 uint32_t acct_flags)
3757 struct samr_SetUserInfo r;
3758 union samr_UserInfo user_info;
3760 torture_comment(tctx, "Testing SetUserInfo level 16\n");
3762 user_info.info16.acct_flags = acct_flags;
3764 r.in.user_handle = user_handle;
3766 r.in.info = &user_info;
3768 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &r),
3769 "failed to set account flags");
3770 torture_assert_ntstatus_ok(tctx, r.out.result,
3771 "failed to set account flags");
3776 static bool test_reset_badpwdcount(struct dcerpc_pipe *p,
3777 struct torture_context *tctx,
3778 struct policy_handle *user_handle,
3779 uint32_t acct_flags,
3782 struct dcerpc_binding_handle *b = p->binding_handle;
3784 torture_assert(tctx, test_SetUserPass(p, tctx, user_handle, password),
3785 "failed to set password");
3787 torture_comment(tctx, "Testing SetUserInfo level 16 (enable account)\n");
3789 torture_assert(tctx,
3790 test_SetUserInfo_acct_flags(b, tctx, user_handle,
3791 acct_flags & ~ACB_DISABLED),
3792 "failed to enable user");
3794 torture_assert(tctx, test_SetUserPass(p, tctx, user_handle, password),
3795 "failed to set password");
3800 static bool test_SetDomainInfo(struct dcerpc_binding_handle *b,
3801 struct torture_context *tctx,
3802 struct policy_handle *domain_handle,
3803 enum samr_DomainInfoClass level,
3804 union samr_DomainInfo *info)
3806 struct samr_SetDomainInfo r;
3808 r.in.domain_handle = domain_handle;
3812 torture_assert_ntstatus_ok(tctx,
3813 dcerpc_samr_SetDomainInfo_r(b, tctx, &r),
3814 "failed to set domain info");
3815 torture_assert_ntstatus_ok(tctx, r.out.result,
3816 "failed to set domain info");
3821 static bool test_SetDomainInfo_ntstatus(struct dcerpc_binding_handle *b,
3822 struct torture_context *tctx,
3823 struct policy_handle *domain_handle,
3824 enum samr_DomainInfoClass level,
3825 union samr_DomainInfo *info,
3828 struct samr_SetDomainInfo r;
3830 r.in.domain_handle = domain_handle;
3834 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &r),
3835 "SetDomainInfo failed");
3836 torture_assert_ntstatus_equal(tctx, r.out.result, expected, "");
3841 static bool test_QueryDomainInfo2_level(struct dcerpc_binding_handle *b,
3842 struct torture_context *tctx,
3843 struct policy_handle *domain_handle,
3844 enum samr_DomainInfoClass level,
3845 union samr_DomainInfo **q_info)
3847 struct samr_QueryDomainInfo2 r;
3849 r.in.domain_handle = domain_handle;
3851 r.out.info = q_info;
3853 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo2_r(b, tctx, &r),
3854 "failed to query domain info");
3855 torture_assert_ntstatus_ok(tctx, r.out.result,
3856 "failed to query domain info");
3861 static bool test_Password_badpwdcount(struct dcerpc_pipe *p,
3862 struct dcerpc_pipe *np,
3863 struct torture_context *tctx,
3864 uint32_t acct_flags,
3865 const char *acct_name,
3866 struct policy_handle *domain_handle,
3867 struct policy_handle *user_handle,
3869 struct cli_credentials *machine_credentials,
3870 const char *comment,
3873 NTSTATUS expected_success_status,
3874 struct samr_DomInfo1 *info1,
3875 struct samr_DomInfo12 *info12)
3877 union samr_DomainInfo info;
3880 uint32_t badpwdcount, tmp;
3881 uint32_t password_history_length = 12;
3882 uint32_t lockout_threshold = 15;
3883 uint32_t lockout_seconds = 5;
3884 uint64_t delta_time_factor = 10 * 1000 * 1000;
3885 struct dcerpc_binding_handle *b = p->binding_handle;
3887 if (torture_setting_bool(tctx, "samba3", false)) {
3888 lockout_seconds = 60;
3891 torture_comment(tctx, "\nTesting bad pwd count with: %s\n", comment);
3893 torture_assert(tctx, password_history_length < lockout_threshold,
3894 "password history length needs to be smaller than account lockout threshold for this test");
3899 info.info1 = *info1;
3900 info.info1.password_history_length = password_history_length;
3901 info.info1.min_password_age = 0;
3903 torture_assert(tctx,
3904 test_SetDomainInfo(b, tctx, domain_handle,
3905 DomainPasswordInformation, &info),
3906 "failed to set password history length and min passwd age");
3908 info.info12 = *info12;
3909 info.info12.lockout_threshold = lockout_threshold;
3911 /* set lockout duration of 5 seconds */
3912 info.info12.lockout_duration = ~(lockout_seconds * delta_time_factor);
3913 info.info12.lockout_window = ~(lockout_seconds * delta_time_factor);
3915 torture_assert(tctx,
3916 test_SetDomainInfo(b, tctx, domain_handle,
3917 DomainLockoutInformation, &info),
3918 "failed to set lockout threshold");
3920 /* reset bad pwd count */
3922 torture_assert(tctx,
3923 test_reset_badpwdcount(p, tctx, user_handle, acct_flags, password), "");
3926 /* enable or disable account */
3928 torture_assert(tctx,
3929 test_SetUserInfo_acct_flags(b, tctx, user_handle,
3930 acct_flags | ACB_DISABLED),
3931 "failed to disable user");
3933 torture_assert(tctx,
3934 test_SetUserInfo_acct_flags(b, tctx, user_handle,
3935 acct_flags & ~ACB_DISABLED),
3936 "failed to enable user");
3940 /* setup password history */
3942 passwords = talloc_array(tctx, char *, password_history_length);
3944 for (i=0; i < password_history_length; i++) {
3946 torture_assert(tctx, test_SetUserPass(p, tctx, user_handle, password),
3947 "failed to set password");
3948 passwords[i] = talloc_strdup(tctx, *password);
3950 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3951 acct_name, passwords[i],
3952 expected_success_status, interactive)) {
3953 torture_fail(tctx, "failed to auth with latest password");
3956 torture_assert(tctx,
3957 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
3959 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
3963 /* test with wrong password */
3965 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3966 acct_name, "random_crap",
3967 NT_STATUS_WRONG_PASSWORD, interactive)) {
3968 torture_fail(tctx, "succeeded to authenticate with wrong password");
3971 torture_assert(tctx,
3972 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
3974 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
3977 /* test with latest good password */
3979 if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
3980 passwords[password_history_length-1],
3981 expected_success_status, interactive)) {
3982 torture_fail(tctx, "succeeded to authenticate with wrong password");
3985 torture_assert(tctx,
3986 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
3989 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
3991 /* only enabled accounts get the bad pwd count reset upon
3992 * successful logon */
3993 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
3999 /* test password history */
4001 for (i=0; i < password_history_length; i++) {
4003 torture_comment(tctx, "Testing bad password count behavior with "
4004 "password #%d of #%d\n", i, password_history_length);
4006 /* - network samlogon will succeed auth and not
4007 * increase badpwdcount for 2 last entries
4008 * - interactive samlogon only for the last one */
4010 if (i == password_history_length - 1 ||
4011 (i == password_history_length - 2 && !interactive)) {
4013 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
4014 acct_name, passwords[i],
4015 expected_success_status, interactive)) {
4016 torture_fail(tctx, talloc_asprintf(tctx, "did not successfully to obtain %s for %s login with old password (#%d of #%d in history)",
4017 nt_errstr(expected_success_status),
4018 interactive ? "interactive" : "network", i, password_history_length));
4021 torture_assert(tctx,
4022 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
4025 /* torture_comment(tctx, "expecting bad pwd count to *NOT INCREASE* for pwd history entry %d\n", i); */
4026 torture_assert_int_equal(tctx, badpwdcount, tmp, "unexpected badpwdcount");
4028 /* torture_comment(tctx, "expecting bad pwd count to be 0 for pwd history entry %d\n", i); */
4029 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
4037 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
4038 acct_name, passwords[i],
4039 NT_STATUS_WRONG_PASSWORD, interactive)) {
4040 torture_fail(tctx, talloc_asprintf(tctx, "succeeded to authenticate with old password (#%d of #%d in history)", i, password_history_length));
4043 torture_assert(tctx,
4044 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
4046 /* - network samlogon will fail auth but not increase
4047 * badpwdcount for 3rd last entry
4048 * - interactive samlogon for 3rd and 2nd last entry */
4050 if (i == password_history_length - 3 ||
4051 (i == password_history_length - 2 && interactive)) {
4052 /* torture_comment(tctx, "expecting bad pwd count to *NOT INCREASE * by one for pwd history entry %d\n", i); */
4053 torture_assert_int_equal(tctx, badpwdcount, tmp, "unexpected badpwdcount");
4055 /* torture_comment(tctx, "expecting bad pwd count to increase by one for pwd history entry %d\n", i); */
4056 torture_assert_int_equal(tctx, badpwdcount, tmp + 1, "unexpected badpwdcount");
4065 static bool test_Password_badpwdcount_wrap(struct dcerpc_pipe *p,
4066 struct torture_context *tctx,
4067 uint32_t acct_flags,
4068 const char *acct_name,
4069 struct policy_handle *domain_handle,
4070 struct policy_handle *user_handle,
4072 struct cli_credentials *machine_credentials)
4074 union samr_DomainInfo *q_info, s_info;
4075 struct samr_DomInfo1 info1, _info1;
4076 struct samr_DomInfo12 info12, _info12;
4078 struct dcerpc_binding_handle *b = p->binding_handle;
4079 struct dcerpc_pipe *np;
4083 const char *comment;
4086 NTSTATUS expected_success_status;
4089 .comment = "network logon (disabled account)",
4091 .interactive = false,
4092 .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
4095 .comment = "network logon (enabled account)",
4097 .interactive = false,
4098 .expected_success_status= NT_STATUS_OK
4101 .comment = "interactive logon (disabled account)",
4103 .interactive = true,
4104 .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
4107 .comment = "interactive logon (enabled account)",
4109 .interactive = true,
4110 .expected_success_status= NT_STATUS_OK
4114 torture_assert(tctx, setup_schannel_netlogon_pipe(tctx, machine_credentials, &np), "");
4116 /* backup old policies */
4118 torture_assert(tctx,
4119 test_QueryDomainInfo2_level(b, tctx, domain_handle,
4120 DomainPasswordInformation, &q_info),
4121 "failed to query domain info level 1");
4123 info1 = q_info->info1;
4126 torture_assert(tctx,
4127 test_QueryDomainInfo2_level(b, tctx, domain_handle,
4128 DomainLockoutInformation, &q_info),
4129 "failed to query domain info level 12");
4131 info12 = q_info->info12;
4136 for (i=0; i < ARRAY_SIZE(creds); i++) {
4138 /* skip trust tests for now */
4139 if (acct_flags & ACB_WSTRUST ||
4140 acct_flags & ACB_SVRTRUST ||
4141 acct_flags & ACB_DOMTRUST) {
4145 if (!test_Password_badpwdcount(p, np, tctx, acct_flags, acct_name,
4146 domain_handle, user_handle, password,
4147 machine_credentials,
4150 creds[i].interactive,
4151 creds[i].expected_success_status,
4152 &_info1, &_info12)) {
4153 torture_result(tctx, TORTURE_FAIL, "TEST #%d (%s) failed\n", i, creds[i].comment);
4156 torture_comment(tctx, "TEST #%d (%s) succeeded\n", i, creds[i].comment);
4160 /* restore policies */
4162 s_info.info1 = info1;
4164 torture_assert(tctx,
4165 test_SetDomainInfo(b, tctx, domain_handle,
4166 DomainPasswordInformation, &s_info),
4167 "failed to set password information");
4169 s_info.info12 = info12;
4171 torture_assert(tctx,
4172 test_SetDomainInfo(b, tctx, domain_handle,
4173 DomainLockoutInformation, &s_info),
4174 "failed to set lockout information");
4179 static bool test_QueryUserInfo_lockout(struct dcerpc_binding_handle *b,
4180 struct torture_context *tctx,
4181 struct policy_handle *domain_handle,
4182 const char *acct_name,
4183 uint16_t raw_bad_password_count,
4184 uint16_t effective_bad_password_count,
4185 uint32_t effective_acb_lockout)
4187 struct policy_handle user_handle;
4188 union samr_UserInfo *i;
4189 struct samr_QueryUserInfo r;
4191 NTSTATUS status = test_OpenUser_byname(b, tctx, domain_handle, acct_name, &user_handle);
4192 if (!NT_STATUS_IS_OK(status)) {
4196 r.in.user_handle = &user_handle;
4199 torture_comment(tctx, "Testing QueryUserInfo level %d", r.in.level);
4200 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
4201 "failed to query userinfo");
4202 torture_assert_ntstatus_ok(tctx, r.out.result,
4203 "failed to query userinfo");
4204 torture_comment(tctx, " (acct_flags: 0x%08x) (raw_bad_pwd_count: %u)\n",
4205 i->info3.acct_flags, i->info3.bad_password_count);
4206 torture_assert_int_equal(tctx, i->info3.bad_password_count,
4207 raw_bad_password_count,
4209 torture_assert_int_equal(tctx, i->info3.acct_flags & ACB_AUTOLOCK,
4210 effective_acb_lockout,
4211 "effective acb_lockout");
4214 r.in.user_handle = &user_handle;
4217 torture_comment(tctx, "Testing QueryUserInfo level %d", r.in.level);
4218 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
4219 "failed to query userinfo");
4220 torture_assert_ntstatus_ok(tctx, r.out.result,
4221 "failed to query userinfo");
4222 torture_comment(tctx, " (acct_flags: 0x%08x) (effective_bad_pwd_count: %u)\n",
4223 i->info5.acct_flags, i->info5.bad_password_count);
4224 torture_assert_int_equal(tctx, i->info5.bad_password_count,
4225 effective_bad_password_count,
4226 "effective badpwdcount");
4227 torture_assert_int_equal(tctx, i->info5.acct_flags & ACB_AUTOLOCK,
4228 effective_acb_lockout,
4229 "effective acb_lockout");
4232 r.in.user_handle = &user_handle;
4235 torture_comment(tctx, "Testing QueryUserInfo level %d", r.in.level);
4236 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
4237 "failed to query userinfo");
4238 torture_assert_ntstatus_ok(tctx, r.out.result,
4239 "failed to query userinfo");
4240 torture_comment(tctx, " (acct_flags: 0x%08x)\n",
4241 i->info16.acct_flags);
4242 torture_assert_int_equal(tctx, i->info16.acct_flags & ACB_AUTOLOCK,
4243 effective_acb_lockout,
4244 "effective acb_lockout");
4247 r.in.user_handle = &user_handle;
4250 torture_comment(tctx, "Testing QueryUserInfo level %d", r.in.level);
4251 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
4252 "failed to query userinfo");
4253 torture_assert_ntstatus_ok(tctx, r.out.result,
4254 "failed to query userinfo");
4255 torture_comment(tctx, " (acct_flags: 0x%08x) (effective_bad_pwd_count: %u)\n",
4256 i->info21.acct_flags, i->info21.bad_password_count);
4257 torture_assert_int_equal(tctx, i->info21.bad_password_count,
4258 effective_bad_password_count,
4259 "effective badpwdcount");
4260 torture_assert_int_equal(tctx, i->info21.acct_flags & ACB_AUTOLOCK,
4261 effective_acb_lockout,
4262 "effective acb_lockout");
4265 if (!test_samr_handle_Close(b, tctx, &user_handle)) {
4272 static bool test_Password_lockout(struct dcerpc_pipe *p,
4273 struct dcerpc_pipe *np,
4274 struct torture_context *tctx,
4275 uint32_t acct_flags,
4276 const char *acct_name,
4277 struct policy_handle *domain_handle,
4278 struct policy_handle *user_handle,
4280 struct cli_credentials *machine_credentials,
4281 const char *comment,
4284 uint32_t password_history_length,
4285 NTSTATUS expected_success_status,
4286 struct samr_DomInfo1 *info1,
4287 struct samr_DomInfo12 *info12)
4289 union samr_DomainInfo info;
4290 uint64_t lockout_threshold = 1;
4291 uint32_t lockout_seconds = 5;
4292 uint64_t delta_time_factor = 10 * 1000 * 1000;
4293 struct dcerpc_binding_handle *b = p->binding_handle;
4295 if (torture_setting_bool(tctx, "samba3", false)) {
4296 lockout_seconds = 60;
4299 torture_comment(tctx, "\nTesting account lockout: %s\n", comment);
4303 info.info1 = *info1;
4305 torture_comment(tctx, "setting password history length to %d.\n", password_history_length);
4306 info.info1.password_history_length = password_history_length;
4308 torture_comment(tctx, "setting min password again.\n");
4309 info.info1.min_password_age = 0;
4311 torture_assert(tctx,
4312 test_SetDomainInfo(b, tctx, domain_handle,
4313 DomainPasswordInformation, &info),
4314 "failed to set password history length");
4316 info.info12 = *info12;
4317 info.info12.lockout_threshold = lockout_threshold;
4319 /* set lockout duration < lockout window: should fail */
4320 info.info12.lockout_duration = ~(lockout_seconds * delta_time_factor);
4321 info.info12.lockout_window = ~((lockout_seconds + 1) * delta_time_factor);
4323 torture_assert(tctx,
4324 test_SetDomainInfo_ntstatus(b, tctx, domain_handle,
4325 DomainLockoutInformation, &info,
4326 NT_STATUS_INVALID_PARAMETER),
4327 "setting lockout duration < lockout window gave unexpected result");
4329 info.info12.lockout_duration = 0;
4330 info.info12.lockout_window = 0;
4332 torture_assert(tctx,
4333 test_SetDomainInfo(b, tctx, domain_handle,
4334 DomainLockoutInformation, &info),
4335 "failed to set lockout window and duration to 0");
4338 /* set lockout duration of 5 seconds */
4339 info.info12.lockout_duration = ~(lockout_seconds * delta_time_factor);
4340 info.info12.lockout_window = ~(lockout_seconds * delta_time_factor);
4342 torture_assert(tctx,
4343 test_SetDomainInfo(b, tctx, domain_handle,
4344 DomainLockoutInformation, &info),
4345 "failed to set lockout window and duration to 5 seconds");
4347 /* reset bad pwd count */
4349 torture_assert(tctx,
4350 test_reset_badpwdcount(p, tctx, user_handle, acct_flags, password), "");
4353 /* enable or disable account */
4356 torture_assert(tctx,
4357 test_SetUserInfo_acct_flags(b, tctx, user_handle,
4358 acct_flags | ACB_DISABLED),
4359 "failed to disable user");
4361 torture_assert(tctx,
4362 test_SetUserInfo_acct_flags(b, tctx, user_handle,
4363 acct_flags & ~ACB_DISABLED),
4364 "failed to enable user");
4368 /* test logon with right password */
4370 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
4371 acct_name, *password,
4372 expected_success_status, interactive)) {
4373 torture_fail(tctx, "failed to auth with latest password");
4376 torture_assert(tctx,
4377 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4379 "expected account to not be locked");
4381 /* test with wrong password ==> lockout */
4383 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
4384 acct_name, "random_crap",
4385 NT_STATUS_WRONG_PASSWORD, interactive)) {
4386 torture_fail(tctx, "succeeded to authenticate with wrong password");
4390 * curiously, windows does _not_ return fresh values of
4391 * effective bad_password_count and ACB_AUTOLOCK.
4393 torture_assert(tctx,
4394 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4395 1, 1, ACB_AUTOLOCK),
4396 "expected account to not be locked");
4398 /* test with good password */
4400 if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
4402 NT_STATUS_ACCOUNT_LOCKED_OUT, interactive))
4404 torture_fail(tctx, "authenticate did not return NT_STATUS_ACCOUNT_LOCKED_OUT");
4407 /* bad pwd count should not get updated */
4408 torture_assert(tctx,
4409 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4410 1, 1, ACB_AUTOLOCK),
4411 "expected account to be locked");
4413 torture_assert(tctx,
4414 test_ChangePasswordUser2_ntstatus(p, tctx, acct_name, *password,
4415 NT_STATUS_ACCOUNT_LOCKED_OUT),
4416 "got wrong status from ChangePasswordUser2");
4418 /* bad pwd count should not get updated */
4419 torture_assert(tctx,
4420 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4421 1, 1, ACB_AUTOLOCK),
4422 "expected account to be locked");
4424 torture_assert(tctx,
4425 test_ChangePasswordUser2_ntstatus(p, tctx, acct_name, "random_crap", NT_STATUS_ACCOUNT_LOCKED_OUT),
4426 "got wrong status from ChangePasswordUser2");
4428 /* bad pwd count should not get updated */
4429 torture_assert(tctx,
4430 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4431 1, 1, ACB_AUTOLOCK),
4432 "expected account to be locked");
4434 /* with bad password */
4436 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
4437 acct_name, "random_crap2",
4438 NT_STATUS_ACCOUNT_LOCKED_OUT, interactive))
4440 torture_fail(tctx, "authenticate did not return NT_STATUS_ACCOUNT_LOCKED_OUT");
4443 /* bad pwd count should not get updated */
4444 torture_assert(tctx,
4445 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4446 1, 1, ACB_AUTOLOCK),
4447 "expected account to be locked");
4449 /* let lockout duration expire ==> unlock */
4451 torture_comment(tctx, "let lockout duration expire...\n");
4452 sleep(lockout_seconds + 1);
4454 torture_assert(tctx,
4455 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4457 "expected account to not be locked");
4459 if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
4461 expected_success_status, interactive))
4463 torture_fail(tctx, "failed to authenticate after lockout expired");
4466 if (NT_STATUS_IS_OK(expected_success_status)) {
4467 torture_assert(tctx,
4468 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4470 "expected account to not be locked");
4472 torture_assert(tctx,
4473 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4475 "expected account to not be locked");
4478 torture_assert(tctx,
4479 test_ChangePasswordUser2_ntstatus(p, tctx, acct_name, "random_crap", NT_STATUS_WRONG_PASSWORD),
4480 "got wrong status from ChangePasswordUser2");
4482 torture_assert(tctx,
4483 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4484 1, 1, ACB_AUTOLOCK),
4485 "expected account to be locked");
4487 torture_assert(tctx,
4488 test_ChangePasswordUser2_ntstatus(p, tctx, acct_name, *password, NT_STATUS_ACCOUNT_LOCKED_OUT),
4489 "got wrong status from ChangePasswordUser2");
4491 torture_assert(tctx,
4492 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4493 1, 1, ACB_AUTOLOCK),
4494 "expected account to be locked");
4496 torture_assert(tctx,
4497 test_ChangePasswordUser2_ntstatus(p, tctx, acct_name, "random_crap", NT_STATUS_ACCOUNT_LOCKED_OUT),
4498 "got wrong status from ChangePasswordUser2");
4500 torture_assert(tctx,
4501 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4502 1, 1, ACB_AUTOLOCK),
4503 "expected account to be locked");
4505 /* let lockout duration expire ==> unlock */
4507 torture_comment(tctx, "let lockout duration expire...\n");
4508 sleep(lockout_seconds + 1);
4510 torture_assert(tctx,
4511 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4513 "expected account to not be locked");
4515 if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
4517 expected_success_status, interactive))
4519 torture_fail(tctx, "failed to authenticate after lockout expired");
4522 if (NT_STATUS_IS_OK(expected_success_status)) {
4523 torture_assert(tctx,
4524 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4526 "expected account to not be locked");
4528 torture_assert(tctx,
4529 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4531 "expected account to not be locked");
4534 /* Testing ChangePasswordUser behaviour with 3 attempts */
4535 info.info12.lockout_threshold = 3;
4537 torture_assert(tctx,
4538 test_SetDomainInfo(b, tctx, domain_handle,
4539 DomainLockoutInformation, &info),
4540 "failed to set lockout threshold to 3");
4542 if (NT_STATUS_IS_OK(expected_success_status)) {
4543 torture_assert(tctx,
4544 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4546 "expected account to not be locked");
4548 torture_assert(tctx,
4549 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4551 "expected account to not be locked");
4554 torture_assert(tctx,
4555 test_ChangePasswordUser2_ntstatus(p, tctx, acct_name, "random_crap", NT_STATUS_WRONG_PASSWORD),
4556 "got wrong status from ChangePasswordUser2");
4558 /* bad pwd count will get updated */
4559 torture_assert(tctx,
4560 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4562 "expected account to not be locked");
4564 torture_assert(tctx,
4565 test_ChangePasswordUser2_ntstatus(p, tctx, acct_name, "random_crap", NT_STATUS_WRONG_PASSWORD),
4566 "got wrong status from ChangePasswordUser2");
4568 /* bad pwd count will get updated */
4569 torture_assert(tctx,
4570 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4572 "expected account to not be locked");
4574 torture_assert(tctx,
4575 test_ChangePasswordUser2_ntstatus(p, tctx, acct_name, "random_crap", NT_STATUS_WRONG_PASSWORD),
4576 "got wrong status from ChangePasswordUser2");
4578 /* bad pwd count should get updated */
4579 torture_assert(tctx,
4580 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4581 3, 3, ACB_AUTOLOCK),
4582 "expected account to be locked");
4584 torture_assert(tctx,
4585 test_ChangePasswordUser2_ntstatus(p, tctx, acct_name, *password, NT_STATUS_ACCOUNT_LOCKED_OUT),
4586 "got wrong status from ChangePasswordUser2");
4588 /* bad pwd count should not get updated */
4589 torture_assert(tctx,
4590 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4591 3, 3, ACB_AUTOLOCK),
4592 "expected account to be locked");
4594 /* let lockout duration expire ==> unlock */
4596 torture_comment(tctx, "let lockout duration expire...\n");
4597 sleep(lockout_seconds + 1);
4599 torture_assert(tctx,
4600 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4602 "expected account to not be locked");
4604 torture_assert(tctx,
4605 test_ChangePasswordUser2(p, tctx, acct_name, password, NULL, false),
4606 "got wrong status from ChangePasswordUser2");
4608 torture_assert(tctx,
4609 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4611 "expected account to not be locked");
4613 /* Used to reset the badPwdCount for the other tests */
4614 if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
4616 expected_success_status, interactive))
4618 torture_fail(tctx, "failed to authenticate after lockout expired");
4621 if (NT_STATUS_IS_OK(expected_success_status)) {
4622 torture_assert(tctx,
4623 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4625 "expected account to not be locked");
4627 torture_assert(tctx,
4628 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4630 "expected account to not be locked");
4636 static bool test_Password_lockout_wrap(struct dcerpc_pipe *p,
4637 struct torture_context *tctx,
4638 uint32_t acct_flags,
4639 const char *acct_name,
4640 struct policy_handle *domain_handle,
4641 struct policy_handle *user_handle,
4643 struct cli_credentials *machine_credentials)
4645 union samr_DomainInfo *q_info, s_info;
4646 struct samr_DomInfo1 info1, _info1;
4647 struct samr_DomInfo12 info12, _info12;
4649 struct dcerpc_binding_handle *b = p->binding_handle;
4650 struct dcerpc_pipe *np;
4654 const char *comment;
4657 uint32_t password_history_length;
4658 NTSTATUS expected_success_status;
4661 .comment = "network logon (disabled account)",
4663 .interactive = false,
4664 .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
4667 .comment = "network logon (enabled account)",
4669 .interactive = false,
4670 .expected_success_status= NT_STATUS_OK
4673 .comment = "network logon (enabled account, history len = 1)",
4675 .interactive = false,
4676 .expected_success_status= NT_STATUS_OK,
4677 .password_history_length = 1
4680 .comment = "interactive logon (disabled account)",
4682 .interactive = true,
4683 .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
4686 .comment = "interactive logon (enabled account)",
4688 .interactive = true,
4689 .expected_success_status= NT_STATUS_OK
4692 .comment = "interactive logon (enabled account, history len = 1)",
4694 .interactive = true,
4695 .expected_success_status= NT_STATUS_OK,
4696 .password_history_length = 1
4700 torture_assert(tctx, setup_schannel_netlogon_pipe(tctx, machine_credentials, &np), "");
4702 /* backup old policies */
4704 torture_assert(tctx,
4705 test_QueryDomainInfo2_level(b, tctx, domain_handle,
4706 DomainPasswordInformation, &q_info),
4707 "failed to query domain info level 1");
4709 info1 = q_info->info1;
4712 torture_assert(tctx,
4713 test_QueryDomainInfo2_level(b, tctx, domain_handle,
4714 DomainLockoutInformation, &q_info),
4715 "failed to query domain info level 12");
4717 info12 = q_info->info12;
4722 for (i=0; i < ARRAY_SIZE(creds); i++) {
4724 /* skip trust tests for now */
4725 if (acct_flags & ACB_WSTRUST ||
4726 acct_flags & ACB_SVRTRUST ||
4727 acct_flags & ACB_DOMTRUST) {
4731 test_passed = test_Password_lockout(p, np, tctx, acct_flags, acct_name,
4732 domain_handle, user_handle, password,
4733 machine_credentials,
4736 creds[i].interactive,
4737 creds[i].password_history_length,
4738 creds[i].expected_success_status,
4742 torture_result(tctx, TORTURE_FAIL, "TEST #%d (%s) failed\n", i, creds[i].comment);
4745 torture_comment(tctx, "TEST #%d (%s) succeeded\n", i, creds[i].comment);
4749 /* restore policies */
4751 s_info.info1 = info1;
4753 torture_assert(tctx,
4754 test_SetDomainInfo(b, tctx, domain_handle,
4755 DomainPasswordInformation, &s_info),
4756 "failed to set password information");
4758 s_info.info12 = info12;
4760 torture_assert(tctx,
4761 test_SetDomainInfo(b, tctx, domain_handle,
4762 DomainLockoutInformation, &s_info),
4763 "failed to set lockout information");
4768 static bool test_DeleteUser_with_privs(struct dcerpc_pipe *p,
4769 struct dcerpc_pipe *lp,
4770 struct torture_context *tctx,
4771 struct policy_handle *domain_handle,
4772 struct policy_handle *lsa_handle,
4773 struct policy_handle *user_handle,
4774 const struct dom_sid *domain_sid,
4776 struct cli_credentials *machine_credentials)
4779 struct dcerpc_binding_handle *b = p->binding_handle;
4780 struct dcerpc_binding_handle *lb = lp->binding_handle;
4782 struct policy_handle lsa_acct_handle;
4783 struct dom_sid *user_sid;
4785 user_sid = dom_sid_add_rid(tctx, domain_sid, rid);
4788 struct lsa_EnumAccountRights r;
4789 struct lsa_RightSet rights;
4791 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4793 r.in.handle = lsa_handle;
4794 r.in.sid = user_sid;
4795 r.out.rights = &rights;
4797 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
4798 "lsa_EnumAccountRights failed");
4799 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4800 "Expected enum rights for account to fail");
4804 struct lsa_RightSet rights;
4805 struct lsa_StringLarge names[2];
4806 struct lsa_AddAccountRights r;
4808 torture_comment(tctx, "Testing LSA AddAccountRights\n");
4810 init_lsa_StringLarge(&names[0], "SeMachineAccountPrivilege");
4811 init_lsa_StringLarge(&names[1], NULL);
4814 rights.names = names;
4816 r.in.handle = lsa_handle;
4817 r.in.sid = user_sid;
4818 r.in.rights = &rights;
4820 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_AddAccountRights_r(lb, tctx, &r),
4821 "lsa_AddAccountRights failed");
4822 torture_assert_ntstatus_ok(tctx, r.out.result,
4823 "Failed to add privileges");
4827 struct lsa_RightSet rights;
4828 struct lsa_StringLarge names[2];
4829 struct lsa_AddAccountRights r;
4831 torture_comment(tctx, "Testing LSA AddAccountRights 1\n");
4833 init_lsa_StringLarge(&names[0], "SeInteractiveLogonRight");
4834 init_lsa_StringLarge(&names[1], NULL);
4837 rights.names = names;
4839 r.in.handle = lsa_handle;
4840 r.in.sid = user_sid;
4841 r.in.rights = &rights;
4843 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_AddAccountRights_r(lb, tctx, &r),
4844 "lsa_AddAccountRights 1 failed");
4846 if (torture_setting_bool(tctx, "nt4_dc", false)) {
4848 * The NT4 DC doesn't implement Rights.
4850 torture_assert_ntstatus_equal(tctx, r.out.result,
4851 NT_STATUS_NO_SUCH_PRIVILEGE,
4852 "Add rights failed with incorrect error");
4854 torture_assert_ntstatus_ok(tctx, r.out.result,
4855 "Failed to add rights");
4862 struct lsa_EnumAccounts r;
4863 uint32_t resume_handle = 0;
4864 struct lsa_SidArray lsa_sid_array;
4866 bool found_sid = false;
4868 torture_comment(tctx, "Testing LSA EnumAccounts\n");
4870 r.in.handle = lsa_handle;
4871 r.in.num_entries = 0x1000;
4872 r.in.resume_handle = &resume_handle;
4873 r.out.sids = &lsa_sid_array;
4874 r.out.resume_handle = &resume_handle;
4876 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(lb, tctx, &r),
4877 "lsa_EnumAccounts failed");
4878 torture_assert_ntstatus_ok(tctx, r.out.result,
4879 "Failed to enum accounts");
4881 for (i=0; i < lsa_sid_array.num_sids; i++) {
4882 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
4887 torture_assert(tctx, found_sid,
4888 "failed to list privileged account");
4892 struct lsa_EnumAccountRights r;
4893 struct lsa_RightSet user_rights;
4894 uint32_t expected_count = 2;
4896 if (torture_setting_bool(tctx, "nt4_dc", false)) {
4898 * NT4 DC doesn't store rights.
4903 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4905 r.in.handle = lsa_handle;
4906 r.in.sid = user_sid;
4907 r.out.rights = &user_rights;
4909 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
4910 "lsa_EnumAccountRights failed");
4911 torture_assert_ntstatus_ok(tctx, r.out.result,
4912 "Failed to enum rights for account");
4914 if (user_rights.count < expected_count) {
4915 torture_result(tctx, TORTURE_FAIL, "failed to find newly added rights");
4921 struct lsa_OpenAccount r;
4923 torture_comment(tctx, "Testing LSA OpenAccount\n");
4925 r.in.handle = lsa_handle;
4926 r.in.sid = user_sid;
4927 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4928 r.out.acct_handle = &lsa_acct_handle;
4930 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenAccount_r(lb, tctx, &r),
4931 "lsa_OpenAccount failed");
4932 torture_assert_ntstatus_ok(tctx, r.out.result,
4933 "Failed to open lsa account");
4937 struct lsa_GetSystemAccessAccount r;
4938 uint32_t access_mask;
4940 torture_comment(tctx, "Testing LSA GetSystemAccessAccount\n");
4942 r.in.handle = &lsa_acct_handle;
4943 r.out.access_mask = &access_mask;
4945 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetSystemAccessAccount_r(lb, tctx, &r),
4946 "lsa_GetSystemAccessAccount failed");
4947 torture_assert_ntstatus_ok(tctx, r.out.result,
4948 "Failed to get lsa system access account");
4954 torture_comment(tctx, "Testing LSA Close\n");
4956 r.in.handle = &lsa_acct_handle;
4957 r.out.handle = &lsa_acct_handle;
4959 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_Close_r(lb, tctx, &r),
4960 "lsa_Close failed");
4961 torture_assert_ntstatus_ok(tctx, r.out.result,
4962 "Failed to close lsa");
4966 struct samr_DeleteUser r;
4968 torture_comment(tctx, "Testing SAMR DeleteUser\n");
4970 r.in.user_handle = user_handle;
4971 r.out.user_handle = user_handle;
4973 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, tctx, &r),
4974 "DeleteUser failed");
4975 torture_assert_ntstatus_ok(tctx, r.out.result,
4976 "DeleteUser failed");
4980 struct lsa_EnumAccounts r;
4981 uint32_t resume_handle = 0;
4982 struct lsa_SidArray lsa_sid_array;
4984 bool found_sid = false;
4986 torture_comment(tctx, "Testing LSA EnumAccounts\n");
4988 r.in.handle = lsa_handle;
4989 r.in.num_entries = 0x1000;
4990 r.in.resume_handle = &resume_handle;
4991 r.out.sids = &lsa_sid_array;
4992 r.out.resume_handle = &resume_handle;
4994 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(lb, tctx, &r),
4995 "lsa_EnumAccounts failed");
4996 torture_assert_ntstatus_ok(tctx, r.out.result,
4997 "Failed to enum accounts");
4999 for (i=0; i < lsa_sid_array.num_sids; i++) {
5000 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
5005 torture_assert(tctx, found_sid,
5006 "failed to list privileged account");
5010 struct lsa_EnumAccountRights r;
5011 struct lsa_RightSet user_rights;
5013 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
5015 r.in.handle = lsa_handle;
5016 r.in.sid = user_sid;
5017 r.out.rights = &user_rights;
5019 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
5020 "lsa_EnumAccountRights failed");
5021 torture_assert_ntstatus_ok(tctx, r.out.result,
5022 "Failed to enum rights for account");
5024 if (user_rights.count < 1) {
5025 torture_result(tctx, TORTURE_FAIL, "failed to find newly added rights");
5031 struct lsa_OpenAccount r;
5033 torture_comment(tctx, "Testing LSA OpenAccount\n");
5035 r.in.handle = lsa_handle;
5036 r.in.sid = user_sid;
5037 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5038 r.out.acct_handle = &lsa_acct_handle;
5040 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenAccount_r(lb, tctx, &r),
5041 "lsa_OpenAccount failed");
5042 torture_assert_ntstatus_ok(tctx, r.out.result,
5043 "Failed to open lsa account");
5047 struct lsa_GetSystemAccessAccount r;
5048 uint32_t access_mask;
5050 torture_comment(tctx, "Testing LSA GetSystemAccessAccount\n");
5052 r.in.handle = &lsa_acct_handle;
5053 r.out.access_mask = &access_mask;
5055 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetSystemAccessAccount_r(lb, tctx, &r),
5056 "lsa_GetSystemAccessAccount failed");
5057 torture_assert_ntstatus_ok(tctx, r.out.result,
5058 "Failed to get lsa system access account");
5062 struct lsa_DeleteObject r;
5064 torture_comment(tctx, "Testing LSA DeleteObject\n");
5066 r.in.handle = &lsa_acct_handle;
5067 r.out.handle = &lsa_acct_handle;
5069 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_DeleteObject_r(lb, tctx, &r),
5070 "lsa_DeleteObject failed");
5071 torture_assert_ntstatus_ok(tctx, r.out.result,
5072 "Failed to delete object");
5076 struct lsa_EnumAccounts r;
5077 uint32_t resume_handle = 0;
5078 struct lsa_SidArray lsa_sid_array;
5080 bool found_sid = false;
5082 torture_comment(tctx, "Testing LSA EnumAccounts\n");
5084 r.in.handle = lsa_handle;
5085 r.in.num_entries = 0x1000;
5086 r.in.resume_handle = &resume_handle;
5087 r.out.sids = &lsa_sid_array;
5088 r.out.resume_handle = &resume_handle;
5090 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(lb, tctx, &r),
5091 "lsa_EnumAccounts failed");
5092 torture_assert_ntstatus_ok(tctx, r.out.result,
5093 "Failed to enum accounts");
5095 for (i=0; i < lsa_sid_array.num_sids; i++) {
5096 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
5101 torture_assert(tctx, !found_sid,
5102 "should not have listed privileged account");
5106 struct lsa_EnumAccountRights r;
5107 struct lsa_RightSet user_rights;
5109 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
5111 r.in.handle = lsa_handle;
5112 r.in.sid = user_sid;
5113 r.out.rights = &user_rights;
5115 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
5116 "lsa_EnumAccountRights failed");
5117 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND,
5118 "Failed to enum rights for account");
5124 static bool test_user_ops(struct dcerpc_pipe *p,
5125 struct torture_context *tctx,
5126 struct policy_handle *user_handle,
5127 struct policy_handle *domain_handle,
5128 const struct dom_sid *domain_sid,
5129 uint32_t base_acct_flags,
5130 const char *base_acct_name, enum torture_samr_choice which_ops,
5131 struct cli_credentials *machine_credentials)
5133 char *password = NULL;
5134 struct samr_QueryUserInfo q;
5135 union samr_UserInfo *info;
5137 struct dcerpc_binding_handle *b = p->binding_handle;
5142 const uint32_t password_fields[] = {
5143 SAMR_FIELD_NT_PASSWORD_PRESENT,
5144 SAMR_FIELD_LM_PASSWORD_PRESENT,
5145 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
5149 status = test_LookupName(b, tctx, domain_handle, base_acct_name, &rid);
5150 if (!NT_STATUS_IS_OK(status)) {
5154 switch (which_ops) {
5155 case TORTURE_SAMR_USER_ATTRIBUTES:
5156 if (!test_QuerySecurity(b, tctx, user_handle)) {
5160 if (!test_QueryUserInfo(b, tctx, user_handle)) {
5164 if (!test_QueryUserInfo2(b, tctx, user_handle)) {
5168 if (!test_SetUserInfo(b, tctx, user_handle, base_acct_flags,
5173 if (!test_GetUserPwInfo(b, tctx, user_handle)) {
5177 if (!test_TestPrivateFunctionsUser(b, tctx, user_handle)) {
5181 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
5185 case TORTURE_SAMR_PASSWORDS:
5186 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
5187 char simple_pass[9];
5188 char *v = generate_random_str(tctx, 1);
5190 ZERO_STRUCT(simple_pass);
5191 memset(simple_pass, *v, sizeof(simple_pass) - 1);
5193 torture_comment(tctx, "Testing machine account password policy rules\n");
5195 /* Workstation trust accounts don't seem to need to honour password quality policy */
5196 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
5200 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
5204 /* reset again, to allow another 'user' password change */
5205 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
5209 /* Try a 'short' password */
5210 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
5214 /* Try a compleatly random password */
5215 if (!test_ChangePasswordRandomBytes(p, tctx, base_acct_name, user_handle, &password)) {
5220 for (i = 0; password_fields[i]; i++) {
5221 if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
5225 /* check it was set right */
5226 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
5231 for (i = 0; password_fields[i]; i++) {
5232 if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
5236 /* check it was set right */
5237 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
5242 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
5246 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
5250 if (!test_SetUserPass_18(p, tctx, user_handle, &password)) {
5254 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
5258 for (i = 0; password_fields[i]; i++) {
5260 if (password_fields[i] == SAMR_FIELD_LM_PASSWORD_PRESENT) {
5261 /* we need to skip as that would break
5262 * the ChangePasswordUser3 verify */
5266 if (!test_SetUserPass_21(p, tctx, user_handle, password_fields[i], &password)) {
5270 /* check it was set right */
5271 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
5276 q.in.user_handle = user_handle;
5280 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
5281 "QueryUserInfo failed");
5282 if (!NT_STATUS_IS_OK(q.out.result)) {
5283 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level %u failed - %s\n",
5284 q.in.level, nt_errstr(q.out.result));
5287 uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
5288 if ((info->info5.acct_flags) != expected_flags) {
5290 if (!torture_setting_bool(tctx, "samba3", false)) {
5291 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
5292 info->info5.acct_flags,
5297 if (info->info5.rid != rid) {
5298 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
5299 info->info5.rid, rid);
5306 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
5308 /* test last password change timestamp behaviour */
5309 torture_assert(tctx, test_SetPassword_pwdlastset(p, tctx, base_acct_flags,
5311 user_handle, &password,
5312 machine_credentials),
5313 "pwdLastSet test failed\n");
5316 case TORTURE_SAMR_PASSWORDS_BADPWDCOUNT:
5318 /* test bad pwd count change behaviour */
5319 torture_assert(tctx, test_Password_badpwdcount_wrap(p, tctx, base_acct_flags,
5322 user_handle, &password,
5323 machine_credentials),
5324 "badPwdCount test failed\n");
5327 case TORTURE_SAMR_PASSWORDS_LOCKOUT:
5329 torture_assert(tctx, test_Password_lockout_wrap(p, tctx, base_acct_flags,
5332 user_handle, &password,
5333 machine_credentials),
5334 "Lockout test failed");
5338 case TORTURE_SAMR_USER_PRIVILEGES: {
5340 struct dcerpc_pipe *lp;
5341 struct policy_handle *lsa_handle;
5342 struct dcerpc_binding_handle *lb;
5344 status = torture_rpc_connection(tctx, &lp, &ndr_table_lsarpc);
5345 torture_assert_ntstatus_ok(tctx, status, "Failed to open LSA pipe");
5346 lb = lp->binding_handle;
5348 if (!test_lsa_OpenPolicy2(lb, tctx, &lsa_handle)) {
5352 if (!test_DeleteUser_with_privs(p, lp, tctx,
5353 domain_handle, lsa_handle, user_handle,
5355 machine_credentials)) {
5359 if (!test_lsa_Close(lb, tctx, lsa_handle)) {
5364 torture_result(tctx, TORTURE_FAIL, "privileged user delete test failed\n");
5369 case TORTURE_SAMR_OTHER:
5370 case TORTURE_SAMR_MANY_ACCOUNTS:
5371 case TORTURE_SAMR_MANY_GROUPS:
5372 case TORTURE_SAMR_MANY_ALIASES:
5373 /* We just need the account to exist */
5379 static bool test_alias_ops(struct dcerpc_binding_handle *b,
5380 struct torture_context *tctx,
5381 struct policy_handle *alias_handle,
5382 const struct dom_sid *domain_sid)
5386 if (!torture_setting_bool(tctx, "samba3", false)) {
5387 if (!test_QuerySecurity(b, tctx, alias_handle)) {
5392 if (!test_QueryAliasInfo(b, tctx, alias_handle)) {
5396 if (!test_SetAliasInfo(b, tctx, alias_handle)) {
5400 if (!test_AddMemberToAlias(b, tctx, alias_handle, domain_sid)) {
5404 if (torture_setting_bool(tctx, "samba3", false) ||
5405 torture_setting_bool(tctx, "samba4", false)) {
5406 torture_comment(tctx, "skipping MultipleMembers Alias tests against Samba\n");
5410 if (!test_AddMultipleMembersToAlias(b, tctx, alias_handle)) {
5418 static bool test_DeleteUser(struct dcerpc_binding_handle *b,
5419 struct torture_context *tctx,
5420 struct policy_handle *user_handle)
5422 struct samr_DeleteUser d;
5423 torture_comment(tctx, "Testing DeleteUser\n");
5425 d.in.user_handle = user_handle;
5426 d.out.user_handle = user_handle;
5428 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, tctx, &d),
5429 "DeleteUser failed");
5430 torture_assert_ntstatus_ok(tctx, d.out.result, "DeleteUser");
5435 bool test_DeleteUser_byname(struct dcerpc_binding_handle *b,
5436 struct torture_context *tctx,
5437 struct policy_handle *handle, const char *name)
5440 struct samr_DeleteUser d;
5441 struct policy_handle user_handle;
5444 status = test_LookupName(b, tctx, handle, name, &rid);
5445 if (!NT_STATUS_IS_OK(status)) {
5449 status = test_OpenUser_byname(b, tctx, handle, name, &user_handle);
5450 if (!NT_STATUS_IS_OK(status)) {
5454 d.in.user_handle = &user_handle;
5455 d.out.user_handle = &user_handle;
5456 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, tctx, &d),
5457 "DeleteUser failed");
5458 if (!NT_STATUS_IS_OK(d.out.result)) {
5459 status = d.out.result;
5466 torture_result(tctx, TORTURE_FAIL, "DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
5471 static bool test_DeleteGroup_byname(struct dcerpc_binding_handle *b,
5472 struct torture_context *tctx,
5473 struct policy_handle *handle, const char *name)
5476 struct samr_OpenGroup r;
5477 struct samr_DeleteDomainGroup d;
5478 struct policy_handle group_handle;
5481 status = test_LookupName(b, tctx, handle, name, &rid);
5482 if (!NT_STATUS_IS_OK(status)) {
5486 r.in.domain_handle = handle;
5487 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5489 r.out.group_handle = &group_handle;
5490 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenGroup_r(b, tctx, &r),
5491 "OpenGroup failed");
5492 if (!NT_STATUS_IS_OK(r.out.result)) {
5493 status = r.out.result;
5497 d.in.group_handle = &group_handle;
5498 d.out.group_handle = &group_handle;
5499 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomainGroup_r(b, tctx, &d),
5500 "DeleteDomainGroup failed");
5501 if (!NT_STATUS_IS_OK(d.out.result)) {
5502 status = d.out.result;
5509 torture_result(tctx, TORTURE_FAIL, "DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
5514 static bool test_DeleteAlias_byname(struct dcerpc_binding_handle *b,
5515 struct torture_context *tctx,
5516 struct policy_handle *domain_handle,
5520 struct samr_OpenAlias r;
5521 struct samr_DeleteDomAlias d;
5522 struct policy_handle alias_handle;
5525 torture_comment(tctx, "Testing DeleteAlias_byname\n");
5527 status = test_LookupName(b, tctx, domain_handle, name, &rid);
5528 if (!NT_STATUS_IS_OK(status)) {
5532 r.in.domain_handle = domain_handle;
5533 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5535 r.out.alias_handle = &alias_handle;
5536 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenAlias_r(b, tctx, &r),
5537 "OpenAlias failed");
5538 if (!NT_STATUS_IS_OK(r.out.result)) {
5539 status = r.out.result;
5543 d.in.alias_handle = &alias_handle;
5544 d.out.alias_handle = &alias_handle;
5545 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomAlias_r(b, tctx, &d),
5546 "DeleteDomAlias failed");
5547 if (!NT_STATUS_IS_OK(d.out.result)) {
5548 status = d.out.result;
5555 torture_result(tctx, TORTURE_FAIL, "DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
5559 static bool test_DeleteAlias(struct dcerpc_binding_handle *b,
5560 struct torture_context *tctx,
5561 struct policy_handle *alias_handle)
5563 struct samr_DeleteDomAlias d;
5566 torture_comment(tctx, "Testing DeleteAlias\n");
5568 d.in.alias_handle = alias_handle;
5569 d.out.alias_handle = alias_handle;
5571 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomAlias_r(b, tctx, &d),
5572 "DeleteDomAlias failed");
5573 if (!NT_STATUS_IS_OK(d.out.result)) {
5574 torture_result(tctx, TORTURE_FAIL, "DeleteAlias failed - %s\n", nt_errstr(d.out.result));
5581 static bool test_CreateAlias(struct dcerpc_binding_handle *b,
5582 struct torture_context *tctx,
5583 struct policy_handle *domain_handle,
5584 const char *alias_name,
5585 struct policy_handle *alias_handle,
5586 const struct dom_sid *domain_sid,
5589 struct samr_CreateDomAlias r;
5590 struct lsa_String name;
5594 init_lsa_String(&name, alias_name);
5595 r.in.domain_handle = domain_handle;
5596 r.in.alias_name = &name;
5597 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5598 r.out.alias_handle = alias_handle;
5601 torture_comment(tctx, "Testing CreateAlias (%s)\n", r.in.alias_name->string);
5603 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomAlias_r(b, tctx, &r),
5604 "CreateDomAlias failed");
5606 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5607 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED)) {
5608 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.alias_name->string);
5611 torture_result(tctx, TORTURE_FAIL, "Server should have refused create of '%s', got %s instead\n", r.in.alias_name->string,
5612 nt_errstr(r.out.result));
5617 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ALIAS_EXISTS)) {
5618 if (!test_DeleteAlias_byname(b, tctx, domain_handle, r.in.alias_name->string)) {
5621 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomAlias_r(b, tctx, &r),
5622 "CreateDomAlias failed");
5625 if (!NT_STATUS_IS_OK(r.out.result)) {
5626 torture_result(tctx, TORTURE_FAIL, "CreateAlias failed - %s\n", nt_errstr(r.out.result));
5634 if (!test_alias_ops(b, tctx, alias_handle, domain_sid)) {
5641 static bool test_ChangePassword(struct dcerpc_pipe *p,
5642 struct torture_context *tctx,
5643 const char *acct_name,
5644 struct policy_handle *domain_handle, char **password)
5647 struct dcerpc_binding_handle *b = p->binding_handle;
5653 if (!test_ChangePasswordUser(b, tctx, acct_name, domain_handle, password)) {
5657 if (!test_ChangePasswordUser2(p, tctx, acct_name, password, 0, true)) {
5661 if (!test_OemChangePasswordUser2(p, tctx, acct_name, domain_handle, password)) {
5665 /* test what happens when setting the old password again */
5666 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, *password, 0, true)) {
5671 char simple_pass[9];
5672 char *v = generate_random_str(tctx, 1);
5674 ZERO_STRUCT(simple_pass);
5675 memset(simple_pass, *v, sizeof(simple_pass) - 1);
5677 /* test what happens when picking a simple password */
5678 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, simple_pass, 0, true)) {
5683 /* set samr_SetDomainInfo level 1 with min_length 5 */
5685 struct samr_QueryDomainInfo r;
5686 union samr_DomainInfo *info = NULL;
5687 struct samr_SetDomainInfo s;
5688 uint16_t len_old, len;
5689 uint32_t pwd_prop_old;
5690 int64_t min_pwd_age_old;
5694 r.in.domain_handle = domain_handle;
5698 torture_comment(tctx, "Testing samr_QueryDomainInfo level 1\n");
5699 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &r),
5700 "QueryDomainInfo failed");
5701 if (!NT_STATUS_IS_OK(r.out.result)) {
5705 s.in.domain_handle = domain_handle;
5709 /* remember the old min length, so we can reset it */
5710 len_old = s.in.info->info1.min_password_length;
5711 s.in.info->info1.min_password_length = len;
5712 pwd_prop_old = s.in.info->info1.password_properties;
5713 /* turn off password complexity checks for this test */
5714 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
5716 min_pwd_age_old = s.in.info->info1.min_password_age;
5717 s.in.info->info1.min_password_age = 0;
5719 torture_comment(tctx, "Testing samr_SetDomainInfo level 1\n");
5720 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
5721 "SetDomainInfo failed");
5722 if (!NT_STATUS_IS_OK(s.out.result)) {
5726 torture_comment(tctx, "calling test_ChangePasswordUser3 with too short password\n");
5728 if (!test_ChangePasswordUser3(p, tctx, acct_name, len - 1, password, NULL, 0, true)) {
5732 s.in.info->info1.min_password_length = len_old;
5733 s.in.info->info1.password_properties = pwd_prop_old;
5734 s.in.info->info1.min_password_age = min_pwd_age_old;
5736 torture_comment(tctx, "Testing samr_SetDomainInfo level 1\n");
5737 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
5738 "SetDomainInfo failed");
5739 if (!NT_STATUS_IS_OK(s.out.result)) {
5746 struct samr_OpenUser r;
5747 struct samr_QueryUserInfo q;
5748 union samr_UserInfo *info;
5749 struct samr_LookupNames n;
5750 struct policy_handle user_handle;
5751 struct samr_Ids rids, types;
5753 n.in.domain_handle = domain_handle;
5755 n.in.names = talloc_array(tctx, struct lsa_String, 1);
5756 n.in.names[0].string = acct_name;
5758 n.out.types = &types;
5760 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupNames_r(b, tctx, &n),
5761 "LookupNames failed");
5762 if (!NT_STATUS_IS_OK(n.out.result)) {
5763 torture_result(tctx, TORTURE_FAIL, "LookupNames failed - %s\n", nt_errstr(n.out.result));
5767 r.in.domain_handle = domain_handle;
5768 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5769 r.in.rid = n.out.rids->ids[0];
5770 r.out.user_handle = &user_handle;
5772 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
5774 if (!NT_STATUS_IS_OK(r.out.result)) {
5775 torture_result(tctx, TORTURE_FAIL, "OpenUser(%u) failed - %s\n", n.out.rids->ids[0], nt_errstr(r.out.result));
5779 q.in.user_handle = &user_handle;
5783 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
5784 "QueryUserInfo failed");
5785 if (!NT_STATUS_IS_OK(q.out.result)) {
5786 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo failed - %s\n", nt_errstr(q.out.result));
5790 torture_comment(tctx, "calling test_ChangePasswordUser3 with too early password change\n");
5792 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL,
5793 info->info5.last_password_change, true)) {
5798 /* we change passwords twice - this has the effect of verifying
5799 they were changed correctly for the final call */
5800 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
5804 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
5811 static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
5812 struct policy_handle *domain_handle,
5813 const char *user_name,
5814 struct policy_handle *user_handle_out,
5815 struct dom_sid *domain_sid,
5816 enum torture_samr_choice which_ops,
5817 struct cli_credentials *machine_credentials,
5821 TALLOC_CTX *user_ctx;
5823 struct samr_CreateUser r;
5824 struct samr_QueryUserInfo q;
5825 union samr_UserInfo *info;
5826 struct samr_DeleteUser d;
5829 /* This call creates a 'normal' account - check that it really does */
5830 const uint32_t acct_flags = ACB_NORMAL;
5831 struct lsa_String name;
5833 struct dcerpc_binding_handle *b = p->binding_handle;
5835 struct policy_handle user_handle;
5836 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
5837 init_lsa_String(&name, user_name);
5839 r.in.domain_handle = domain_handle;
5840 r.in.account_name = &name;
5841 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5842 r.out.user_handle = &user_handle;
5845 torture_comment(tctx, "Testing CreateUser(%s)\n", r.in.account_name->string);
5847 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser_r(b, user_ctx, &r),
5848 "CreateUser failed");
5850 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5851 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
5852 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.account_name->string);
5855 torture_result(tctx, TORTURE_FAIL, "Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
5856 nt_errstr(r.out.result));
5861 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_USER_EXISTS)) {
5862 if (!test_DeleteUser_byname(b, tctx, domain_handle, r.in.account_name->string)) {
5863 talloc_free(user_ctx);
5866 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser_r(b, user_ctx, &r),
5867 "CreateUser failed");
5870 if (!NT_STATUS_IS_OK(r.out.result)) {
5871 talloc_free(user_ctx);
5872 torture_result(tctx, TORTURE_FAIL, "CreateUser failed - %s\n", nt_errstr(r.out.result));
5877 if (user_handle_out) {
5878 *user_handle_out = user_handle;
5884 q.in.user_handle = &user_handle;
5888 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, user_ctx, &q),
5889 "QueryUserInfo failed");
5890 if (!NT_STATUS_IS_OK(q.out.result)) {
5891 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level %u failed - %s\n",
5892 q.in.level, nt_errstr(q.out.result));
5895 if ((info->info16.acct_flags & acct_flags) != acct_flags) {
5896 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
5897 info->info16.acct_flags,
5903 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
5904 domain_sid, acct_flags, name.string, which_ops,
5905 machine_credentials)) {
5909 if (user_handle_out) {
5910 *user_handle_out = user_handle;
5912 torture_comment(tctx, "Testing DeleteUser (createuser test)\n");
5914 d.in.user_handle = &user_handle;
5915 d.out.user_handle = &user_handle;
5917 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, user_ctx, &d),
5918 "DeleteUser failed");
5919 if (!NT_STATUS_IS_OK(d.out.result)) {
5920 torture_result(tctx, TORTURE_FAIL, "DeleteUser failed - %s\n", nt_errstr(d.out.result));
5927 talloc_free(user_ctx);
5933 static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
5934 struct policy_handle *domain_handle,
5935 struct dom_sid *domain_sid,
5936 enum torture_samr_choice which_ops,
5937 struct cli_credentials *machine_credentials)
5939 struct samr_CreateUser2 r;
5940 struct samr_QueryUserInfo q;
5941 union samr_UserInfo *info;
5942 struct samr_DeleteUser d;
5943 struct policy_handle user_handle;
5945 struct lsa_String name;
5948 struct dcerpc_binding_handle *b = p->binding_handle;
5951 uint32_t acct_flags;
5952 const char *account_name;
5954 } account_types[] = {
5955 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
5956 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5957 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5958 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
5959 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5960 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5961 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
5962 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5963 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5964 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_ACCESS_DENIED },
5965 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
5966 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
5967 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5968 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5969 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
5972 for (i = 0; account_types[i].account_name; i++) {
5973 TALLOC_CTX *user_ctx;
5974 uint32_t acct_flags = account_types[i].acct_flags;
5975 uint32_t access_granted;
5976 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
5977 init_lsa_String(&name, account_types[i].account_name);
5979 r.in.domain_handle = domain_handle;
5980 r.in.account_name = &name;
5981 r.in.acct_flags = acct_flags;
5982 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5983 r.out.user_handle = &user_handle;
5984 r.out.access_granted = &access_granted;
5987 torture_comment(tctx, "Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
5989 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser2_r(b, user_ctx, &r),
5990 "CreateUser2 failed");
5992 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5993 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
5994 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.account_name->string);
5997 torture_result(tctx, TORTURE_FAIL, "Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
5998 nt_errstr(r.out.result));
6004 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_USER_EXISTS)) {
6005 if (!test_DeleteUser_byname(b, tctx, domain_handle, r.in.account_name->string)) {
6006 talloc_free(user_ctx);
6010 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser2_r(b, user_ctx, &r),
6011 "CreateUser2 failed");
6014 if (!NT_STATUS_EQUAL(r.out.result, account_types[i].nt_status)) {
6015 torture_result(tctx, TORTURE_FAIL, "CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
6016 nt_errstr(r.out.result), nt_errstr(account_types[i].nt_status));
6020 if (NT_STATUS_IS_OK(r.out.result)) {
6021 q.in.user_handle = &user_handle;
6025 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, user_ctx, &q),
6026 "QueryUserInfo failed");
6027 if (!NT_STATUS_IS_OK(q.out.result)) {
6028 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level %u failed - %s\n",
6029 q.in.level, nt_errstr(q.out.result));
6032 uint32_t expected_flags = (acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
6033 if (acct_flags == ACB_NORMAL) {
6034 expected_flags |= ACB_PW_EXPIRED;
6036 if ((info->info5.acct_flags) != expected_flags) {
6037 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
6038 info->info5.acct_flags,
6042 switch (acct_flags) {
6044 if (info->info5.primary_gid != DOMAIN_RID_DCS) {
6045 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level 5: DC should have had Primary Group %d, got %d\n",
6046 DOMAIN_RID_DCS, info->info5.primary_gid);
6051 if (info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
6052 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
6053 DOMAIN_RID_DOMAIN_MEMBERS, info->info5.primary_gid);
6058 if (info->info5.primary_gid != DOMAIN_RID_USERS) {
6059 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level 5: Users should have had Primary Group %d, got %d\n",
6060 DOMAIN_RID_USERS, info->info5.primary_gid);
6067 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
6068 domain_sid, acct_flags, name.string, which_ops,
6069 machine_credentials)) {
6073 if (!ndr_policy_handle_empty(&user_handle)) {
6074 torture_comment(tctx, "Testing DeleteUser (createuser2 test)\n");
6076 d.in.user_handle = &user_handle;
6077 d.out.user_handle = &user_handle;
6079 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, user_ctx, &d),
6080 "DeleteUser failed");
6081 if (!NT_STATUS_IS_OK(d.out.result)) {
6082 torture_result(tctx, TORTURE_FAIL, "DeleteUser failed - %s\n", nt_errstr(d.out.result));
6087 talloc_free(user_ctx);
6093 static bool test_QueryAliasInfo(struct dcerpc_binding_handle *b,
6094 struct torture_context *tctx,
6095 struct policy_handle *handle)
6097 struct samr_QueryAliasInfo r;
6098 union samr_AliasInfo *info;
6099 uint16_t levels[] = {1, 2, 3};
6103 for (i=0;i<ARRAY_SIZE(levels);i++) {
6104 torture_comment(tctx, "Testing QueryAliasInfo level %u\n", levels[i]);
6106 r.in.alias_handle = handle;
6107 r.in.level = levels[i];
6110 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryAliasInfo_r(b, tctx, &r),
6111 "QueryAliasInfo failed");
6112 if (!NT_STATUS_IS_OK(r.out.result)) {
6113 torture_result(tctx, TORTURE_FAIL, "QueryAliasInfo level %u failed - %s\n",
6114 levels[i], nt_errstr(r.out.result));
6122 static bool test_QueryGroupInfo(struct dcerpc_binding_handle *b,
6123 struct torture_context *tctx,
6124 struct policy_handle *handle)
6126 struct samr_QueryGroupInfo r;
6127 union samr_GroupInfo *info;
6128 uint16_t levels[] = {1, 2, 3, 4, 5};
6132 for (i=0;i<ARRAY_SIZE(levels);i++) {
6133 torture_comment(tctx, "Testing QueryGroupInfo level %u\n", levels[i]);
6135 r.in.group_handle = handle;
6136 r.in.level = levels[i];
6139 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupInfo_r(b, tctx, &r),
6140 "QueryGroupInfo failed");
6141 if (!NT_STATUS_IS_OK(r.out.result)) {
6142 torture_result(tctx, TORTURE_FAIL, "QueryGroupInfo level %u failed - %s\n",
6143 levels[i], nt_errstr(r.out.result));
6151 static bool test_QueryGroupMember(struct dcerpc_binding_handle *b,
6152 struct torture_context *tctx,
6153 struct policy_handle *handle)
6155 struct samr_QueryGroupMember r;
6156 struct samr_RidAttrArray *rids = NULL;
6159 torture_comment(tctx, "Testing QueryGroupMember\n");
6161 r.in.group_handle = handle;
6164 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupMember_r(b, tctx, &r),
6165 "QueryGroupMember failed");
6166 if (!NT_STATUS_IS_OK(r.out.result)) {
6167 torture_result(tctx, TORTURE_FAIL, "QueryGroupMember failed - %s\n", nt_errstr(r.out.result));
6175 static bool test_SetGroupInfo(struct dcerpc_binding_handle *b,
6176 struct torture_context *tctx,
6177 struct policy_handle *handle)
6179 struct samr_QueryGroupInfo r;
6180 union samr_GroupInfo *info;
6181 struct samr_SetGroupInfo s;
6182 uint16_t levels[] = {1, 2, 3, 4};
6183 uint16_t set_ok[] = {0, 1, 1, 1};
6187 for (i=0;i<ARRAY_SIZE(levels);i++) {
6188 torture_comment(tctx, "Testing QueryGroupInfo level %u\n", levels[i]);
6190 r.in.group_handle = handle;
6191 r.in.level = levels[i];
6194 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupInfo_r(b, tctx, &r),
6195 "QueryGroupInfo failed");
6196 if (!NT_STATUS_IS_OK(r.out.result)) {
6197 torture_result(tctx, TORTURE_FAIL, "QueryGroupInfo level %u failed - %s\n",
6198 levels[i], nt_errstr(r.out.result));
6202 torture_comment(tctx, "Testing SetGroupInfo level %u\n", levels[i]);
6204 s.in.group_handle = handle;
6205 s.in.level = levels[i];
6206 s.in.info = *r.out.info;
6209 /* disabled this, as it changes the name only from the point of view of samr,
6210 but leaves the name from the point of view of w2k3 internals (and ldap). This means
6211 the name is still reserved, so creating the old name fails, but deleting by the old name
6213 if (s.in.level == 2) {
6214 init_lsa_String(&s.in.info->string, "NewName");
6218 if (s.in.level == 4) {
6219 init_lsa_String(&s.in.info->description, "test description");
6222 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetGroupInfo_r(b, tctx, &s),
6223 "SetGroupInfo failed");
6225 if (!NT_STATUS_IS_OK(s.out.result)) {
6226 torture_result(tctx, TORTURE_FAIL, "SetGroupInfo level %u failed - %s\n",
6227 r.in.level, nt_errstr(s.out.result));
6232 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, s.out.result)) {
6233 torture_result(tctx, TORTURE_FAIL, "SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
6234 r.in.level, nt_errstr(s.out.result));
6244 static bool test_QueryUserInfo(struct dcerpc_binding_handle *b,
6245 struct torture_context *tctx,
6246 struct policy_handle *handle)
6248 struct samr_QueryUserInfo r;
6249 union samr_UserInfo *info;
6250 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
6251 11, 12, 13, 14, 16, 17, 20, 21};
6255 for (i=0;i<ARRAY_SIZE(levels);i++) {
6256 torture_comment(tctx, "Testing QueryUserInfo level %u\n", levels[i]);
6258 r.in.user_handle = handle;
6259 r.in.level = levels[i];
6262 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
6263 "QueryUserInfo failed");
6264 if (!NT_STATUS_IS_OK(r.out.result)) {
6265 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level %u failed - %s\n",
6266 levels[i], nt_errstr(r.out.result));
6274 static bool test_QueryUserInfo2(struct dcerpc_binding_handle *b,
6275 struct torture_context *tctx,
6276 struct policy_handle *handle)
6278 struct samr_QueryUserInfo2 r;
6279 union samr_UserInfo *info;
6280 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
6281 11, 12, 13, 14, 16, 17, 20, 21};
6285 for (i=0;i<ARRAY_SIZE(levels);i++) {
6286 torture_comment(tctx, "Testing QueryUserInfo2 level %u\n", levels[i]);
6288 r.in.user_handle = handle;
6289 r.in.level = levels[i];
6292 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo2_r(b, tctx, &r),
6293 "QueryUserInfo2 failed");
6294 if (!NT_STATUS_IS_OK(r.out.result)) {
6295 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo2 level %u failed - %s\n",
6296 levels[i], nt_errstr(r.out.result));
6304 static bool test_OpenUser(struct dcerpc_binding_handle *b,
6305 struct torture_context *tctx,
6306 struct policy_handle *handle, uint32_t rid)
6308 struct samr_OpenUser r;
6309 struct policy_handle user_handle;
6312 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
6314 r.in.domain_handle = handle;
6315 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6317 r.out.user_handle = &user_handle;
6319 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
6321 if (!NT_STATUS_IS_OK(r.out.result)) {
6322 torture_result(tctx, TORTURE_FAIL, "OpenUser(%u) failed - %s\n", rid, nt_errstr(r.out.result));
6326 if (!test_QuerySecurity(b, tctx, &user_handle)) {
6330 if (!test_QueryUserInfo(b, tctx, &user_handle)) {
6334 if (!test_QueryUserInfo2(b, tctx, &user_handle)) {
6338 if (!test_GetUserPwInfo(b, tctx, &user_handle)) {
6342 if (!test_GetGroupsForUser(b, tctx, &user_handle)) {
6346 if (!test_samr_handle_Close(b, tctx, &user_handle)) {
6353 static bool test_OpenGroup(struct dcerpc_binding_handle *b,
6354 struct torture_context *tctx,
6355 struct policy_handle *handle, uint32_t rid)
6357 struct samr_OpenGroup r;
6358 struct policy_handle group_handle;
6361 torture_comment(tctx, "Testing OpenGroup(%u)\n", rid);
6363 r.in.domain_handle = handle;
6364 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6366 r.out.group_handle = &group_handle;
6368 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenGroup_r(b, tctx, &r),
6369 "OpenGroup failed");
6370 if (!NT_STATUS_IS_OK(r.out.result)) {
6371 torture_result(tctx, TORTURE_FAIL, "OpenGroup(%u) failed - %s\n", rid, nt_errstr(r.out.result));
6375 if (!torture_setting_bool(tctx, "samba3", false)) {
6376 if (!test_QuerySecurity(b, tctx, &group_handle)) {
6381 if (!test_QueryGroupInfo(b, tctx, &group_handle)) {
6385 if (!test_QueryGroupMember(b, tctx, &group_handle)) {
6389 if (!test_samr_handle_Close(b, tctx, &group_handle)) {
6396 static bool test_OpenAlias(struct dcerpc_binding_handle *b,
6397 struct torture_context *tctx,
6398 struct policy_handle *handle, uint32_t rid)
6400 struct samr_OpenAlias r;
6401 struct policy_handle alias_handle;
6404 torture_comment(tctx, "Testing OpenAlias(%u)\n", rid);
6406 r.in.domain_handle = handle;
6407 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6409 r.out.alias_handle = &alias_handle;
6411 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenAlias_r(b, tctx, &r),
6412 "OpenAlias failed");
6413 if (!NT_STATUS_IS_OK(r.out.result)) {
6414 torture_result(tctx, TORTURE_FAIL, "OpenAlias(%u) failed - %s\n", rid, nt_errstr(r.out.result));
6418 if (!torture_setting_bool(tctx, "samba3", false)) {
6419 if (!test_QuerySecurity(b, tctx, &alias_handle)) {
6424 if (!test_QueryAliasInfo(b, tctx, &alias_handle)) {
6428 if (!test_GetMembersInAlias(b, tctx, &alias_handle)) {
6432 if (!test_samr_handle_Close(b, tctx, &alias_handle)) {
6439 static bool check_mask(struct dcerpc_binding_handle *b,
6440 struct torture_context *tctx,
6441 struct policy_handle *handle, uint32_t rid,
6442 uint32_t acct_flag_mask)
6444 struct samr_OpenUser r;
6445 struct samr_QueryUserInfo q;
6446 union samr_UserInfo *info;
6447 struct policy_handle user_handle;
6450 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
6452 r.in.domain_handle = handle;
6453 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6455 r.out.user_handle = &user_handle;
6457 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
6459 if (!NT_STATUS_IS_OK(r.out.result)) {
6460 torture_result(tctx, TORTURE_FAIL, "OpenUser(%u) failed - %s\n", rid, nt_errstr(r.out.result));
6464 q.in.user_handle = &user_handle;
6468 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
6469 "QueryUserInfo failed");
6470 if (!NT_STATUS_IS_OK(q.out.result)) {
6471 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level 16 failed - %s\n",
6472 nt_errstr(q.out.result));
6475 if ((acct_flag_mask & info->info16.acct_flags) == 0) {
6476 torture_result(tctx, TORTURE_FAIL, "Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
6477 acct_flag_mask, info->info16.acct_flags, rid);
6482 if (!test_samr_handle_Close(b, tctx, &user_handle)) {
6489 static bool test_EnumDomainUsers_all(struct dcerpc_binding_handle *b,
6490 struct torture_context *tctx,
6491 struct policy_handle *handle)
6493 struct samr_EnumDomainUsers r;
6494 uint32_t mask, resume_handle=0;
6497 struct samr_LookupNames n;
6498 struct samr_LookupRids lr ;
6499 struct lsa_Strings names;
6500 struct samr_Ids rids, types;
6501 struct samr_SamArray *sam = NULL;
6502 uint32_t num_entries = 0;
6504 uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
6505 ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
6506 ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
6509 torture_comment(tctx, "Testing EnumDomainUsers\n");
6511 for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
6512 r.in.domain_handle = handle;
6513 r.in.resume_handle = &resume_handle;
6514 r.in.acct_flags = mask = masks[mask_idx];
6515 r.in.max_size = (uint32_t)-1;
6516 r.out.resume_handle = &resume_handle;
6517 r.out.num_entries = &num_entries;
6520 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainUsers_r(b, tctx, &r),
6521 "EnumDomainUsers failed");
6522 if (!NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) &&
6523 !NT_STATUS_IS_OK(r.out.result)) {
6524 torture_result(tctx, TORTURE_FAIL, "EnumDomainUsers failed - %s\n", nt_errstr(r.out.result));
6528 torture_assert(tctx, sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
6530 if (sam->count == 0) {
6534 for (i=0;i<sam->count;i++) {
6536 if (!check_mask(b, tctx, handle, sam->entries[i].idx, mask)) {
6539 } else if (!test_OpenUser(b, tctx, handle, sam->entries[i].idx)) {
6545 torture_comment(tctx, "Testing LookupNames\n");
6546 n.in.domain_handle = handle;
6547 n.in.num_names = sam->count;
6548 n.in.names = talloc_array(tctx, struct lsa_String, sam->count);
6550 n.out.types = &types;
6551 for (i=0;i<sam->count;i++) {
6552 n.in.names[i].string = sam->entries[i].name.string;
6554 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupNames_r(b, tctx, &n),
6555 "LookupNames failed");
6556 if (!NT_STATUS_IS_OK(n.out.result)) {
6557 torture_result(tctx, TORTURE_FAIL, "LookupNames failed - %s\n", nt_errstr(n.out.result));
6562 torture_comment(tctx, "Testing LookupRids\n");
6563 lr.in.domain_handle = handle;
6564 lr.in.num_rids = sam->count;
6565 lr.in.rids = talloc_array(tctx, uint32_t, sam->count);
6566 lr.out.names = &names;
6567 lr.out.types = &types;
6568 for (i=0;i<sam->count;i++) {
6569 lr.in.rids[i] = sam->entries[i].idx;
6571 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupRids_r(b, tctx, &lr),
6572 "LookupRids failed");
6573 torture_assert_ntstatus_ok(tctx, lr.out.result, "LookupRids");
6579 try blasting the server with a bunch of sync requests
6581 static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, struct torture_context *tctx,
6582 struct policy_handle *handle)
6584 struct samr_EnumDomainUsers r;
6585 uint32_t resume_handle=0;
6587 #define ASYNC_COUNT 100
6588 struct tevent_req *req[ASYNC_COUNT];
6590 if (!torture_setting_bool(tctx, "dangerous", false)) {
6591 torture_skip(tctx, "samr async test disabled - enable dangerous tests to use\n");
6594 torture_comment(tctx, "Testing EnumDomainUsers_async\n");
6596 r.in.domain_handle = handle;
6597 r.in.resume_handle = &resume_handle;
6598 r.in.acct_flags = 0;
6599 r.in.max_size = (uint32_t)-1;
6600 r.out.resume_handle = &resume_handle;
6602 for (i=0;i<ASYNC_COUNT;i++) {
6603 req[i] = dcerpc_samr_EnumDomainUsers_r_send(tctx, tctx->ev, p->binding_handle, &r);
6606 for (i=0;i<ASYNC_COUNT;i++) {
6607 tevent_req_poll(req[i], tctx->ev);
6608 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainUsers_r_recv(req[i], tctx),
6609 talloc_asprintf(tctx, "EnumDomainUsers[%d] failed - %s\n",
6610 i, nt_errstr(r.out.result)));
6613 torture_comment(tctx, "%d async requests OK\n", i);
6618 static bool test_EnumDomainGroups_all(struct dcerpc_binding_handle *b,
6619 struct torture_context *tctx,
6620 struct policy_handle *handle)
6622 struct samr_EnumDomainGroups r;
6623 uint32_t resume_handle=0;
6624 struct samr_SamArray *sam = NULL;
6625 uint32_t num_entries = 0;
6628 bool universal_group_found = false;
6630 torture_comment(tctx, "Testing EnumDomainGroups\n");
6632 r.in.domain_handle = handle;
6633 r.in.resume_handle = &resume_handle;
6634 r.in.max_size = (uint32_t)-1;
6635 r.out.resume_handle = &resume_handle;
6636 r.out.num_entries = &num_entries;
6639 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainGroups_r(b, tctx, &r),
6640 "EnumDomainGroups failed");
6641 if (!NT_STATUS_IS_OK(r.out.result)) {
6642 torture_result(tctx, TORTURE_FAIL, "EnumDomainGroups failed - %s\n", nt_errstr(r.out.result));
6650 for (i=0;i<sam->count;i++) {
6651 if (!test_OpenGroup(b, tctx, handle, sam->entries[i].idx)) {
6654 if ((ret == true) && (strcasecmp(sam->entries[i].name.string,
6655 "Enterprise Admins") == 0)) {
6656 universal_group_found = true;
6660 /* when we are running this on s4 we should get back at least the
6661 * "Enterprise Admins" universal group. If we don't get a group entry
6662 * at all we probably are performing the test on the builtin domain.
6663 * So ignore this case. */
6664 if (torture_setting_bool(tctx, "samba4", false)) {
6665 if ((sam->count > 0) && (!universal_group_found)) {
6673 static bool test_EnumDomainAliases_all(struct dcerpc_binding_handle *b,
6674 struct torture_context *tctx,
6675 struct policy_handle *handle)
6677 struct samr_EnumDomainAliases r;
6678 uint32_t resume_handle=0;
6679 struct samr_SamArray *sam = NULL;
6680 uint32_t num_entries = 0;
6684 torture_comment(tctx, "Testing EnumDomainAliases\n");
6686 r.in.domain_handle = handle;
6687 r.in.resume_handle = &resume_handle;
6688 r.in.max_size = (uint32_t)-1;
6690 r.out.num_entries = &num_entries;
6691 r.out.resume_handle = &resume_handle;
6693 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainAliases_r(b, tctx, &r),
6694 "EnumDomainAliases failed");
6695 if (!NT_STATUS_IS_OK(r.out.result)) {
6696 torture_result(tctx, TORTURE_FAIL, "EnumDomainAliases failed - %s\n", nt_errstr(r.out.result));
6704 for (i=0;i<sam->count;i++) {
6705 if (!test_OpenAlias(b, tctx, handle, sam->entries[i].idx)) {
6713 static bool test_GetDisplayEnumerationIndex(struct dcerpc_binding_handle *b,
6714 struct torture_context *tctx,
6715 struct policy_handle *handle)
6717 struct samr_GetDisplayEnumerationIndex r;
6719 uint16_t levels[] = {1, 2, 3, 4, 5};
6720 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
6721 struct lsa_String name;
6725 for (i=0;i<ARRAY_SIZE(levels);i++) {
6726 torture_comment(tctx, "Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
6728 init_lsa_String(&name, TEST_ACCOUNT_NAME);
6730 r.in.domain_handle = handle;
6731 r.in.level = levels[i];
6735 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex_r(b, tctx, &r),
6736 "GetDisplayEnumerationIndex failed");
6739 !NT_STATUS_IS_OK(r.out.result) &&
6740 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
6741 torture_result(tctx, TORTURE_FAIL, "GetDisplayEnumerationIndex level %u failed - %s\n",
6742 levels[i], nt_errstr(r.out.result));
6746 init_lsa_String(&name, "zzzzzzzz");
6748 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex_r(b, tctx, &r),
6749 "GetDisplayEnumerationIndex failed");
6751 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
6752 torture_result(tctx, TORTURE_FAIL, "GetDisplayEnumerationIndex level %u failed - %s\n",
6753 levels[i], nt_errstr(r.out.result));
6761 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_binding_handle *b,
6762 struct torture_context *tctx,
6763 struct policy_handle *handle)
6765 struct samr_GetDisplayEnumerationIndex2 r;
6767 uint16_t levels[] = {1, 2, 3, 4, 5};
6768 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
6769 struct lsa_String name;
6773 for (i=0;i<ARRAY_SIZE(levels);i++) {
6774 torture_comment(tctx, "Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
6776 init_lsa_String(&name, TEST_ACCOUNT_NAME);
6778 r.in.domain_handle = handle;
6779 r.in.level = levels[i];
6783 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex2_r(b, tctx, &r),
6784 "GetDisplayEnumerationIndex2 failed");
6786 !NT_STATUS_IS_OK(r.out.result) &&
6787 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
6788 torture_result(tctx, TORTURE_FAIL, "GetDisplayEnumerationIndex2 level %u failed - %s\n",
6789 levels[i], nt_errstr(r.out.result));
6793 init_lsa_String(&name, "zzzzzzzz");
6795 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex2_r(b, tctx, &r),
6796 "GetDisplayEnumerationIndex2 failed");
6797 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
6798 torture_result(tctx, TORTURE_FAIL, "GetDisplayEnumerationIndex2 level %u failed - %s\n",
6799 levels[i], nt_errstr(r.out.result));
6807 #define STRING_EQUAL_QUERY(s1, s2, user) \
6808 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
6809 /* odd, but valid */ \
6810 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
6811 torture_result(tctx, TORTURE_FAIL, "%s mismatch for %s: %s != %s (%s)\n", \
6812 #s1, user.string, s1.string, s2.string, __location__); \
6815 #define INT_EQUAL_QUERY(s1, s2, user) \
6817 torture_result(tctx, TORTURE_FAIL, "%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
6818 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
6822 static bool test_each_DisplayInfo_user(struct dcerpc_binding_handle *b,
6823 struct torture_context *tctx,
6824 struct samr_QueryDisplayInfo *querydisplayinfo,
6825 bool *seen_testuser)
6827 struct samr_OpenUser r;
6828 struct samr_QueryUserInfo q;
6829 union samr_UserInfo *info;
6830 struct policy_handle user_handle;
6832 r.in.domain_handle = querydisplayinfo->in.domain_handle;
6833 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6834 for (i = 0; ; i++) {
6835 switch (querydisplayinfo->in.level) {
6837 if (i >= querydisplayinfo->out.info->info1.count) {
6840 r.in.rid = querydisplayinfo->out.info->info1.entries[i].rid;
6843 if (i >= querydisplayinfo->out.info->info2.count) {
6846 r.in.rid = querydisplayinfo->out.info->info2.entries[i].rid;
6852 /* Not interested in validating just the account name */
6856 r.out.user_handle = &user_handle;
6858 switch (querydisplayinfo->in.level) {
6861 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
6863 if (!NT_STATUS_IS_OK(r.out.result)) {
6864 torture_result(tctx, TORTURE_FAIL, "OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(r.out.result));
6869 q.in.user_handle = &user_handle;
6872 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
6873 "QueryUserInfo failed");
6874 if (!NT_STATUS_IS_OK(r.out.result)) {
6875 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(r.out.result));
6879 switch (querydisplayinfo->in.level) {
6881 if (seen_testuser && strcmp(info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
6882 *seen_testuser = true;
6884 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].full_name,
6885 info->info21.full_name, info->info21.account_name);
6886 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].account_name,
6887 info->info21.account_name, info->info21.account_name);
6888 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].description,
6889 info->info21.description, info->info21.account_name);
6890 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].rid,
6891 info->info21.rid, info->info21.account_name);
6892 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].acct_flags,
6893 info->info21.acct_flags, info->info21.account_name);
6897 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].account_name,
6898 info->info21.account_name, info->info21.account_name);
6899 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].description,
6900 info->info21.description, info->info21.account_name);
6901 INT_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].rid,
6902 info->info21.rid, info->info21.account_name);
6903 INT_EQUAL_QUERY((querydisplayinfo->out.info->info2.entries[i].acct_flags & ~ACB_NORMAL),
6904 info->info21.acct_flags, info->info21.account_name);
6906 if (!(querydisplayinfo->out.info->info2.entries[i].acct_flags & ACB_NORMAL)) {
6907 torture_result(tctx, TORTURE_FAIL, "Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
6908 info->info21.account_name.string);
6911 if (!(info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
6912 torture_result(tctx, TORTURE_FAIL, "Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
6913 info->info21.account_name.string,
6914 querydisplayinfo->out.info->info2.entries[i].acct_flags,
6915 info->info21.acct_flags);
6922 if (!test_samr_handle_Close(b, tctx, &user_handle)) {
6929 static bool test_QueryDisplayInfo(struct dcerpc_binding_handle *b,
6930 struct torture_context *tctx,
6931 struct policy_handle *handle)
6933 struct samr_QueryDisplayInfo r;
6934 struct samr_QueryDomainInfo dom_info;
6935 union samr_DomainInfo *info = NULL;
6937 uint16_t levels[] = {1, 2, 3, 4, 5};
6939 bool seen_testuser = false;
6940 uint32_t total_size;
6941 uint32_t returned_size;
6942 union samr_DispInfo disp_info;
6945 for (i=0;i<ARRAY_SIZE(levels);i++) {
6946 torture_comment(tctx, "Testing QueryDisplayInfo level %u\n", levels[i]);
6949 r.out.result = STATUS_MORE_ENTRIES;
6950 while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES)) {
6951 r.in.domain_handle = handle;
6952 r.in.level = levels[i];
6953 r.in.max_entries = 2;
6954 r.in.buf_size = (uint32_t)-1;
6955 r.out.total_size = &total_size;
6956 r.out.returned_size = &returned_size;
6957 r.out.info = &disp_info;
6959 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &r),
6960 "QueryDisplayInfo failed");
6961 if (!NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(r.out.result)) {
6962 torture_result(tctx, TORTURE_FAIL, "QueryDisplayInfo level %u failed - %s\n",
6963 levels[i], nt_errstr(r.out.result));
6966 switch (r.in.level) {
6968 if (!test_each_DisplayInfo_user(b, tctx, &r, &seen_testuser)) {
6971 r.in.start_idx += r.out.info->info1.count;
6974 if (!test_each_DisplayInfo_user(b, tctx, &r, NULL)) {
6977 r.in.start_idx += r.out.info->info2.count;
6980 r.in.start_idx += r.out.info->info3.count;
6983 r.in.start_idx += r.out.info->info4.count;
6986 r.in.start_idx += r.out.info->info5.count;
6990 dom_info.in.domain_handle = handle;
6991 dom_info.in.level = 2;
6992 dom_info.out.info = &info;
6994 /* Check number of users returned is correct */
6995 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &dom_info),
6996 "QueryDomainInfo failed");
6997 if (!NT_STATUS_IS_OK(dom_info.out.result)) {
6998 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo level %u failed - %s\n",
6999 r.in.level, nt_errstr(dom_info.out.result));
7003 switch (r.in.level) {
7006 if (info->general.num_users < r.in.start_idx) {
7007 /* On AD deployments this numbers don't match
7008 * since QueryDisplayInfo returns universal and
7009 * global groups, QueryDomainInfo only global
7011 if (torture_setting_bool(tctx, "samba3", false)) {
7012 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
7013 r.in.start_idx, info->general.num_groups,
7014 info->general.domain_name.string);
7018 if (!seen_testuser) {
7019 struct policy_handle user_handle;
7020 if (NT_STATUS_IS_OK(test_OpenUser_byname(b, tctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
7021 torture_result(tctx, TORTURE_FAIL, "Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
7022 info->general.domain_name.string);
7024 test_samr_handle_Close(b, tctx, &user_handle);
7030 if (info->general.num_groups != r.in.start_idx) {
7031 /* On AD deployments this numbers don't match
7032 * since QueryDisplayInfo returns universal and
7033 * global groups, QueryDomainInfo only global
7035 if (torture_setting_bool(tctx, "samba3", false)) {
7036 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
7037 r.in.start_idx, info->general.num_groups,
7038 info->general.domain_name.string);
7051 static bool test_QueryDisplayInfo2(struct dcerpc_binding_handle *b,
7052 struct torture_context *tctx,
7053 struct policy_handle *handle)
7055 struct samr_QueryDisplayInfo2 r;
7057 uint16_t levels[] = {1, 2, 3, 4, 5};
7059 uint32_t total_size;
7060 uint32_t returned_size;
7061 union samr_DispInfo info;
7063 for (i=0;i<ARRAY_SIZE(levels);i++) {
7064 torture_comment(tctx, "Testing QueryDisplayInfo2 level %u\n", levels[i]);
7066 r.in.domain_handle = handle;
7067 r.in.level = levels[i];
7069 r.in.max_entries = 1000;
7070 r.in.buf_size = (uint32_t)-1;
7071 r.out.total_size = &total_size;
7072 r.out.returned_size = &returned_size;
7075 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo2_r(b, tctx, &r),
7076 "QueryDisplayInfo2 failed");
7077 if (!NT_STATUS_IS_OK(r.out.result)) {
7078 torture_result(tctx, TORTURE_FAIL, "QueryDisplayInfo2 level %u failed - %s\n",
7079 levels[i], nt_errstr(r.out.result));
7087 static bool test_QueryDisplayInfo3(struct dcerpc_binding_handle *b,
7088 struct torture_context *tctx,
7089 struct policy_handle *handle)
7091 struct samr_QueryDisplayInfo3 r;
7093 uint16_t levels[] = {1, 2, 3, 4, 5};
7095 uint32_t total_size;
7096 uint32_t returned_size;
7097 union samr_DispInfo info;
7099 for (i=0;i<ARRAY_SIZE(levels);i++) {
7100 torture_comment(tctx, "Testing QueryDisplayInfo3 level %u\n", levels[i]);
7102 r.in.domain_handle = handle;
7103 r.in.level = levels[i];
7105 r.in.max_entries = 1000;
7106 r.in.buf_size = (uint32_t)-1;
7107 r.out.total_size = &total_size;
7108 r.out.returned_size = &returned_size;
7111 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo3_r(b, tctx, &r),
7112 "QueryDisplayInfo3 failed");
7113 if (!NT_STATUS_IS_OK(r.out.result)) {
7114 torture_result(tctx, TORTURE_FAIL, "QueryDisplayInfo3 level %u failed - %s\n",
7115 levels[i], nt_errstr(r.out.result));
7124 static bool test_QueryDisplayInfo_continue(struct dcerpc_binding_handle *b,
7125 struct torture_context *tctx,
7126 struct policy_handle *handle)
7128 struct samr_QueryDisplayInfo r;
7130 uint32_t total_size;
7131 uint32_t returned_size;
7132 union samr_DispInfo info;
7134 torture_comment(tctx, "Testing QueryDisplayInfo continuation\n");
7136 r.in.domain_handle = handle;
7139 r.in.max_entries = 1;
7140 r.in.buf_size = (uint32_t)-1;
7141 r.out.total_size = &total_size;
7142 r.out.returned_size = &returned_size;
7146 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &r),
7147 "QueryDisplayInfo failed");
7148 if (NT_STATUS_IS_OK(r.out.result) && *r.out.returned_size != 0) {
7149 if (r.out.info->info1.entries[0].idx != r.in.start_idx + 1) {
7150 torture_result(tctx, TORTURE_FAIL, "expected idx %d but got %d\n",
7152 r.out.info->info1.entries[0].idx);
7156 if (!NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) &&
7157 !NT_STATUS_IS_OK(r.out.result)) {
7158 torture_result(tctx, TORTURE_FAIL, "QueryDisplayInfo level %u failed - %s\n",
7159 r.in.level, nt_errstr(r.out.result));
7164 } while ((NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) ||
7165 NT_STATUS_IS_OK(r.out.result)) &&
7166 *r.out.returned_size != 0);
7171 static bool test_QueryDomainInfo(struct dcerpc_pipe *p,
7172 struct torture_context *tctx,
7173 struct policy_handle *handle)
7175 struct samr_QueryDomainInfo r;
7176 union samr_DomainInfo *info = NULL;
7177 struct samr_SetDomainInfo s;
7178 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
7179 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
7182 struct dcerpc_binding_handle *b = p->binding_handle;
7183 const char *domain_comment = talloc_asprintf(tctx,
7184 "Tortured by Samba4 RPC-SAMR: %s",
7185 timestring(tctx, time(NULL)));
7187 s.in.domain_handle = handle;
7189 s.in.info = talloc(tctx, union samr_DomainInfo);
7191 s.in.info->oem.oem_information.string = domain_comment;
7192 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
7193 "SetDomainInfo failed");
7194 if (!NT_STATUS_IS_OK(s.out.result)) {
7195 torture_result(tctx, TORTURE_FAIL, "SetDomainInfo level %u (set comment) failed - %s\n",
7196 s.in.level, nt_errstr(s.out.result));
7200 for (i=0;i<ARRAY_SIZE(levels);i++) {
7201 torture_comment(tctx, "Testing QueryDomainInfo level %u\n", levels[i]);
7203 r.in.domain_handle = handle;
7204 r.in.level = levels[i];
7207 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &r),
7208 "QueryDomainInfo failed");
7209 if (!NT_STATUS_IS_OK(r.out.result)) {
7210 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo level %u failed - %s\n",
7211 r.in.level, nt_errstr(r.out.result));
7216 switch (levels[i]) {
7218 if (strcmp(info->general.oem_information.string, domain_comment) != 0) {
7219 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
7220 levels[i], info->general.oem_information.string, domain_comment);
7221 if (!torture_setting_bool(tctx, "samba3", false)) {
7225 if (!info->general.primary.string) {
7226 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo level %u returned no PDC name\n",
7229 } else if (info->general.role == SAMR_ROLE_DOMAIN_PDC) {
7230 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), info->general.primary.string) != 0) {
7231 if (torture_setting_bool(tctx, "samba3", false)) {
7232 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",
7233 levels[i], info->general.primary.string, dcerpc_server_name(p));
7239 if (strcmp(info->oem.oem_information.string, domain_comment) != 0) {
7240 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
7241 levels[i], info->oem.oem_information.string, domain_comment);
7242 if (!torture_setting_bool(tctx, "samba3", false)) {
7248 if (!info->info6.primary.string) {
7249 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo level %u returned no PDC name\n",
7255 if (strcmp(info->general2.general.oem_information.string, domain_comment) != 0) {
7256 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
7257 levels[i], info->general2.general.oem_information.string, domain_comment);
7258 if (!torture_setting_bool(tctx, "samba3", false)) {
7265 torture_comment(tctx, "Testing SetDomainInfo level %u\n", levels[i]);
7267 s.in.domain_handle = handle;
7268 s.in.level = levels[i];
7271 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
7272 "SetDomainInfo failed");
7274 if (!NT_STATUS_IS_OK(s.out.result)) {
7275 torture_result(tctx, TORTURE_FAIL, "SetDomainInfo level %u failed - %s\n",
7276 r.in.level, nt_errstr(s.out.result));
7281 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, s.out.result)) {
7282 torture_result(tctx, TORTURE_FAIL, "SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
7283 r.in.level, nt_errstr(s.out.result));
7289 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &r),
7290 "QueryDomainInfo failed");
7291 if (!NT_STATUS_IS_OK(r.out.result)) {
7292 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo level %u failed - %s\n",
7293 r.in.level, nt_errstr(r.out.result));
7303 static bool test_QueryDomainInfo2(struct dcerpc_binding_handle *b,
7304 struct torture_context *tctx,
7305 struct policy_handle *handle)
7307 struct samr_QueryDomainInfo2 r;
7308 union samr_DomainInfo *info = NULL;
7309 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
7313 for (i=0;i<ARRAY_SIZE(levels);i++) {
7314 torture_comment(tctx, "Testing QueryDomainInfo2 level %u\n", levels[i]);
7316 r.in.domain_handle = handle;
7317 r.in.level = levels[i];
7320 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo2_r(b, tctx, &r),
7321 "QueryDomainInfo2 failed");
7322 if (!NT_STATUS_IS_OK(r.out.result)) {
7323 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo2 level %u failed - %s\n",
7324 r.in.level, nt_errstr(r.out.result));
7333 /* Test whether querydispinfo level 5 and enumdomgroups return the same
7334 set of group names. */
7335 static bool test_GroupList(struct dcerpc_binding_handle *b,
7336 struct torture_context *tctx,
7337 struct dom_sid *domain_sid,
7338 struct policy_handle *handle)
7340 struct samr_EnumDomainGroups q1;
7341 struct samr_QueryDisplayInfo q2;
7343 uint32_t resume_handle=0;
7344 struct samr_SamArray *sam = NULL;
7345 uint32_t num_entries = 0;
7348 uint32_t total_size;
7349 uint32_t returned_size;
7350 union samr_DispInfo info;
7352 size_t num_names = 0;
7353 const char **names = NULL;
7355 bool builtin_domain = dom_sid_compare(domain_sid,
7356 &global_sid_Builtin) == 0;
7358 torture_comment(tctx, "Testing coherency of querydispinfo vs enumdomgroups\n");
7360 q1.in.domain_handle = handle;
7361 q1.in.resume_handle = &resume_handle;
7363 q1.out.resume_handle = &resume_handle;
7364 q1.out.num_entries = &num_entries;
7367 status = STATUS_MORE_ENTRIES;
7368 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
7369 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainGroups_r(b, tctx, &q1),
7370 "EnumDomainGroups failed");
7371 status = q1.out.result;
7373 if (!NT_STATUS_IS_OK(status) &&
7374 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
7377 for (i=0; i<*q1.out.num_entries; i++) {
7378 add_string_to_array(tctx,
7379 sam->entries[i].name.string,
7380 &names, &num_names);
7384 torture_assert_ntstatus_ok(tctx, status, "EnumDomainGroups");
7386 torture_assert(tctx, sam, "EnumDomainGroups failed to return sam");
7388 if (builtin_domain) {
7389 torture_assert(tctx, num_names == 0,
7390 "EnumDomainGroups shouldn't return any group in the builtin domain!");
7393 q2.in.domain_handle = handle;
7395 q2.in.start_idx = 0;
7396 q2.in.max_entries = 5;
7397 q2.in.buf_size = (uint32_t)-1;
7398 q2.out.total_size = &total_size;
7399 q2.out.returned_size = &returned_size;
7400 q2.out.info = &info;
7402 status = STATUS_MORE_ENTRIES;
7403 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
7404 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &q2),
7405 "QueryDisplayInfo failed");
7406 status = q2.out.result;
7407 if (!NT_STATUS_IS_OK(status) &&
7408 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
7411 for (i=0; i<q2.out.info->info5.count; i++) {
7413 const char *name = q2.out.info->info5.entries[i].account_name.string;
7415 for (j=0; j<num_names; j++) {
7416 if (names[j] == NULL)
7418 if (strequal(names[j], name)) {
7425 if ((!found) && (!builtin_domain)) {
7426 torture_result(tctx, TORTURE_FAIL, "QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
7431 q2.in.start_idx += q2.out.info->info5.count;
7434 if (!NT_STATUS_IS_OK(status)) {
7435 torture_result(tctx, TORTURE_FAIL, "QueryDisplayInfo level 5 failed - %s\n",
7440 if (builtin_domain) {
7441 torture_assert(tctx, q2.in.start_idx != 0,
7442 "QueryDisplayInfo should return all domain groups also on the builtin domain handle!");
7445 for (i=0; i<num_names; i++) {
7446 if (names[i] != NULL) {
7447 torture_result(tctx, TORTURE_FAIL, "EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
7456 static bool test_DeleteDomainGroup(struct dcerpc_binding_handle *b,
7457 struct torture_context *tctx,
7458 struct policy_handle *group_handle)
7460 struct samr_DeleteDomainGroup d;
7462 torture_comment(tctx, "Testing DeleteDomainGroup\n");
7464 d.in.group_handle = group_handle;
7465 d.out.group_handle = group_handle;
7467 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomainGroup_r(b, tctx, &d),
7468 "DeleteDomainGroup failed");
7469 torture_assert_ntstatus_ok(tctx, d.out.result, "DeleteDomainGroup");
7474 static bool test_TestPrivateFunctionsDomain(struct dcerpc_binding_handle *b,
7475 struct torture_context *tctx,
7476 struct policy_handle *domain_handle)
7478 struct samr_TestPrivateFunctionsDomain r;
7481 torture_comment(tctx, "Testing TestPrivateFunctionsDomain\n");
7483 r.in.domain_handle = domain_handle;
7485 torture_assert_ntstatus_ok(tctx, dcerpc_samr_TestPrivateFunctionsDomain_r(b, tctx, &r),
7486 "TestPrivateFunctionsDomain failed");
7487 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsDomain");
7492 static bool test_RidToSid(struct dcerpc_binding_handle *b,
7493 struct torture_context *tctx,
7494 struct dom_sid *domain_sid,
7495 struct policy_handle *domain_handle)
7497 struct samr_RidToSid r;
7499 struct dom_sid *calc_sid, *out_sid;
7500 int rids[] = { 0, 42, 512, 10200 };
7503 for (i=0;i<ARRAY_SIZE(rids);i++) {
7504 torture_comment(tctx, "Testing RidToSid\n");
7506 calc_sid = dom_sid_dup(tctx, domain_sid);
7507 r.in.domain_handle = domain_handle;
7509 r.out.sid = &out_sid;
7511 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RidToSid_r(b, tctx, &r),
7513 if (!NT_STATUS_IS_OK(r.out.result)) {
7514 torture_result(tctx, TORTURE_FAIL, "RidToSid for %d failed - %s\n", rids[i], nt_errstr(r.out.result));
7517 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
7519 if (!dom_sid_equal(calc_sid, out_sid)) {
7520 torture_result(tctx, TORTURE_FAIL, "RidToSid for %d failed - got %s, expected %s\n", rids[i],
7521 dom_sid_string(tctx, out_sid),
7522 dom_sid_string(tctx, calc_sid));
7531 static bool test_GetBootKeyInformation(struct dcerpc_binding_handle *b,
7532 struct torture_context *tctx,
7533 struct policy_handle *domain_handle)
7535 struct samr_GetBootKeyInformation r;
7537 uint32_t unknown = 0;
7540 torture_comment(tctx, "Testing GetBootKeyInformation\n");
7542 r.in.domain_handle = domain_handle;
7543 r.out.unknown = &unknown;
7545 status = dcerpc_samr_GetBootKeyInformation_r(b, tctx, &r);
7546 if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_OK(r.out.result)) {
7547 status = r.out.result;
7549 if (!NT_STATUS_IS_OK(status)) {
7550 /* w2k3 seems to fail this sometimes and pass it sometimes */
7551 torture_comment(tctx, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
7557 static bool test_AddGroupMember(struct dcerpc_binding_handle *b,
7558 struct torture_context *tctx,
7559 struct policy_handle *domain_handle,
7560 struct policy_handle *group_handle)
7563 struct samr_AddGroupMember r;
7564 struct samr_DeleteGroupMember d;
7565 struct samr_QueryGroupMember q;
7566 struct samr_RidAttrArray *rids = NULL;
7567 struct samr_SetMemberAttributesOfGroup s;
7569 bool found_member = false;
7572 status = test_LookupName(b, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
7573 torture_assert_ntstatus_ok(tctx, status, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME);
7575 r.in.group_handle = group_handle;
7577 r.in.flags = 0; /* ??? */
7579 torture_comment(tctx, "Testing AddGroupMember, QueryGroupMember and DeleteGroupMember\n");
7581 d.in.group_handle = group_handle;
7584 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteGroupMember_r(b, tctx, &d),
7585 "DeleteGroupMember failed");
7586 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_NOT_IN_GROUP, d.out.result, "DeleteGroupMember");
7588 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddGroupMember_r(b, tctx, &r),
7589 "AddGroupMember failed");
7590 torture_assert_ntstatus_ok(tctx, r.out.result, "AddGroupMember");
7592 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddGroupMember_r(b, tctx, &r),
7593 "AddGroupMember failed");
7594 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_IN_GROUP, r.out.result, "AddGroupMember");
7596 if (torture_setting_bool(tctx, "samba4", false) ||
7597 torture_setting_bool(tctx, "samba3", false)) {
7598 torture_comment(tctx, "skipping SetMemberAttributesOfGroup test against Samba\n");
7600 /* this one is quite strange. I am using random inputs in the
7601 hope of triggering an error that might give us a clue */
7603 s.in.group_handle = group_handle;
7604 s.in.unknown1 = random();
7605 s.in.unknown2 = random();
7607 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetMemberAttributesOfGroup_r(b, tctx, &s),
7608 "SetMemberAttributesOfGroup failed");
7609 torture_assert_ntstatus_ok(tctx, s.out.result, "SetMemberAttributesOfGroup");
7612 q.in.group_handle = group_handle;
7615 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupMember_r(b, tctx, &q),
7616 "QueryGroupMember failed");
7617 torture_assert_ntstatus_ok(tctx, q.out.result, "QueryGroupMember");
7618 torture_assert(tctx, rids, "QueryGroupMember did not fill in rids structure");
7620 for (i=0; i < rids->count; i++) {
7621 if (rids->rids[i] == rid) {
7622 found_member = true;
7626 torture_assert(tctx, found_member, "QueryGroupMember did not list newly added member");
7628 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteGroupMember_r(b, tctx, &d),
7629 "DeleteGroupMember failed");
7630 torture_assert_ntstatus_ok(tctx, d.out.result, "DeleteGroupMember");
7633 found_member = false;
7635 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupMember_r(b, tctx, &q),
7636 "QueryGroupMember failed");
7637 torture_assert_ntstatus_ok(tctx, q.out.result, "QueryGroupMember");
7638 torture_assert(tctx, rids, "QueryGroupMember did not fill in rids structure");
7640 for (i=0; i < rids->count; i++) {
7641 if (rids->rids[i] == rid) {
7642 found_member = true;
7646 torture_assert(tctx, !found_member, "QueryGroupMember does still list removed member");
7648 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddGroupMember_r(b, tctx, &r),
7649 "AddGroupMember failed");
7650 torture_assert_ntstatus_ok(tctx, r.out.result, "AddGroupMember");
7656 static bool test_CreateDomainGroup(struct dcerpc_binding_handle *b,
7657 struct torture_context *tctx,
7658 struct policy_handle *domain_handle,
7659 const char *group_name,
7660 struct policy_handle *group_handle,
7661 struct dom_sid *domain_sid,
7664 struct samr_CreateDomainGroup r;
7666 struct lsa_String name;
7669 init_lsa_String(&name, group_name);
7671 r.in.domain_handle = domain_handle;
7673 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7674 r.out.group_handle = group_handle;
7677 torture_comment(tctx, "Testing CreateDomainGroup(%s)\n", r.in.name->string);
7679 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomainGroup_r(b, tctx, &r),
7680 "CreateDomainGroup failed");
7682 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
7683 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED)) {
7684 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.name->string);
7687 torture_result(tctx, TORTURE_FAIL, "Server should have refused create of '%s', got %s instead\n", r.in.name->string,
7688 nt_errstr(r.out.result));
7693 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_GROUP_EXISTS)) {
7694 if (!test_DeleteGroup_byname(b, tctx, domain_handle, r.in.name->string)) {
7695 torture_result(tctx, TORTURE_FAIL, "CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
7696 nt_errstr(r.out.result));
7699 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomainGroup_r(b, tctx, &r),
7700 "CreateDomainGroup failed");
7702 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_USER_EXISTS)) {
7703 if (!test_DeleteUser_byname(b, tctx, domain_handle, r.in.name->string)) {
7705 torture_result(tctx, TORTURE_FAIL, "CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
7706 nt_errstr(r.out.result));
7709 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomainGroup_r(b, tctx, &r),
7710 "CreateDomainGroup failed");
7712 torture_assert_ntstatus_ok(tctx, r.out.result, "CreateDomainGroup");
7718 if (!test_AddGroupMember(b, tctx, domain_handle, group_handle)) {
7719 torture_result(tctx, TORTURE_FAIL, "CreateDomainGroup failed - %s\n", nt_errstr(r.out.result));
7723 if (!test_SetGroupInfo(b, tctx, group_handle)) {
7732 its not totally clear what this does. It seems to accept any sid you like.
7734 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_binding_handle *b,
7735 struct torture_context *tctx,
7736 struct policy_handle *domain_handle)
7738 struct samr_RemoveMemberFromForeignDomain r;
7740 r.in.domain_handle = domain_handle;
7741 r.in.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-12-34-56-78");
7743 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RemoveMemberFromForeignDomain_r(b, tctx, &r),
7744 "RemoveMemberFromForeignDomain failed");
7745 torture_assert_ntstatus_ok(tctx, r.out.result, "RemoveMemberFromForeignDomain");
7750 static bool test_EnumDomainUsers(struct dcerpc_binding_handle *b,
7751 struct torture_context *tctx,
7752 struct policy_handle *domain_handle,
7753 uint32_t *total_num_entries_p)
7756 struct samr_EnumDomainUsers r;
7757 uint32_t resume_handle = 0;
7758 uint32_t num_entries = 0;
7759 uint32_t total_num_entries = 0;
7760 struct samr_SamArray *sam;
7762 r.in.domain_handle = domain_handle;
7763 r.in.acct_flags = 0;
7764 r.in.max_size = (uint32_t)-1;
7765 r.in.resume_handle = &resume_handle;
7768 r.out.num_entries = &num_entries;
7769 r.out.resume_handle = &resume_handle;
7771 torture_comment(tctx, "Testing EnumDomainUsers\n");
7774 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainUsers_r(b, tctx, &r),
7775 "EnumDomainUsers failed");
7776 if (NT_STATUS_IS_ERR(r.out.result)) {
7777 torture_assert_ntstatus_ok(tctx, r.out.result,
7778 "failed to enumerate users");
7780 status = r.out.result;
7782 total_num_entries += num_entries;
7783 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7785 if (total_num_entries_p) {
7786 *total_num_entries_p = total_num_entries;
7792 static bool test_EnumDomainGroups(struct dcerpc_binding_handle *b,
7793 struct torture_context *tctx,
7794 struct policy_handle *domain_handle,
7795 uint32_t *total_num_entries_p)
7798 struct samr_EnumDomainGroups r;
7799 uint32_t resume_handle = 0;
7800 uint32_t num_entries = 0;
7801 uint32_t total_num_entries = 0;
7802 struct samr_SamArray *sam;
7804 r.in.domain_handle = domain_handle;
7805 r.in.max_size = (uint32_t)-1;
7806 r.in.resume_handle = &resume_handle;
7809 r.out.num_entries = &num_entries;
7810 r.out.resume_handle = &resume_handle;
7812 torture_comment(tctx, "Testing EnumDomainGroups\n");
7815 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainGroups_r(b, tctx, &r),
7816 "EnumDomainGroups failed");
7817 if (NT_STATUS_IS_ERR(r.out.result)) {
7818 torture_assert_ntstatus_ok(tctx, r.out.result,
7819 "failed to enumerate groups");
7821 status = r.out.result;
7823 total_num_entries += num_entries;
7824 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7826 if (total_num_entries_p) {
7827 *total_num_entries_p = total_num_entries;
7833 static bool test_EnumDomainAliases(struct dcerpc_binding_handle *b,
7834 struct torture_context *tctx,
7835 struct policy_handle *domain_handle,
7836 uint32_t *total_num_entries_p)
7839 struct samr_EnumDomainAliases r;
7840 uint32_t resume_handle = 0;
7841 uint32_t num_entries = 0;
7842 uint32_t total_num_entries = 0;
7843 struct samr_SamArray *sam;
7845 r.in.domain_handle = domain_handle;
7846 r.in.max_size = (uint32_t)-1;
7847 r.in.resume_handle = &resume_handle;
7850 r.out.num_entries = &num_entries;
7851 r.out.resume_handle = &resume_handle;
7853 torture_comment(tctx, "Testing EnumDomainAliases\n");
7856 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainAliases_r(b, tctx, &r),
7857 "EnumDomainAliases failed");
7858 if (NT_STATUS_IS_ERR(r.out.result)) {
7859 torture_assert_ntstatus_ok(tctx, r.out.result,
7860 "failed to enumerate aliases");
7862 status = r.out.result;
7864 total_num_entries += num_entries;
7865 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7867 if (total_num_entries_p) {
7868 *total_num_entries_p = total_num_entries;
7874 static bool test_QueryDisplayInfo_level(struct dcerpc_binding_handle *b,
7875 struct torture_context *tctx,
7876 struct policy_handle *handle,
7878 uint32_t *total_num_entries_p)
7881 struct samr_QueryDisplayInfo r;
7882 uint32_t total_num_entries = 0;
7884 r.in.domain_handle = handle;
7887 r.in.max_entries = (uint32_t)-1;
7888 r.in.buf_size = (uint32_t)-1;
7890 torture_comment(tctx, "Testing QueryDisplayInfo\n");
7893 uint32_t total_size;
7894 uint32_t returned_size;
7895 union samr_DispInfo info;
7897 r.out.total_size = &total_size;
7898 r.out.returned_size = &returned_size;
7901 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &r),
7902 "failed to query displayinfo");
7903 if (NT_STATUS_IS_ERR(r.out.result)) {
7904 torture_assert_ntstatus_ok(tctx, r.out.result,
7905 "failed to query displayinfo");
7907 status = r.out.result;
7909 if (*r.out.returned_size == 0) {
7913 switch (r.in.level) {
7915 total_num_entries += info.info1.count;
7916 r.in.start_idx += info.info1.entries[info.info1.count - 1].idx + 1;
7919 total_num_entries += info.info2.count;
7920 r.in.start_idx += info.info2.entries[info.info2.count - 1].idx + 1;
7923 total_num_entries += info.info3.count;
7924 r.in.start_idx += info.info3.entries[info.info3.count - 1].idx + 1;
7927 total_num_entries += info.info4.count;
7928 r.in.start_idx += info.info4.entries[info.info4.count - 1].idx + 1;
7931 total_num_entries += info.info5.count;
7932 r.in.start_idx += info.info5.entries[info.info5.count - 1].idx + 1;
7938 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7940 if (total_num_entries_p) {
7941 *total_num_entries_p = total_num_entries;
7947 static bool test_ManyObjects(struct dcerpc_pipe *p,
7948 struct torture_context *tctx,
7949 struct policy_handle *domain_handle,
7950 struct dom_sid *domain_sid,
7951 struct torture_samr_context *ctx)
7953 uint32_t num_total = ctx->num_objects_large_dc;
7954 uint32_t num_enum = 0;
7955 uint32_t num_disp = 0;
7956 uint32_t num_created = 0;
7957 uint32_t num_anounced = 0;
7959 struct dcerpc_binding_handle *b = p->binding_handle;
7961 struct policy_handle *handles = talloc_zero_array(tctx, struct policy_handle, num_total);
7966 struct samr_QueryDomainInfo2 r;
7967 union samr_DomainInfo *info;
7968 r.in.domain_handle = domain_handle;
7972 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo2_r(b, tctx, &r),
7973 "QueryDomainInfo2 failed");
7974 torture_assert_ntstatus_ok(tctx, r.out.result,
7975 "failed to query domain info");
7977 switch (ctx->choice) {
7978 case TORTURE_SAMR_MANY_ACCOUNTS:
7979 num_anounced = info->general.num_users;
7981 case TORTURE_SAMR_MANY_GROUPS:
7982 num_anounced = info->general.num_groups;
7984 case TORTURE_SAMR_MANY_ALIASES:
7985 num_anounced = info->general.num_aliases;
7994 for (i=0; i < num_total; i++) {
7996 const char *name = NULL;
7998 switch (ctx->choice) {
7999 case TORTURE_SAMR_MANY_ACCOUNTS:
8000 name = talloc_asprintf(tctx, "%s%04d", TEST_ACCOUNT_NAME, i);
8001 torture_assert(tctx,
8002 test_CreateUser(p, tctx, domain_handle, name, &handles[i], domain_sid, 0, NULL, false),
8003 "failed to create user");
8005 case TORTURE_SAMR_MANY_GROUPS:
8006 name = talloc_asprintf(tctx, "%s%04d", TEST_GROUPNAME, i);
8007 torture_assert(tctx,
8008 test_CreateDomainGroup(b, tctx, domain_handle, name, &handles[i], domain_sid, false),
8009 "failed to create group");
8011 case TORTURE_SAMR_MANY_ALIASES:
8012 name = talloc_asprintf(tctx, "%s%04d", TEST_ALIASNAME, i);
8013 torture_assert(tctx,
8014 test_CreateAlias(b, tctx, domain_handle, name, &handles[i], domain_sid, false),
8015 "failed to create alias");
8020 if (!ndr_policy_handle_empty(&handles[i])) {
8027 switch (ctx->choice) {
8028 case TORTURE_SAMR_MANY_ACCOUNTS:
8029 torture_assert(tctx,
8030 test_EnumDomainUsers(b, tctx, domain_handle, &num_enum),
8031 "failed to enum users");
8033 case TORTURE_SAMR_MANY_GROUPS:
8034 torture_assert(tctx,
8035 test_EnumDomainGroups(b, tctx, domain_handle, &num_enum),
8036 "failed to enum groups");
8038 case TORTURE_SAMR_MANY_ALIASES:
8039 torture_assert(tctx,
8040 test_EnumDomainAliases(b, tctx, domain_handle, &num_enum),
8041 "failed to enum aliases");
8049 switch (ctx->choice) {
8050 case TORTURE_SAMR_MANY_ACCOUNTS:
8051 torture_assert(tctx,
8052 test_QueryDisplayInfo_level(b, tctx, domain_handle, 1, &num_disp),
8053 "failed to query display info");
8055 case TORTURE_SAMR_MANY_GROUPS:
8056 torture_assert(tctx,
8057 test_QueryDisplayInfo_level(b, tctx, domain_handle, 3, &num_disp),
8058 "failed to query display info");
8060 case TORTURE_SAMR_MANY_ALIASES:
8061 /* no aliases in dispinfo */
8067 /* close or delete */
8069 for (i=0; i < num_total; i++) {
8071 if (ndr_policy_handle_empty(&handles[i])) {
8075 if (torture_setting_bool(tctx, "samba3", false)) {
8076 torture_assert(tctx,
8077 test_samr_handle_Close(b, tctx, &handles[i]),
8078 "failed to close handle");
8080 switch (ctx->choice) {
8081 case TORTURE_SAMR_MANY_ACCOUNTS:
8082 torture_assert(tctx,
8083 test_DeleteUser(b, tctx, &handles[i]),
8084 "failed to delete user");
8086 case TORTURE_SAMR_MANY_GROUPS:
8087 torture_assert(tctx,
8088 test_DeleteDomainGroup(b, tctx, &handles[i]),
8089 "failed to delete group");
8091 case TORTURE_SAMR_MANY_ALIASES:
8092 torture_assert(tctx,
8093 test_DeleteAlias(b, tctx, &handles[i]),
8094 "failed to delete alias");
8102 talloc_free(handles);
8104 if (ctx->choice == TORTURE_SAMR_MANY_ACCOUNTS && num_enum != num_anounced + num_created) {
8105 torture_comment(tctx,
8106 "unexpected number of results (%u) returned in enum call, expected %u\n",
8107 num_enum, num_anounced + num_created);
8109 torture_comment(tctx,
8110 "unexpected number of results (%u) returned in dispinfo, call, expected %u\n",
8111 num_disp, num_anounced + num_created);
8117 static bool test_Connect(struct dcerpc_binding_handle *b,
8118 struct torture_context *tctx,
8119 struct policy_handle *handle);
8121 static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
8122 struct torture_samr_context *ctx, struct dom_sid *sid)
8124 struct samr_OpenDomain r;
8125 struct policy_handle domain_handle;
8126 struct policy_handle alias_handle;
8127 struct policy_handle user_handle;
8128 struct policy_handle group_handle;
8130 struct dcerpc_binding_handle *b = p->binding_handle;
8132 ZERO_STRUCT(alias_handle);
8133 ZERO_STRUCT(user_handle);
8134 ZERO_STRUCT(group_handle);
8135 ZERO_STRUCT(domain_handle);
8137 torture_comment(tctx, "Testing OpenDomain of %s\n", dom_sid_string(tctx, sid));
8139 r.in.connect_handle = &ctx->handle;
8140 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
8142 r.out.domain_handle = &domain_handle;
8144 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenDomain_r(b, tctx, &r),
8145 "OpenDomain failed");
8146 torture_assert_ntstatus_ok(tctx, r.out.result, "OpenDomain failed");
8148 /* run the domain tests with the main handle closed - this tests
8149 the servers reference counting */
8150 torture_assert(tctx, test_samr_handle_Close(b, tctx, &ctx->handle), "Failed to close SAMR handle");
8152 switch (ctx->choice) {
8153 case TORTURE_SAMR_PASSWORDS:
8154 case TORTURE_SAMR_USER_PRIVILEGES:
8155 if (!torture_setting_bool(tctx, "samba3", false)) {
8156 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, NULL);
8158 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
8160 torture_result(tctx, TORTURE_FAIL, "Testing PASSWORDS or PRIVILEGES on domain %s failed!\n", dom_sid_string(tctx, sid));
8163 case TORTURE_SAMR_USER_ATTRIBUTES:
8164 if (!torture_setting_bool(tctx, "samba3", false)) {
8165 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, NULL);
8167 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
8168 /* This test needs 'complex' users to validate */
8169 ret &= test_QueryDisplayInfo(b, tctx, &domain_handle);
8171 torture_result(tctx, TORTURE_FAIL, "Testing ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
8174 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
8175 case TORTURE_SAMR_PASSWORDS_BADPWDCOUNT:
8176 case TORTURE_SAMR_PASSWORDS_LOCKOUT:
8177 if (!torture_setting_bool(tctx, "samba3", false)) {
8178 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, ctx->machine_credentials);
8180 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, ctx->machine_credentials, true);
8182 torture_result(tctx, TORTURE_FAIL, "Testing PASSWORDS PWDLASTSET or BADPWDCOUNT on domain %s failed!\n", dom_sid_string(tctx, sid));
8185 case TORTURE_SAMR_MANY_ACCOUNTS:
8186 case TORTURE_SAMR_MANY_GROUPS:
8187 case TORTURE_SAMR_MANY_ALIASES:
8188 ret &= test_ManyObjects(p, tctx, &domain_handle, sid, ctx);
8190 torture_result(tctx, TORTURE_FAIL, "Testing MANY-{ACCOUNTS,GROUPS,ALIASES} on domain %s failed!\n", dom_sid_string(tctx, sid));
8193 case TORTURE_SAMR_OTHER:
8194 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
8196 torture_result(tctx, TORTURE_FAIL, "Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid));
8198 if (!torture_setting_bool(tctx, "samba3", false)) {
8199 ret &= test_QuerySecurity(b, tctx, &domain_handle);
8201 ret &= test_RemoveMemberFromForeignDomain(b, tctx, &domain_handle);
8202 ret &= test_CreateAlias(b, tctx, &domain_handle, TEST_ALIASNAME, &alias_handle, sid, true);
8203 ret &= test_CreateDomainGroup(b, tctx, &domain_handle, TEST_GROUPNAME, &group_handle, sid, true);
8204 ret &= test_GetAliasMembership(b, tctx, &domain_handle);
8205 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
8206 ret &= test_QueryDomainInfo2(b, tctx, &domain_handle);
8207 ret &= test_EnumDomainUsers_all(b, tctx, &domain_handle);
8208 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
8209 ret &= test_EnumDomainGroups_all(b, tctx, &domain_handle);
8210 ret &= test_EnumDomainAliases_all(b, tctx, &domain_handle);
8211 ret &= test_QueryDisplayInfo2(b, tctx, &domain_handle);
8212 ret &= test_QueryDisplayInfo3(b, tctx, &domain_handle);
8213 ret &= test_QueryDisplayInfo_continue(b, tctx, &domain_handle);
8215 if (torture_setting_bool(tctx, "samba4", false)) {
8216 torture_comment(tctx, "skipping GetDisplayEnumerationIndex test against Samba4\n");
8218 ret &= test_GetDisplayEnumerationIndex(b, tctx, &domain_handle);
8219 ret &= test_GetDisplayEnumerationIndex2(b, tctx, &domain_handle);
8221 ret &= test_GroupList(b, tctx, sid, &domain_handle);
8222 ret &= test_TestPrivateFunctionsDomain(b, tctx, &domain_handle);
8223 ret &= test_RidToSid(b, tctx, sid, &domain_handle);
8224 ret &= test_GetBootKeyInformation(b, tctx, &domain_handle);
8226 torture_comment(tctx, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx, sid));
8231 if (!ndr_policy_handle_empty(&user_handle) &&
8232 !test_DeleteUser(b, tctx, &user_handle)) {
8236 if (!ndr_policy_handle_empty(&alias_handle) &&
8237 !test_DeleteAlias(b, tctx, &alias_handle)) {
8241 if (!ndr_policy_handle_empty(&group_handle) &&
8242 !test_DeleteDomainGroup(b, tctx, &group_handle)) {
8246 torture_assert(tctx, test_samr_handle_Close(b, tctx, &domain_handle), "Failed to close SAMR domain handle");
8248 torture_assert(tctx, test_Connect(b, tctx, &ctx->handle), "Faile to re-connect SAMR handle");
8249 /* reconnect the main handle */
8252 torture_result(tctx, TORTURE_FAIL, "Testing domain %s failed!\n", dom_sid_string(tctx, sid));
8258 static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
8259 struct torture_samr_context *ctx, const char *domain)
8261 struct samr_LookupDomain r;
8262 struct dom_sid2 *sid = NULL;
8263 struct lsa_String n1;
8264 struct lsa_String n2;
8266 struct dcerpc_binding_handle *b = p->binding_handle;
8268 torture_comment(tctx, "Testing LookupDomain(%s)\n", domain);
8270 /* check for correct error codes */
8271 r.in.connect_handle = &ctx->handle;
8272 r.in.domain_name = &n2;
8276 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupDomain_r(b, tctx, &r),
8277 "LookupDomain failed");
8278 torture_assert_ntstatus_equal(tctx, NT_STATUS_INVALID_PARAMETER, r.out.result, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
8280 init_lsa_String(&n2, "xxNODOMAINxx");
8282 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupDomain_r(b, tctx, &r),
8283 "LookupDomain failed");
8284 torture_assert_ntstatus_equal(tctx, NT_STATUS_NO_SUCH_DOMAIN, r.out.result, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
8286 r.in.connect_handle = &ctx->handle;
8288 init_lsa_String(&n1, domain);
8289 r.in.domain_name = &n1;
8291 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupDomain_r(b, tctx, &r),
8292 "LookupDomain failed");
8293 torture_assert_ntstatus_ok(tctx, r.out.result, "LookupDomain");
8295 if (!test_GetDomPwInfo(p, tctx, &n1)) {
8299 if (!test_OpenDomain(p, tctx, ctx, *r.out.sid)) {
8307 static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
8308 struct torture_samr_context *ctx)
8310 struct samr_EnumDomains r;
8311 uint32_t resume_handle = 0;
8312 uint32_t num_entries = 0;
8313 struct samr_SamArray *sam = NULL;
8316 struct dcerpc_binding_handle *b = p->binding_handle;
8318 r.in.connect_handle = &ctx->handle;
8319 r.in.resume_handle = &resume_handle;
8320 r.in.buf_size = (uint32_t)-1;
8321 r.out.resume_handle = &resume_handle;
8322 r.out.num_entries = &num_entries;
8325 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomains_r(b, tctx, &r),
8326 "EnumDomains failed");
8327 torture_assert_ntstatus_ok(tctx, r.out.result, "EnumDomains failed");
8333 for (i=0;i<sam->count;i++) {
8334 if (!test_LookupDomain(p, tctx, ctx,
8335 sam->entries[i].name.string)) {
8340 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomains_r(b, tctx, &r),
8341 "EnumDomains failed");
8342 torture_assert_ntstatus_ok(tctx, r.out.result, "EnumDomains failed");
8348 static bool test_Connect(struct dcerpc_binding_handle *b,
8349 struct torture_context *tctx,
8350 struct policy_handle *handle)
8352 struct samr_Connect r;
8353 struct samr_Connect2 r2;
8354 struct samr_Connect3 r3;
8355 struct samr_Connect4 r4;
8356 struct samr_Connect5 r5;
8357 union samr_ConnectInfo info;
8358 struct policy_handle h;
8359 uint32_t level_out = 0;
8360 bool ret = true, got_handle = false;
8362 torture_comment(tctx, "Testing samr_Connect\n");
8364 r.in.system_name = NULL;
8365 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
8366 r.out.connect_handle = &h;
8368 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect_r(b, tctx, &r),
8370 if (!NT_STATUS_IS_OK(r.out.result)) {
8371 torture_comment(tctx, "Connect failed - %s\n", nt_errstr(r.out.result));
8378 torture_comment(tctx, "Testing samr_Connect2\n");
8380 r2.in.system_name = NULL;
8381 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
8382 r2.out.connect_handle = &h;
8384 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect2_r(b, tctx, &r2),
8386 if (!NT_STATUS_IS_OK(r2.out.result)) {
8387 torture_comment(tctx, "Connect2 failed - %s\n", nt_errstr(r2.out.result));
8391 test_samr_handle_Close(b, tctx, handle);
8397 torture_comment(tctx, "Testing samr_Connect3\n");
8399 r3.in.system_name = NULL;
8401 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
8402 r3.out.connect_handle = &h;
8404 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect3_r(b, tctx, &r3),
8406 if (!NT_STATUS_IS_OK(r3.out.result)) {
8407 torture_result(tctx, TORTURE_FAIL, "Connect3 failed - %s\n", nt_errstr(r3.out.result));
8411 test_samr_handle_Close(b, tctx, handle);
8417 torture_comment(tctx, "Testing samr_Connect4\n");
8419 r4.in.system_name = "";
8420 r4.in.client_version = 0;
8421 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
8422 r4.out.connect_handle = &h;
8424 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect4_r(b, tctx, &r4),
8426 if (!NT_STATUS_IS_OK(r4.out.result)) {
8427 torture_result(tctx, TORTURE_FAIL, "Connect4 failed - %s\n", nt_errstr(r4.out.result));
8431 test_samr_handle_Close(b, tctx, handle);
8437 torture_comment(tctx, "Testing samr_Connect5\n");
8439 info.info1.client_version = 0;
8440 info.info1.unknown2 = 0;
8442 r5.in.system_name = "";
8443 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
8445 r5.out.level_out = &level_out;
8446 r5.in.info_in = &info;
8447 r5.out.info_out = &info;
8448 r5.out.connect_handle = &h;
8450 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect5_r(b, tctx, &r5),
8452 if (!NT_STATUS_IS_OK(r5.out.result)) {
8453 torture_result(tctx, TORTURE_FAIL, "Connect5 failed - %s\n", nt_errstr(r5.out.result));
8457 test_samr_handle_Close(b, tctx, handle);
8467 static bool test_samr_ValidatePassword(struct torture_context *tctx,
8468 struct dcerpc_pipe *p)
8470 struct samr_ValidatePassword r;
8471 union samr_ValidatePasswordReq req;
8472 union samr_ValidatePasswordRep *repp = NULL;
8474 const char *passwords[] = { "penguin", "p@ssw0rd", "p@ssw0rd123$", NULL };
8476 struct dcerpc_binding_handle *b = p->binding_handle;
8478 torture_comment(tctx, "Testing samr_ValidatePassword\n");
8480 if (p->conn->transport.transport != NCACN_IP_TCP) {
8481 torture_comment(tctx, "samr_ValidatePassword only should succeed over NCACN_IP_TCP!\n");
8485 r.in.level = NetValidatePasswordReset;
8490 req.req3.account.string = "non-existent-account-aklsdji";
8492 for (i=0; passwords[i]; i++) {
8493 req.req3.password.string = passwords[i];
8495 status = dcerpc_samr_ValidatePassword_r(b, tctx, &r);
8496 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE)) {
8497 torture_skip(tctx, "ValidatePassword not supported by server\n");
8499 torture_assert_ntstatus_ok(tctx, status,
8500 "samr_ValidatePassword failed");
8501 torture_assert_ntstatus_ok(tctx, r.out.result,
8502 "samr_ValidatePassword failed");
8503 torture_comment(tctx, "Server %s password '%s' with code %i\n",
8504 repp->ctr3.status==SAMR_VALIDATION_STATUS_SUCCESS?"allowed":"refused",
8505 req.req3.password.string, repp->ctr3.status);
8511 bool torture_rpc_samr(struct torture_context *torture)
8514 struct dcerpc_pipe *p;
8516 struct torture_samr_context *ctx;
8517 struct dcerpc_binding_handle *b;
8519 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8520 if (!NT_STATUS_IS_OK(status)) {
8523 b = p->binding_handle;
8525 ctx = talloc_zero(torture, struct torture_samr_context);
8527 ctx->choice = TORTURE_SAMR_OTHER;
8529 ret &= test_Connect(b, torture, &ctx->handle);
8531 if (!torture_setting_bool(torture, "samba3", false)) {
8532 ret &= test_QuerySecurity(b, torture, &ctx->handle);
8535 ret &= test_EnumDomains(p, torture, ctx);
8537 ret &= test_SetDsrmPassword(b, torture, &ctx->handle);
8539 ret &= test_Shutdown(b, torture, &ctx->handle);
8541 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8547 bool torture_rpc_samr_users(struct torture_context *torture)
8550 struct dcerpc_pipe *p;
8552 struct torture_samr_context *ctx;
8553 struct dcerpc_binding_handle *b;
8555 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8556 if (!NT_STATUS_IS_OK(status)) {
8559 b = p->binding_handle;
8561 ctx = talloc_zero(torture, struct torture_samr_context);
8563 ctx->choice = TORTURE_SAMR_USER_ATTRIBUTES;
8565 ret &= test_Connect(b, torture, &ctx->handle);
8567 if (!torture_setting_bool(torture, "samba3", false)) {
8568 ret &= test_QuerySecurity(b, torture, &ctx->handle);
8571 ret &= test_EnumDomains(p, torture, ctx);
8573 ret &= test_SetDsrmPassword(b, torture, &ctx->handle);
8575 ret &= test_Shutdown(b, torture, &ctx->handle);
8577 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8583 bool torture_rpc_samr_passwords(struct torture_context *torture)
8586 struct dcerpc_pipe *p;
8588 struct torture_samr_context *ctx;
8589 struct dcerpc_binding_handle *b;
8591 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8592 if (!NT_STATUS_IS_OK(status)) {
8595 b = p->binding_handle;
8597 ctx = talloc_zero(torture, struct torture_samr_context);
8599 ctx->choice = TORTURE_SAMR_PASSWORDS;
8601 ret &= test_Connect(b, torture, &ctx->handle);
8603 ret &= test_EnumDomains(p, torture, ctx);
8605 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8610 static bool torture_rpc_samr_pwdlastset(struct torture_context *torture,
8611 struct dcerpc_pipe *p2,
8612 struct cli_credentials *machine_credentials)
8615 struct dcerpc_pipe *p;
8617 struct torture_samr_context *ctx;
8618 struct dcerpc_binding_handle *b;
8620 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8621 if (!NT_STATUS_IS_OK(status)) {
8624 b = p->binding_handle;
8626 ctx = talloc_zero(torture, struct torture_samr_context);
8628 ctx->choice = TORTURE_SAMR_PASSWORDS_PWDLASTSET;
8629 ctx->machine_credentials = machine_credentials;
8631 ret &= test_Connect(b, torture, &ctx->handle);
8633 ret &= test_EnumDomains(p, torture, ctx);
8635 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8640 struct torture_suite *torture_rpc_samr_passwords_pwdlastset(TALLOC_CTX *mem_ctx)
8642 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.passwords.pwdlastset");
8643 struct torture_rpc_tcase *tcase;
8645 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8647 TEST_ACCOUNT_NAME_PWD);
8649 torture_rpc_tcase_add_test_creds(tcase, "pwdLastSet",
8650 torture_rpc_samr_pwdlastset);
8655 static bool torture_rpc_samr_users_privileges_delete_user(struct torture_context *torture,
8656 struct dcerpc_pipe *p2,
8657 struct cli_credentials *machine_credentials)
8660 struct dcerpc_pipe *p;
8662 struct torture_samr_context *ctx;
8663 struct dcerpc_binding_handle *b;
8665 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8666 if (!NT_STATUS_IS_OK(status)) {
8669 b = p->binding_handle;
8671 ctx = talloc_zero(torture, struct torture_samr_context);
8673 ctx->choice = TORTURE_SAMR_USER_PRIVILEGES;
8674 ctx->machine_credentials = machine_credentials;
8676 ret &= test_Connect(b, torture, &ctx->handle);
8678 ret &= test_EnumDomains(p, torture, ctx);
8680 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8685 struct torture_suite *torture_rpc_samr_user_privileges(TALLOC_CTX *mem_ctx)
8687 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.users.privileges");
8688 struct torture_rpc_tcase *tcase;
8690 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8692 TEST_ACCOUNT_NAME_PWD);
8694 torture_rpc_tcase_add_test_creds(tcase, "delete_privileged_user",
8695 torture_rpc_samr_users_privileges_delete_user);
8700 static bool torture_rpc_samr_many_accounts(struct torture_context *torture,
8701 struct dcerpc_pipe *p2,
8705 struct dcerpc_pipe *p;
8707 struct torture_samr_context *ctx =
8708 talloc_get_type_abort(data, struct torture_samr_context);
8709 struct dcerpc_binding_handle *b;
8711 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8712 if (!NT_STATUS_IS_OK(status)) {
8715 b = p->binding_handle;
8717 ctx->choice = TORTURE_SAMR_MANY_ACCOUNTS;
8718 ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
8719 ctx->num_objects_large_dc);
8721 ret &= test_Connect(b, torture, &ctx->handle);
8723 ret &= test_EnumDomains(p, torture, ctx);
8725 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8730 static bool torture_rpc_samr_many_groups(struct torture_context *torture,
8731 struct dcerpc_pipe *p2,
8735 struct dcerpc_pipe *p;
8737 struct torture_samr_context *ctx =
8738 talloc_get_type_abort(data, struct torture_samr_context);
8739 struct dcerpc_binding_handle *b;
8741 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8742 if (!NT_STATUS_IS_OK(status)) {
8745 b = p->binding_handle;
8747 ctx->choice = TORTURE_SAMR_MANY_GROUPS;
8748 ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
8749 ctx->num_objects_large_dc);
8751 ret &= test_Connect(b, torture, &ctx->handle);
8753 ret &= test_EnumDomains(p, torture, ctx);
8755 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8760 static bool torture_rpc_samr_many_aliases(struct torture_context *torture,
8761 struct dcerpc_pipe *p2,
8765 struct dcerpc_pipe *p;
8767 struct torture_samr_context *ctx =
8768 talloc_get_type_abort(data, struct torture_samr_context);
8769 struct dcerpc_binding_handle *b;
8771 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8772 if (!NT_STATUS_IS_OK(status)) {
8775 b = p->binding_handle;
8777 ctx->choice = TORTURE_SAMR_MANY_ALIASES;
8778 ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
8779 ctx->num_objects_large_dc);
8781 ret &= test_Connect(b, torture, &ctx->handle);
8783 ret &= test_EnumDomains(p, torture, ctx);
8785 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8790 struct torture_suite *torture_rpc_samr_large_dc(TALLOC_CTX *mem_ctx)
8792 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.large-dc");
8793 struct torture_rpc_tcase *tcase;
8794 struct torture_samr_context *ctx;
8796 tcase = torture_suite_add_rpc_iface_tcase(suite, "samr", &ndr_table_samr);
8798 ctx = talloc_zero(suite, struct torture_samr_context);
8799 ctx->num_objects_large_dc = 150;
8801 torture_rpc_tcase_add_test_ex(tcase, "many_aliases",
8802 torture_rpc_samr_many_aliases, ctx);
8803 torture_rpc_tcase_add_test_ex(tcase, "many_groups",
8804 torture_rpc_samr_many_groups, ctx);
8805 torture_rpc_tcase_add_test_ex(tcase, "many_accounts",
8806 torture_rpc_samr_many_accounts, ctx);
8811 static bool torture_rpc_samr_badpwdcount(struct torture_context *torture,
8812 struct dcerpc_pipe *p2,
8813 struct cli_credentials *machine_credentials)
8816 struct dcerpc_pipe *p;
8818 struct torture_samr_context *ctx;
8819 struct dcerpc_binding_handle *b;
8821 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8822 if (!NT_STATUS_IS_OK(status)) {
8825 b = p->binding_handle;
8827 ctx = talloc_zero(torture, struct torture_samr_context);
8829 ctx->choice = TORTURE_SAMR_PASSWORDS_BADPWDCOUNT;
8830 ctx->machine_credentials = machine_credentials;
8832 ret &= test_Connect(b, torture, &ctx->handle);
8834 ret &= test_EnumDomains(p, torture, ctx);
8836 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8841 struct torture_suite *torture_rpc_samr_passwords_badpwdcount(TALLOC_CTX *mem_ctx)
8843 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.passwords.badpwdcount");
8844 struct torture_rpc_tcase *tcase;
8846 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8848 TEST_ACCOUNT_NAME_PWD);
8850 torture_rpc_tcase_add_test_creds(tcase, "badPwdCount",
8851 torture_rpc_samr_badpwdcount);
8856 static bool torture_rpc_samr_lockout(struct torture_context *torture,
8857 struct dcerpc_pipe *p2,
8858 struct cli_credentials *machine_credentials)
8861 struct dcerpc_pipe *p;
8863 struct torture_samr_context *ctx;
8864 struct dcerpc_binding_handle *b;
8866 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8867 if (!NT_STATUS_IS_OK(status)) {
8870 b = p->binding_handle;
8872 ctx = talloc_zero(torture, struct torture_samr_context);
8874 ctx->choice = TORTURE_SAMR_PASSWORDS_LOCKOUT;
8875 ctx->machine_credentials = machine_credentials;
8877 ret &= test_Connect(b, torture, &ctx->handle);
8879 ret &= test_EnumDomains(p, torture, ctx);
8881 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8886 struct torture_suite *torture_rpc_samr_passwords_lockout(TALLOC_CTX *mem_ctx)
8888 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.passwords.lockout");
8889 struct torture_rpc_tcase *tcase;
8891 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8893 TEST_ACCOUNT_NAME_PWD);
8895 torture_rpc_tcase_add_test_creds(tcase, "lockout",
8896 torture_rpc_samr_lockout);
8901 struct torture_suite *torture_rpc_samr_passwords_validate(TALLOC_CTX *mem_ctx)
8903 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.passwords.validate");
8904 struct torture_rpc_tcase *tcase;
8906 tcase = torture_suite_add_rpc_iface_tcase(suite, "samr",
8908 torture_rpc_tcase_add_test(tcase, "validate",
8909 test_samr_ValidatePassword);