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;
1169 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
1170 gnutls_hash_hd_t hash_hnd;
1171 uint8_t confounder[16];
1173 struct dcerpc_binding_handle *b = p->binding_handle;
1174 struct samr_GetUserPwInfo pwp;
1175 struct samr_PwInfo info;
1176 int policy_min_pw_len = 0;
1177 const char *comment = NULL;
1178 uint8_t lm_hash[16], nt_hash[16];
1180 pwp.in.user_handle = handle;
1181 pwp.out.info = &info;
1183 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &pwp),
1184 "GetUserPwInfo failed");
1185 if (NT_STATUS_IS_OK(pwp.out.result)) {
1186 policy_min_pw_len = pwp.out.info->min_password_length;
1188 newpass = samr_rand_pass_silent(tctx, policy_min_pw_len);
1191 s2.in.user_handle = handle;
1193 s2.in.level = level;
1195 s.in.user_handle = handle;
1200 if (fields_present & SAMR_FIELD_COMMENT) {
1201 comment = talloc_asprintf(tctx, "comment: %ld\n", (long int) time(NULL));
1208 E_md4hash(newpass, nt_hash);
1209 E_deshash(newpass, lm_hash);
1211 u.info18.nt_pwd_active = true;
1212 u.info18.lm_pwd_active = true;
1213 u.info18.password_expired = password_expired;
1215 memcpy(u.info18.lm_pwd.hash, lm_hash, 16);
1216 memcpy(u.info18.nt_pwd.hash, nt_hash, 16);
1220 E_md4hash(newpass, nt_hash);
1221 E_deshash(newpass, lm_hash);
1223 u.info21.fields_present = fields_present;
1224 u.info21.password_expired = password_expired;
1225 u.info21.comment.string = comment;
1227 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1228 u.info21.lm_owf_password.length = 16;
1229 u.info21.lm_owf_password.size = 16;
1230 u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
1231 u.info21.lm_password_set = true;
1234 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1235 u.info21.nt_owf_password.length = 16;
1236 u.info21.nt_owf_password.size = 16;
1237 u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
1238 u.info21.nt_password_set = true;
1243 u.info23.info.fields_present = fields_present;
1244 u.info23.info.password_expired = password_expired;
1245 u.info23.info.comment.string = comment;
1247 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
1251 u.info24.password_expired = password_expired;
1253 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
1257 u.info25.info.fields_present = fields_present;
1258 u.info25.info.password_expired = password_expired;
1259 u.info25.info.comment.string = comment;
1261 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
1265 u.info26.password_expired = password_expired;
1267 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
1272 status = dcerpc_fetch_session_key(p, &session_key);
1273 if (!NT_STATUS_IS_OK(status)) {
1274 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u - no session key - %s\n",
1275 s.in.level, nt_errstr(status));
1279 generate_random_buffer((uint8_t *)confounder, 16);
1281 gnutls_hash_init(&hash_hnd, GNUTLS_DIG_MD5);
1282 gnutls_hash(hash_hnd, confounder, 16);
1283 gnutls_hash(hash_hnd, session_key.data, session_key.length);
1284 gnutls_hash_deinit(hash_hnd, confounded_session_key.data);
1290 in = data_blob_const(u.info18.nt_pwd.hash, 16);
1291 out = data_blob_talloc_zero(tctx, 16);
1292 sess_crypt_blob(&out, &in, &session_key, true);
1293 memcpy(u.info18.nt_pwd.hash, out.data, out.length);
1297 in = data_blob_const(u.info18.lm_pwd.hash, 16);
1298 out = data_blob_talloc_zero(tctx, 16);
1299 sess_crypt_blob(&out, &in, &session_key, true);
1300 memcpy(u.info18.lm_pwd.hash, out.data, out.length);
1305 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1307 in = data_blob_const(u.info21.lm_owf_password.array,
1308 u.info21.lm_owf_password.length);
1309 out = data_blob_talloc_zero(tctx, 16);
1310 sess_crypt_blob(&out, &in, &session_key, true);
1311 u.info21.lm_owf_password.array = (uint16_t *)out.data;
1313 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1315 in = data_blob_const(u.info21.nt_owf_password.array,
1316 u.info21.nt_owf_password.length);
1317 out = data_blob_talloc_zero(tctx, 16);
1318 sess_crypt_blob(&out, &in, &session_key, true);
1319 u.info21.nt_owf_password.array = (uint16_t *)out.data;
1323 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
1326 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
1329 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
1330 memcpy(&u.info25.password.data[516], confounder, 16);
1333 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
1334 memcpy(&u.info26.password.data[516], confounder, 16);
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];
2036 struct samr_GetDomPwInfo dom_pw_info;
2037 struct samr_PwInfo info;
2038 int policy_min_pw_len = 0;
2040 struct lsa_String domain_name;
2042 domain_name.string = "";
2043 dom_pw_info.in.domain_name = &domain_name;
2044 dom_pw_info.out.info = &info;
2046 torture_comment(tctx, "Testing OemChangePasswordUser2\n");
2048 torture_assert(tctx, *password != NULL,
2049 "Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?");
2051 oldpass = *password;
2053 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDomPwInfo_r(b, tctx, &dom_pw_info),
2054 "GetDomPwInfo failed");
2055 if (NT_STATUS_IS_OK(dom_pw_info.out.result)) {
2056 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
2059 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2061 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2062 account.string = acct_name;
2064 E_deshash(oldpass, old_lm_hash);
2065 E_deshash(newpass, new_lm_hash);
2067 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
2068 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2069 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
2071 r.in.server = &server;
2072 r.in.account = &account;
2073 r.in.password = &lm_pass;
2074 r.in.hash = &lm_verifier;
2076 /* Break the verification */
2077 lm_verifier.hash[0]++;
2079 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
2080 "OemChangePasswordUser2 failed");
2081 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2082 __location__, __FUNCTION__,
2083 oldpass, newpass, nt_errstr(r.out.result));
2085 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)
2086 && !NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD)) {
2087 torture_result(tctx, TORTURE_FAIL, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
2088 nt_errstr(r.out.result));
2092 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
2093 /* Break the old password */
2095 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2096 /* unbreak it for the next operation */
2098 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
2100 r.in.server = &server;
2101 r.in.account = &account;
2102 r.in.password = &lm_pass;
2103 r.in.hash = &lm_verifier;
2105 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
2106 "OemChangePasswordUser2 failed");
2107 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2108 __location__, __FUNCTION__,
2109 oldpass, newpass, nt_errstr(r.out.result));
2111 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)
2112 && !NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD)) {
2113 torture_result(tctx, TORTURE_FAIL, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
2114 nt_errstr(r.out.result));
2118 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
2119 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2121 r.in.server = &server;
2122 r.in.account = &account;
2123 r.in.password = &lm_pass;
2126 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
2127 "OemChangePasswordUser2 failed");
2128 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2129 __location__, __FUNCTION__,
2130 oldpass, newpass, nt_errstr(r.out.result));
2132 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)
2133 && !NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
2134 torture_result(tctx, TORTURE_FAIL, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
2135 nt_errstr(r.out.result));
2139 /* This shouldn't be a valid name */
2140 account_bad.string = TEST_ACCOUNT_NAME "XX";
2141 r.in.account = &account_bad;
2143 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
2144 "OemChangePasswordUser2 failed");
2145 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2146 __location__, __FUNCTION__,
2147 oldpass, newpass, nt_errstr(r.out.result));
2149 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
2150 torture_result(tctx, TORTURE_FAIL, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
2151 nt_errstr(r.out.result));
2155 /* This shouldn't be a valid name */
2156 account_bad.string = TEST_ACCOUNT_NAME "XX";
2157 r.in.account = &account_bad;
2158 r.in.password = &lm_pass;
2159 r.in.hash = &lm_verifier;
2161 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
2162 "OemChangePasswordUser2 failed");
2163 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2164 __location__, __FUNCTION__,
2165 oldpass, newpass, nt_errstr(r.out.result));
2167 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD)) {
2168 torture_result(tctx, TORTURE_FAIL, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
2169 nt_errstr(r.out.result));
2173 /* This shouldn't be a valid name */
2174 account_bad.string = TEST_ACCOUNT_NAME "XX";
2175 r.in.account = &account_bad;
2176 r.in.password = NULL;
2177 r.in.hash = &lm_verifier;
2179 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
2180 "OemChangePasswordUser2 failed");
2181 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2182 __location__, __FUNCTION__,
2183 oldpass, newpass, nt_errstr(r.out.result));
2185 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
2186 torture_result(tctx, TORTURE_FAIL, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
2187 nt_errstr(r.out.result));
2191 E_deshash(oldpass, old_lm_hash);
2192 E_deshash(newpass, new_lm_hash);
2194 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
2195 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2196 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
2198 r.in.server = &server;
2199 r.in.account = &account;
2200 r.in.password = &lm_pass;
2201 r.in.hash = &lm_verifier;
2203 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
2204 "OemChangePasswordUser2 failed");
2205 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2206 __location__, __FUNCTION__,
2207 oldpass, newpass, nt_errstr(r.out.result));
2209 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
2210 torture_comment(tctx, "OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(r.out.result));
2211 } else if (!NT_STATUS_IS_OK(r.out.result)) {
2212 torture_result(tctx, TORTURE_FAIL, "OemChangePasswordUser2 failed - %s\n", nt_errstr(r.out.result));
2215 *password = newpass;
2222 static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
2223 const char *acct_name,
2225 char *newpass, bool allow_password_restriction)
2227 struct samr_ChangePasswordUser2 r;
2229 struct lsa_String server, account;
2230 struct samr_CryptPassword nt_pass, lm_pass;
2231 struct samr_Password nt_verifier, lm_verifier;
2233 struct dcerpc_binding_handle *b = p->binding_handle;
2234 uint8_t old_nt_hash[16], new_nt_hash[16];
2235 uint8_t old_lm_hash[16], new_lm_hash[16];
2237 struct samr_GetDomPwInfo dom_pw_info;
2238 struct samr_PwInfo info;
2240 struct lsa_String domain_name;
2242 domain_name.string = "";
2243 dom_pw_info.in.domain_name = &domain_name;
2244 dom_pw_info.out.info = &info;
2246 torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name);
2248 torture_assert(tctx, *password != NULL,
2249 "Failing ChangePasswordUser2 as old password was NULL. Previous test failed?");
2250 oldpass = *password;
2253 int policy_min_pw_len = 0;
2254 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDomPwInfo_r(b, tctx, &dom_pw_info),
2255 "GetDomPwInfo failed");
2256 if (NT_STATUS_IS_OK(dom_pw_info.out.result)) {
2257 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
2260 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2263 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2264 init_lsa_String(&account, acct_name);
2266 E_md4hash(oldpass, old_nt_hash);
2267 E_md4hash(newpass, new_nt_hash);
2269 E_deshash(oldpass, old_lm_hash);
2270 E_deshash(newpass, new_lm_hash);
2272 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
2273 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2274 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2276 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2277 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2278 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2280 r.in.server = &server;
2281 r.in.account = &account;
2282 r.in.nt_password = &nt_pass;
2283 r.in.nt_verifier = &nt_verifier;
2285 r.in.lm_password = &lm_pass;
2286 r.in.lm_verifier = &lm_verifier;
2288 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser2_r(b, tctx, &r),
2289 "ChangePasswordUser2 failed");
2290 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2291 __location__, __FUNCTION__,
2292 oldpass, newpass, nt_errstr(r.out.result));
2294 if (allow_password_restriction && NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
2295 torture_comment(tctx, "ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(r.out.result));
2296 } else if (!NT_STATUS_IS_OK(r.out.result)) {
2297 torture_result(tctx, TORTURE_FAIL, "ChangePasswordUser2 failed - %s\n", nt_errstr(r.out.result));
2300 *password = newpass;
2307 static bool test_ChangePasswordUser2_ntstatus(struct dcerpc_pipe *p, struct torture_context *tctx,
2308 const char *acct_name,
2309 const char *password, NTSTATUS status)
2311 struct samr_ChangePasswordUser2 r;
2312 struct lsa_String server, account;
2313 struct samr_CryptPassword nt_pass, lm_pass;
2314 struct samr_Password nt_verifier, lm_verifier;
2315 const char *oldpass;
2316 struct dcerpc_binding_handle *b = p->binding_handle;
2317 uint8_t old_nt_hash[16], new_nt_hash[16];
2318 uint8_t old_lm_hash[16], new_lm_hash[16];
2320 struct samr_GetDomPwInfo dom_pw_info;
2321 struct samr_PwInfo info;
2323 struct lsa_String domain_name;
2325 int policy_min_pw_len = 0;
2327 domain_name.string = "";
2328 dom_pw_info.in.domain_name = &domain_name;
2329 dom_pw_info.out.info = &info;
2331 torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name);
2335 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDomPwInfo_r(b, tctx, &dom_pw_info),
2336 "GetDomPwInfo failed");
2337 if (NT_STATUS_IS_OK(dom_pw_info.out.result)) {
2338 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
2341 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2343 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2344 init_lsa_String(&account, acct_name);
2346 E_md4hash(oldpass, old_nt_hash);
2347 E_md4hash(newpass, new_nt_hash);
2349 E_deshash(oldpass, old_lm_hash);
2350 E_deshash(newpass, new_lm_hash);
2352 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
2353 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2354 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2356 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2357 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2358 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2360 r.in.server = &server;
2361 r.in.account = &account;
2362 r.in.nt_password = &nt_pass;
2363 r.in.nt_verifier = &nt_verifier;
2365 r.in.lm_password = &lm_pass;
2366 r.in.lm_verifier = &lm_verifier;
2368 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser2_r(b, tctx, &r),
2369 "ChangePasswordUser2 failed");
2370 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2371 __location__, __FUNCTION__,
2372 oldpass, newpass, nt_errstr(r.out.result));
2374 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
2375 torture_comment(tctx, "ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(r.out.result));
2377 torture_assert_ntstatus_equal(tctx, r.out.result, status, "ChangePasswordUser2 returned unexpected value");
2384 bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tctx,
2385 const char *account_string,
2386 int policy_min_pw_len,
2388 const char *newpass,
2389 NTTIME last_password_change,
2390 bool handle_reject_reason)
2392 struct samr_ChangePasswordUser3 r;
2394 struct lsa_String server, account, account_bad;
2395 struct samr_CryptPassword nt_pass, lm_pass;
2396 struct samr_Password nt_verifier, lm_verifier;
2398 struct dcerpc_binding_handle *b = p->binding_handle;
2399 uint8_t old_nt_hash[16], new_nt_hash[16];
2400 uint8_t old_lm_hash[16], new_lm_hash[16];
2402 struct samr_DomInfo1 *dominfo = NULL;
2403 struct userPwdChangeFailureInformation *reject = NULL;
2405 torture_comment(tctx, "Testing ChangePasswordUser3\n");
2407 if (newpass == NULL) {
2409 if (policy_min_pw_len == 0) {
2410 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2412 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len);
2414 } while (check_password_quality(newpass) == false);
2416 torture_comment(tctx, "Using password '%s'\n", newpass);
2419 torture_assert(tctx, *password != NULL,
2420 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2422 oldpass = *password;
2423 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2424 init_lsa_String(&account, account_string);
2426 E_md4hash(oldpass, old_nt_hash);
2427 E_md4hash(newpass, new_nt_hash);
2429 E_deshash(oldpass, old_lm_hash);
2430 E_deshash(newpass, new_lm_hash);
2432 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2433 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2434 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2436 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2437 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2438 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2440 /* Break the verification */
2441 nt_verifier.hash[0]++;
2443 r.in.server = &server;
2444 r.in.account = &account;
2445 r.in.nt_password = &nt_pass;
2446 r.in.nt_verifier = &nt_verifier;
2448 r.in.lm_password = &lm_pass;
2449 r.in.lm_verifier = &lm_verifier;
2450 r.in.password3 = NULL;
2451 r.out.dominfo = &dominfo;
2452 r.out.reject = &reject;
2454 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2455 "ChangePasswordUser3 failed");
2456 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2457 __location__, __FUNCTION__,
2458 oldpass, newpass, nt_errstr(r.out.result));
2459 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION) &&
2460 (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD))) {
2461 torture_result(tctx, TORTURE_FAIL, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
2462 nt_errstr(r.out.result));
2466 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2467 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2468 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2470 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2471 /* Break the NT hash */
2473 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2474 /* Unbreak it again */
2476 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2478 r.in.server = &server;
2479 r.in.account = &account;
2480 r.in.nt_password = &nt_pass;
2481 r.in.nt_verifier = &nt_verifier;
2483 r.in.lm_password = &lm_pass;
2484 r.in.lm_verifier = &lm_verifier;
2485 r.in.password3 = NULL;
2486 r.out.dominfo = &dominfo;
2487 r.out.reject = &reject;
2489 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2490 "ChangePasswordUser3 failed");
2491 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2492 __location__, __FUNCTION__,
2493 oldpass, newpass, nt_errstr(r.out.result));
2494 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION) &&
2495 (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD))) {
2496 torture_result(tctx, TORTURE_FAIL, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
2497 nt_errstr(r.out.result));
2501 /* This shouldn't be a valid name */
2502 init_lsa_String(&account_bad, talloc_asprintf(tctx, "%sXX", account_string));
2504 r.in.account = &account_bad;
2505 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2506 "ChangePasswordUser3 failed");
2507 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2508 __location__, __FUNCTION__,
2509 oldpass, newpass, nt_errstr(r.out.result));
2510 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD)) {
2511 torture_result(tctx, TORTURE_FAIL, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
2512 nt_errstr(r.out.result));
2516 E_md4hash(oldpass, old_nt_hash);
2517 E_md4hash(newpass, new_nt_hash);
2519 E_deshash(oldpass, old_lm_hash);
2520 E_deshash(newpass, new_lm_hash);
2522 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2523 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2524 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2526 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2527 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2528 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2530 r.in.server = &server;
2531 r.in.account = &account;
2532 r.in.nt_password = &nt_pass;
2533 r.in.nt_verifier = &nt_verifier;
2535 r.in.lm_password = &lm_pass;
2536 r.in.lm_verifier = &lm_verifier;
2537 r.in.password3 = NULL;
2538 r.out.dominfo = &dominfo;
2539 r.out.reject = &reject;
2541 unix_to_nt_time(&t, time(NULL));
2543 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2544 "ChangePasswordUser3 failed");
2545 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2546 __location__, __FUNCTION__,
2547 oldpass, newpass, nt_errstr(r.out.result));
2549 torture_comment(tctx, "(%s): dominfo[%s], reject[%s], handle_reject_reason[%s], "
2550 "last_password_change[%s], dominfo->min_password_age[%lld]\n",
2552 (dominfo == NULL)? "NULL" : "present",
2553 reject ? "true" : "false",
2554 handle_reject_reason ? "true" : "false",
2555 null_nttime(last_password_change) ? "null" : "not null",
2556 dominfo ? (long long)dominfo->min_password_age : (long long)0);
2558 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)
2561 && handle_reject_reason
2562 && (!null_nttime(last_password_change) || !dominfo->min_password_age)) {
2563 if (dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
2565 if (reject && (reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR)) {
2566 torture_result(tctx, TORTURE_FAIL, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2567 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2572 /* We tested the order of precendence which is as follows:
2581 if ((dominfo->min_password_age < 0) && !null_nttime(last_password_change) &&
2582 (last_password_change - dominfo->min_password_age > t)) {
2584 if (reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2585 torture_result(tctx, TORTURE_FAIL, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2586 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2590 } else if ((dominfo->min_password_length > 0) &&
2591 (strlen(newpass) < dominfo->min_password_length)) {
2593 if (reject->extendedFailureReason != SAM_PWD_CHANGE_PASSWORD_TOO_SHORT) {
2594 torture_result(tctx, TORTURE_FAIL, "expected SAM_PWD_CHANGE_PASSWORD_TOO_SHORT (%d), got %d\n",
2595 SAM_PWD_CHANGE_PASSWORD_TOO_SHORT, reject->extendedFailureReason);
2599 } else if ((dominfo->password_history_length > 0) &&
2600 strequal(oldpass, newpass)) {
2602 if (reject->extendedFailureReason != SAM_PWD_CHANGE_PWD_IN_HISTORY) {
2603 torture_result(tctx, TORTURE_FAIL, "expected SAM_PWD_CHANGE_PWD_IN_HISTORY (%d), got %d\n",
2604 SAM_PWD_CHANGE_PWD_IN_HISTORY, reject->extendedFailureReason);
2607 } else if (dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
2609 if (reject->extendedFailureReason != SAM_PWD_CHANGE_NOT_COMPLEX) {
2610 torture_result(tctx, TORTURE_FAIL, "expected SAM_PWD_CHANGE_NOT_COMPLEX (%d), got %d\n",
2611 SAM_PWD_CHANGE_NOT_COMPLEX, reject->extendedFailureReason);
2617 if (reject->extendedFailureReason == SAM_PWD_CHANGE_PASSWORD_TOO_SHORT) {
2618 /* retry with adjusted size */
2619 return test_ChangePasswordUser3(p, tctx, account_string,
2620 dominfo->min_password_length,
2621 password, NULL, 0, false);
2625 } else if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
2626 if (reject && reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2627 torture_result(tctx, TORTURE_FAIL, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2628 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2631 /* Perhaps the server has a 'min password age' set? */
2634 torture_assert_ntstatus_ok(tctx, r.out.result, "ChangePasswordUser3");
2636 *password = talloc_strdup(tctx, newpass);
2642 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_context *tctx,
2643 const char *account_string,
2644 struct policy_handle *handle,
2648 struct samr_ChangePasswordUser3 r;
2649 struct samr_SetUserInfo s;
2650 union samr_UserInfo u;
2651 DATA_BLOB session_key;
2652 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
2653 uint8_t confounder[16];
2654 gnutls_hash_hd_t hash_hnd;
2657 struct lsa_String server, account;
2658 struct samr_CryptPassword nt_pass;
2659 struct samr_Password nt_verifier;
2660 DATA_BLOB new_random_pass;
2663 struct dcerpc_binding_handle *b = p->binding_handle;
2664 uint8_t old_nt_hash[16], new_nt_hash[16];
2666 struct samr_DomInfo1 *dominfo = NULL;
2667 struct userPwdChangeFailureInformation *reject = NULL;
2669 new_random_pass = samr_very_rand_pass(tctx, 128);
2671 torture_assert(tctx, *password != NULL,
2672 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2674 oldpass = *password;
2675 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2676 init_lsa_String(&account, account_string);
2678 s.in.user_handle = handle;
2684 u.info25.info.fields_present = SAMR_FIELD_NT_PASSWORD_PRESENT;
2686 set_pw_in_buffer(u.info25.password.data, &new_random_pass);
2688 status = dcerpc_fetch_session_key(p, &session_key);
2689 if (!NT_STATUS_IS_OK(status)) {
2690 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u - no session key - %s\n",
2691 s.in.level, nt_errstr(status));
2695 generate_random_buffer((uint8_t *)confounder, 16);
2697 gnutls_hash_init(&hash_hnd, GNUTLS_DIG_MD5);
2698 gnutls_hash(hash_hnd, confounder, 16);
2699 gnutls_hash(hash_hnd, session_key.data, session_key.length);
2700 gnutls_hash_deinit(hash_hnd, confounded_session_key.data);
2702 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
2703 memcpy(&u.info25.password.data[516], confounder, 16);
2705 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
2707 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
2708 "SetUserInfo failed");
2709 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2710 __location__, __FUNCTION__,
2711 oldpass, "RANDOM", nt_errstr(s.out.result));
2712 if (!NT_STATUS_IS_OK(s.out.result)) {
2713 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u failed - %s\n",
2714 s.in.level, nt_errstr(s.out.result));
2718 torture_comment(tctx, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
2720 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2722 new_random_pass = samr_very_rand_pass(tctx, 128);
2724 mdfour(new_nt_hash, new_random_pass.data, new_random_pass.length);
2726 set_pw_in_buffer(nt_pass.data, &new_random_pass);
2727 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2728 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2730 r.in.server = &server;
2731 r.in.account = &account;
2732 r.in.nt_password = &nt_pass;
2733 r.in.nt_verifier = &nt_verifier;
2735 r.in.lm_password = NULL;
2736 r.in.lm_verifier = NULL;
2737 r.in.password3 = NULL;
2738 r.out.dominfo = &dominfo;
2739 r.out.reject = &reject;
2741 unix_to_nt_time(&t, time(NULL));
2743 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2744 "ChangePasswordUser3 failed");
2745 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2746 __location__, __FUNCTION__,
2747 oldpass, "RANDOM", nt_errstr(r.out.result));
2749 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
2750 if (reject && reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2751 torture_result(tctx, TORTURE_FAIL, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2752 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2755 /* Perhaps the server has a 'min password age' set? */
2757 } else if (!NT_STATUS_IS_OK(r.out.result)) {
2758 torture_result(tctx, TORTURE_FAIL, "ChangePasswordUser3 failed - %s\n", nt_errstr(r.out.result));
2762 newpass = samr_rand_pass(tctx, 128);
2764 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2766 E_md4hash(newpass, new_nt_hash);
2768 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2769 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2770 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2772 r.in.server = &server;
2773 r.in.account = &account;
2774 r.in.nt_password = &nt_pass;
2775 r.in.nt_verifier = &nt_verifier;
2777 r.in.lm_password = NULL;
2778 r.in.lm_verifier = NULL;
2779 r.in.password3 = NULL;
2780 r.out.dominfo = &dominfo;
2781 r.out.reject = &reject;
2783 unix_to_nt_time(&t, time(NULL));
2785 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2786 "ChangePasswordUser3 failed");
2787 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2788 __location__, __FUNCTION__,
2789 oldpass, newpass, nt_errstr(r.out.result));
2791 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
2792 if (reject && reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2793 torture_result(tctx, TORTURE_FAIL, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2794 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2797 /* Perhaps the server has a 'min password age' set? */
2800 torture_assert_ntstatus_ok(tctx, r.out.result, "ChangePasswordUser3 (on second random password)");
2801 *password = talloc_strdup(tctx, newpass);
2808 static bool test_GetMembersInAlias(struct dcerpc_binding_handle *b,
2809 struct torture_context *tctx,
2810 struct policy_handle *alias_handle)
2812 struct samr_GetMembersInAlias r;
2813 struct lsa_SidArray sids;
2815 torture_comment(tctx, "Testing GetMembersInAlias\n");
2817 r.in.alias_handle = alias_handle;
2820 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetMembersInAlias_r(b, tctx, &r),
2821 "GetMembersInAlias failed");
2822 torture_assert_ntstatus_ok(tctx, r.out.result, "GetMembersInAlias failed");
2827 static bool test_AddMemberToAlias(struct dcerpc_binding_handle *b,
2828 struct torture_context *tctx,
2829 struct policy_handle *alias_handle,
2830 const struct dom_sid *domain_sid)
2832 struct samr_AddAliasMember r;
2833 struct samr_DeleteAliasMember d;
2834 struct dom_sid *sid;
2836 sid = dom_sid_add_rid(tctx, domain_sid, 512);
2838 torture_comment(tctx, "Testing AddAliasMember\n");
2839 r.in.alias_handle = alias_handle;
2842 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddAliasMember_r(b, tctx, &r),
2843 "AddAliasMember failed");
2844 torture_assert_ntstatus_ok(tctx, r.out.result, "AddAliasMember failed");
2846 d.in.alias_handle = alias_handle;
2849 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteAliasMember_r(b, tctx, &d),
2850 "DeleteAliasMember failed");
2851 torture_assert_ntstatus_ok(tctx, d.out.result, "DelAliasMember failed");
2856 static bool test_AddMultipleMembersToAlias(struct dcerpc_binding_handle *b,
2857 struct torture_context *tctx,
2858 struct policy_handle *alias_handle)
2860 struct samr_AddMultipleMembersToAlias a;
2861 struct samr_RemoveMultipleMembersFromAlias r;
2862 struct lsa_SidArray sids;
2864 torture_comment(tctx, "Testing AddMultipleMembersToAlias\n");
2865 a.in.alias_handle = alias_handle;
2869 sids.sids = talloc_array(tctx, struct lsa_SidPtr, 3);
2871 sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2872 sids.sids[1].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-2");
2873 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-3");
2875 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddMultipleMembersToAlias_r(b, tctx, &a),
2876 "AddMultipleMembersToAlias failed");
2877 torture_assert_ntstatus_ok(tctx, a.out.result, "AddMultipleMembersToAlias");
2880 torture_comment(tctx, "Testing RemoveMultipleMembersFromAlias\n");
2881 r.in.alias_handle = alias_handle;
2884 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RemoveMultipleMembersFromAlias_r(b, tctx, &r),
2885 "RemoveMultipleMembersFromAlias failed");
2886 torture_assert_ntstatus_ok(tctx, r.out.result, "RemoveMultipleMembersFromAlias failed");
2888 /* strange! removing twice doesn't give any error */
2889 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RemoveMultipleMembersFromAlias_r(b, tctx, &r),
2890 "RemoveMultipleMembersFromAlias failed");
2891 torture_assert_ntstatus_ok(tctx, r.out.result, "RemoveMultipleMembersFromAlias failed");
2893 /* but removing an alias that isn't there does */
2894 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-4");
2896 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RemoveMultipleMembersFromAlias_r(b, tctx, &r),
2897 "RemoveMultipleMembersFromAlias failed");
2898 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND, "RemoveMultipleMembersFromAlias");
2903 static bool test_GetAliasMembership(struct dcerpc_binding_handle *b,
2904 struct torture_context *tctx,
2905 struct policy_handle *domain_handle)
2907 struct samr_GetAliasMembership r;
2908 struct lsa_SidArray sids;
2909 struct samr_Ids rids;
2911 torture_comment(tctx, "Testing GetAliasMembership\n");
2913 r.in.domain_handle = domain_handle;
2918 sids.sids = talloc_zero_array(tctx, struct lsa_SidPtr, sids.num_sids);
2920 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetAliasMembership_r(b, tctx, &r),
2921 "GetAliasMembership failed");
2922 torture_assert_ntstatus_ok(tctx, r.out.result,
2923 "samr_GetAliasMembership failed");
2925 torture_assert_int_equal(tctx, sids.num_sids, rids.count,
2926 "protocol misbehaviour");
2929 sids.sids = talloc_zero_array(tctx, struct lsa_SidPtr, sids.num_sids);
2930 sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2932 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetAliasMembership_r(b, tctx, &r),
2933 "samr_GetAliasMembership failed");
2934 torture_assert_ntstatus_ok(tctx, r.out.result,
2935 "samr_GetAliasMembership failed");
2938 /* only true for w2k8 it seems
2939 * win7, xp, w2k3 will return a 0 length array pointer */
2941 if (rids.ids && (rids.count == 0)) {
2942 torture_fail(tctx, "samr_GetAliasMembership returned 0 count and a rids array");
2945 if (!rids.ids && rids.count) {
2946 torture_fail(tctx, "samr_GetAliasMembership returned non-0 count but no rids");
2952 static bool test_TestPrivateFunctionsUser(struct dcerpc_binding_handle *b,
2953 struct torture_context *tctx,
2954 struct policy_handle *user_handle)
2956 struct samr_TestPrivateFunctionsUser r;
2958 torture_comment(tctx, "Testing TestPrivateFunctionsUser\n");
2960 r.in.user_handle = user_handle;
2962 torture_assert_ntstatus_ok(tctx, dcerpc_samr_TestPrivateFunctionsUser_r(b, tctx, &r),
2963 "TestPrivateFunctionsUser failed");
2964 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsUser");
2969 static bool test_QueryUserInfo_pwdlastset(struct dcerpc_binding_handle *b,
2970 struct torture_context *tctx,
2971 struct policy_handle *handle,
2976 uint16_t levels[] = { /* 3, */ 5, 21 };
2978 /* NTTIME pwdlastset3 = 0; */
2979 NTTIME pwdlastset5 = 0;
2980 NTTIME pwdlastset21 = 0;
2982 torture_comment(tctx, "Testing QueryUserInfo%s level 5 and 21 call ",
2983 use_info2 ? "2":"");
2985 for (i=0; i<ARRAY_SIZE(levels); i++) {
2987 struct samr_QueryUserInfo r;
2988 struct samr_QueryUserInfo2 r2;
2989 union samr_UserInfo *info;
2992 r2.in.user_handle = handle;
2993 r2.in.level = levels[i];
2994 r2.out.info = &info;
2995 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo2_r(b, tctx, &r2),
2996 "QueryUserInfo2 failed");
2997 status = r2.out.result;
3000 r.in.user_handle = handle;
3001 r.in.level = levels[i];
3003 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
3004 "QueryUserInfo failed");
3005 status = r.out.result;
3008 if (!NT_STATUS_IS_OK(status) &&
3009 !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
3010 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo%s level %u failed - %s\n",
3011 use_info2 ? "2":"", levels[i], nt_errstr(status));
3015 switch (levels[i]) {
3017 /* pwdlastset3 = info->info3.last_password_change; */
3020 pwdlastset5 = info->info5.last_password_change;
3023 pwdlastset21 = info->info21.last_password_change;
3029 /* torture_assert_int_equal(tctx, pwdlastset3, pwdlastset5,
3030 "pwdlastset mixup"); */
3031 torture_assert_int_equal(tctx, pwdlastset5, pwdlastset21,
3032 "pwdlastset mixup");
3034 *pwdlastset = pwdlastset21;
3036 torture_comment(tctx, "(pwdlastset: %llu)\n",
3037 (unsigned long long) *pwdlastset);
3042 static bool test_SamLogon(struct torture_context *tctx,
3043 struct dcerpc_pipe *p,
3044 struct cli_credentials *machine_credentials,
3045 struct cli_credentials *test_credentials,
3046 NTSTATUS expected_result,
3050 struct netr_LogonSamLogonEx r;
3051 union netr_LogonLevel logon;
3052 union netr_Validation validation;
3053 uint8_t authoritative;
3054 struct netr_IdentityInfo identity;
3055 struct netr_NetworkInfo ninfo;
3056 struct netr_PasswordInfo pinfo;
3057 DATA_BLOB names_blob, chal, lm_resp, nt_resp;
3058 int flags = CLI_CRED_NTLM_AUTH;
3059 uint32_t samlogon_flags = 0;
3060 struct netlogon_creds_CredentialState *creds;
3061 struct netr_Authenticator a;
3062 struct dcerpc_binding_handle *b = p->binding_handle;
3064 torture_assert(tctx, (creds = cli_credentials_get_netlogon_creds(machine_credentials)), "");
3066 if (lpcfg_client_lanman_auth(tctx->lp_ctx)) {
3067 flags |= CLI_CRED_LANMAN_AUTH;
3070 if (lpcfg_client_ntlmv2_auth(tctx->lp_ctx)) {
3071 flags |= CLI_CRED_NTLMv2_AUTH;
3074 cli_credentials_get_ntlm_username_domain(test_credentials, tctx,
3075 &identity.account_name.string,
3076 &identity.domain_name.string);
3078 identity.parameter_control =
3079 MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT |
3080 MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;
3081 identity.logon_id = 0;
3082 identity.workstation.string = cli_credentials_get_workstation(test_credentials);
3085 netlogon_creds_client_authenticator(creds, &a);
3087 if (!E_deshash(cli_credentials_get_password(test_credentials), pinfo.lmpassword.hash)) {
3088 ZERO_STRUCT(pinfo.lmpassword.hash);
3090 E_md4hash(cli_credentials_get_password(test_credentials), pinfo.ntpassword.hash);
3092 if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
3093 netlogon_creds_aes_encrypt(creds, pinfo.lmpassword.hash, 16);
3094 netlogon_creds_aes_encrypt(creds, pinfo.ntpassword.hash, 16);
3095 } else if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
3096 netlogon_creds_arcfour_crypt(creds, pinfo.lmpassword.hash, 16);
3097 netlogon_creds_arcfour_crypt(creds, pinfo.ntpassword.hash, 16);
3099 netlogon_creds_des_encrypt(creds, &pinfo.lmpassword);
3100 netlogon_creds_des_encrypt(creds, &pinfo.ntpassword);
3103 pinfo.identity_info = identity;
3104 logon.password = &pinfo;
3106 r.in.logon_level = NetlogonInteractiveInformation;
3108 generate_random_buffer(ninfo.challenge,
3109 sizeof(ninfo.challenge));
3110 chal = data_blob_const(ninfo.challenge,
3111 sizeof(ninfo.challenge));
3113 names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(test_credentials),
3114 cli_credentials_get_domain(test_credentials));
3116 status = cli_credentials_get_ntlm_response(test_credentials, tctx,
3119 NULL, /* server_timestamp */
3123 torture_assert_ntstatus_ok(tctx, status, "cli_credentials_get_ntlm_response failed");
3125 ninfo.lm.data = lm_resp.data;
3126 ninfo.lm.length = lm_resp.length;
3128 ninfo.nt.data = nt_resp.data;
3129 ninfo.nt.length = nt_resp.length;
3131 ninfo.identity_info = identity;
3132 logon.network = &ninfo;
3134 r.in.logon_level = NetlogonNetworkInformation;
3137 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3138 r.in.computer_name = cli_credentials_get_workstation(test_credentials);
3139 r.in.logon = &logon;
3140 r.in.flags = &samlogon_flags;
3141 r.out.flags = &samlogon_flags;
3142 r.out.validation = &validation;
3143 r.out.authoritative = &authoritative;
3145 torture_comment(tctx, "Testing LogonSamLogon with name %s\n", identity.account_name.string);
3147 r.in.validation_level = 6;
3149 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogonEx_r(b, tctx, &r),
3150 "netr_LogonSamLogonEx failed");
3151 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_INFO_CLASS)) {
3152 r.in.validation_level = 3;
3153 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogonEx_r(b, tctx, &r),
3154 "netr_LogonSamLogonEx failed");
3156 if (!NT_STATUS_IS_OK(r.out.result)) {
3157 torture_assert_ntstatus_equal(tctx, r.out.result, expected_result, "LogonSamLogonEx failed");
3160 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogonEx failed");
3166 static bool test_SamLogon_with_creds(struct torture_context *tctx,
3167 struct dcerpc_pipe *p,
3168 struct cli_credentials *machine_creds,
3169 const char *acct_name,
3170 const char *password,
3171 NTSTATUS expected_samlogon_result,
3175 struct cli_credentials *test_credentials;
3177 test_credentials = cli_credentials_init(tctx);
3179 cli_credentials_set_workstation(test_credentials,
3180 cli_credentials_get_workstation(machine_creds), CRED_SPECIFIED);
3181 cli_credentials_set_domain(test_credentials,
3182 cli_credentials_get_domain(machine_creds), CRED_SPECIFIED);
3183 cli_credentials_set_username(test_credentials,
3184 acct_name, CRED_SPECIFIED);
3185 cli_credentials_set_password(test_credentials,
3186 password, CRED_SPECIFIED);
3188 torture_comment(tctx, "Testing samlogon (%s) as %s password: %s\n",
3189 interactive ? "interactive" : "network", acct_name, password);
3191 if (!test_SamLogon(tctx, p, machine_creds, test_credentials,
3192 expected_samlogon_result, interactive)) {
3193 torture_result(tctx, TORTURE_FAIL, "new password did not work\n");
3200 static bool test_SetPassword_level(struct dcerpc_pipe *p,
3201 struct dcerpc_pipe *np,
3202 struct torture_context *tctx,
3203 struct policy_handle *handle,
3205 uint32_t fields_present,
3206 uint8_t password_expired,
3207 bool *matched_expected_error,
3209 const char *acct_name,
3211 struct cli_credentials *machine_creds,
3212 bool use_queryinfo2,
3214 NTSTATUS expected_samlogon_result)
3216 const char *fields = NULL;
3218 struct dcerpc_binding_handle *b = p->binding_handle;
3224 fields = talloc_asprintf(tctx, "(fields_present: 0x%08x)",
3231 torture_comment(tctx, "Testing SetUserInfo%s level %d call "
3232 "(password_expired: %d) %s\n",
3233 use_setinfo2 ? "2":"", level, password_expired,
3234 fields ? fields : "");
3236 if (!test_SetUserPass_level_ex(p, tctx, handle, level,
3241 matched_expected_error)) {
3245 if (!test_QueryUserInfo_pwdlastset(b, tctx, handle,
3251 if (*matched_expected_error == true) {
3255 if (!test_SamLogon_with_creds(tctx, np,
3259 expected_samlogon_result,
3267 static bool setup_schannel_netlogon_pipe(struct torture_context *tctx,
3268 struct cli_credentials *credentials,
3269 struct dcerpc_pipe **p)
3271 struct dcerpc_binding *b;
3274 torture_assert_ntstatus_ok(tctx, torture_rpc_binding(tctx, &b),
3275 "failed to get rpc binding");
3277 /* We have to use schannel, otherwise the SamLogonEx fails
3278 * with INTERNAL_ERROR */
3280 status = dcerpc_binding_set_flags(b,
3282 DCERPC_SIGN | DCERPC_SEAL |
3283 DCERPC_SCHANNEL_AUTO,
3284 DCERPC_AUTH_OPTIONS);
3285 torture_assert_ntstatus_ok(tctx, status, "set flags");
3287 torture_assert_ntstatus_ok(tctx,
3288 dcerpc_pipe_connect_b(tctx, p, b, &ndr_table_netlogon,
3289 credentials, tctx->ev, tctx->lp_ctx),
3290 "failed to bind to netlogon");
3295 static bool test_SetPassword_pwdlastset(struct dcerpc_pipe *p,
3296 struct torture_context *tctx,
3297 uint32_t acct_flags,
3298 const char *acct_name,
3299 struct policy_handle *handle,
3301 struct cli_credentials *machine_credentials)
3303 int s = 0, q = 0, f = 0, l = 0, z = 0;
3306 bool set_levels[] = { false, true };
3307 bool query_levels[] = { false, true };
3308 uint32_t levels[] = { 18, 21, 26, 23, 24, 25 }; /* Second half only used when TEST_ALL_LEVELS defined */
3309 uint32_t nonzeros[] = { 1, 24 };
3310 uint32_t fields_present[] = {
3312 SAMR_FIELD_EXPIRED_FLAG,
3313 SAMR_FIELD_LAST_PWD_CHANGE,
3314 SAMR_FIELD_EXPIRED_FLAG | SAMR_FIELD_LAST_PWD_CHANGE,
3316 SAMR_FIELD_NT_PASSWORD_PRESENT,
3317 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
3318 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
3319 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
3320 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
3321 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
3322 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE | SAMR_FIELD_EXPIRED_FLAG
3324 struct dcerpc_pipe *np = NULL;
3326 if (torture_setting_bool(tctx, "samba3", false) ||
3327 torture_setting_bool(tctx, "samba4", false)) {
3329 torture_comment(tctx, "Samba3 has second granularity, setting delay to: %d\n",
3333 torture_assert(tctx, setup_schannel_netlogon_pipe(tctx, machine_credentials, &np), "");
3335 /* set to 1 to enable testing for all possible opcode
3336 (SetUserInfo, SetUserInfo2, QueryUserInfo, QueryUserInfo2)
3339 #define TEST_ALL_LEVELS 1
3340 #define TEST_SET_LEVELS 1
3341 #define TEST_QUERY_LEVELS 1
3343 #ifdef TEST_ALL_LEVELS
3344 for (l=0; l<ARRAY_SIZE(levels); l++) {
3346 for (l=0; l<(ARRAY_SIZE(levels))/2; l++) {
3348 for (z=0; z<ARRAY_SIZE(nonzeros); z++) {
3349 for (f=0; f<ARRAY_SIZE(fields_present); f++) {
3350 #ifdef TEST_SET_LEVELS
3351 for (s=0; s<ARRAY_SIZE(set_levels); s++) {
3353 #ifdef TEST_QUERY_LEVELS
3354 for (q=0; q<ARRAY_SIZE(query_levels); q++) {
3356 NTTIME pwdlastset_old = 0;
3357 NTTIME pwdlastset_new = 0;
3358 bool matched_expected_error = false;
3359 NTSTATUS expected_samlogon_result = NT_STATUS_ACCOUNT_DISABLED;
3361 torture_comment(tctx, "------------------------------\n"
3362 "Testing pwdLastSet attribute for flags: 0x%08x "
3363 "(s: %d (l: %d), q: %d)\n",
3364 acct_flags, s, levels[l], q);
3366 switch (levels[l]) {
3370 if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3371 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT))) {
3372 expected_samlogon_result = NT_STATUS_WRONG_PASSWORD;
3380 /* set a password and force password change (pwdlastset 0) by
3381 * setting the password expired flag to a non-0 value */
3383 if (!test_SetPassword_level(p, np, tctx, handle,
3387 &matched_expected_error,
3391 machine_credentials,
3394 expected_samlogon_result)) {
3398 if (matched_expected_error == true) {
3399 /* skipping on expected failure */
3403 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3404 * set without the SAMR_FIELD_EXPIRED_FLAG */
3406 switch (levels[l]) {
3410 if ((pwdlastset_new != 0) &&
3411 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
3412 torture_comment(tctx, "not considering a non-0 "
3413 "pwdLastSet as a an error as the "
3414 "SAMR_FIELD_EXPIRED_FLAG has not "
3420 if (pwdlastset_new != 0) {
3421 torture_result(tctx, TORTURE_FAIL, "pwdLastSet test failed: "
3422 "expected pwdLastSet 0 but got %llu\n",
3423 (unsigned long long) pwdlastset_old);
3429 switch (levels[l]) {
3433 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3434 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3435 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3436 (pwdlastset_old >= pwdlastset_new)) {
3437 torture_result(tctx, TORTURE_FAIL, "pwdlastset not increasing\n");
3443 pwdlastset_old = pwdlastset_new;
3449 /* set a password, pwdlastset needs to get updated (increased
3450 * value), password_expired value used here is 0 */
3452 if (!test_SetPassword_level(p, np, tctx, handle,
3456 &matched_expected_error,
3460 machine_credentials,
3463 expected_samlogon_result)) {
3467 /* when a password has been changed, pwdlastset must not be 0 afterwards
3468 * and must be larger then the old value */
3470 switch (levels[l]) {
3474 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3475 * password has been changed, old and new pwdlastset
3476 * need to be the same value */
3478 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3479 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3480 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3482 torture_assert_int_equal(tctx, pwdlastset_old,
3483 pwdlastset_new, "pwdlastset must be equal");
3488 if (pwdlastset_old >= pwdlastset_new) {
3489 torture_result(tctx, TORTURE_FAIL, "pwdLastSet test failed: "
3490 "expected last pwdlastset (%llu) < new pwdlastset (%llu)\n",
3491 (unsigned long long) pwdlastset_old,
3492 (unsigned long long) pwdlastset_new);
3495 if (pwdlastset_new == 0) {
3496 torture_result(tctx, TORTURE_FAIL, "pwdLastSet test failed: "
3497 "expected non-0 pwdlastset, got: %llu\n",
3498 (unsigned long long) pwdlastset_new);
3504 switch (levels[l]) {
3508 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3509 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3510 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3511 (pwdlastset_old >= pwdlastset_new)) {
3512 torture_result(tctx, TORTURE_FAIL, "pwdlastset not increasing\n");
3518 pwdlastset_old = pwdlastset_new;
3524 /* set a password, pwdlastset needs to get updated (increased
3525 * value), password_expired value used here is 0 */
3527 if (!test_SetPassword_level(p, np, tctx, handle,
3531 &matched_expected_error,
3535 machine_credentials,
3538 expected_samlogon_result)) {
3542 /* when a password has been changed, pwdlastset must not be 0 afterwards
3543 * and must be larger then the old value */
3545 switch (levels[l]) {
3550 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3551 * password has been changed, old and new pwdlastset
3552 * need to be the same value */
3554 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3555 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3556 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3558 torture_assert_int_equal(tctx, pwdlastset_old,
3559 pwdlastset_new, "pwdlastset must be equal");
3564 if (pwdlastset_old >= pwdlastset_new) {
3565 torture_result(tctx, TORTURE_FAIL, "pwdLastSet test failed: "
3566 "expected last pwdlastset (%llu) < new pwdlastset (%llu)\n",
3567 (unsigned long long) pwdlastset_old,
3568 (unsigned long long) pwdlastset_new);
3571 if (pwdlastset_new == 0) {
3572 torture_result(tctx, TORTURE_FAIL, "pwdLastSet test failed: "
3573 "expected non-0 pwdlastset, got: %llu\n",
3574 (unsigned long long) pwdlastset_new);
3580 switch (levels[l]) {
3584 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3585 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3586 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3587 (pwdlastset_old >= pwdlastset_new)) {
3588 torture_result(tctx, TORTURE_FAIL, "pwdlastset not increasing\n");
3594 pwdlastset_old = pwdlastset_new;
3600 /* set a password and force password change (pwdlastset 0) by
3601 * setting the password expired flag to a non-0 value */
3603 if (!test_SetPassword_level(p, np, tctx, handle,
3607 &matched_expected_error,
3611 machine_credentials,
3614 expected_samlogon_result)) {
3618 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3619 * set without the SAMR_FIELD_EXPIRED_FLAG */
3621 switch (levels[l]) {
3625 if ((pwdlastset_new != 0) &&
3626 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
3627 torture_comment(tctx, "not considering a non-0 "
3628 "pwdLastSet as a an error as the "
3629 "SAMR_FIELD_EXPIRED_FLAG has not "
3634 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3635 * password has been changed, old and new pwdlastset
3636 * need to be the same value */
3638 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3639 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3640 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3642 torture_assert_int_equal(tctx, pwdlastset_old,
3643 pwdlastset_new, "pwdlastset must be equal");
3648 if (pwdlastset_new != 0) {
3649 torture_result(tctx, TORTURE_FAIL, "pwdLastSet test failed: "
3650 "expected pwdLastSet 0, got %llu\n",
3651 (unsigned long long) pwdlastset_old);
3657 switch (levels[l]) {
3661 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3662 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3663 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3664 (pwdlastset_old >= pwdlastset_new)) {
3665 torture_result(tctx, TORTURE_FAIL, "pwdlastset not increasing\n");
3671 /* if the level we are testing does not have a fields_present
3672 * field, skip all fields present tests by setting f to to
3674 switch (levels[l]) {
3678 f = ARRAY_SIZE(fields_present);
3682 #ifdef TEST_QUERY_LEVELS
3685 #ifdef TEST_SET_LEVELS
3688 } /* fields present */
3692 #undef TEST_SET_LEVELS
3693 #undef TEST_QUERY_LEVELS
3700 static bool test_QueryUserInfo_badpwdcount(struct dcerpc_binding_handle *b,
3701 struct torture_context *tctx,
3702 struct policy_handle *handle,
3703 uint32_t *badpwdcount)
3705 union samr_UserInfo *info;
3706 struct samr_QueryUserInfo r;
3708 r.in.user_handle = handle;
3712 torture_comment(tctx, "Testing QueryUserInfo level %d", r.in.level);
3714 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
3715 "failed to query userinfo");
3716 torture_assert_ntstatus_ok(tctx, r.out.result,
3717 "failed to query userinfo");
3719 *badpwdcount = info->info3.bad_password_count;
3721 torture_comment(tctx, " (bad password count: %d)\n", *badpwdcount);
3726 static bool test_SetUserInfo_acct_flags(struct dcerpc_binding_handle *b,
3727 struct torture_context *tctx,
3728 struct policy_handle *user_handle,
3729 uint32_t acct_flags)
3731 struct samr_SetUserInfo r;
3732 union samr_UserInfo user_info;
3734 torture_comment(tctx, "Testing SetUserInfo level 16\n");
3736 user_info.info16.acct_flags = acct_flags;
3738 r.in.user_handle = user_handle;
3740 r.in.info = &user_info;
3742 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &r),
3743 "failed to set account flags");
3744 torture_assert_ntstatus_ok(tctx, r.out.result,
3745 "failed to set account flags");
3750 static bool test_reset_badpwdcount(struct dcerpc_pipe *p,
3751 struct torture_context *tctx,
3752 struct policy_handle *user_handle,
3753 uint32_t acct_flags,
3756 struct dcerpc_binding_handle *b = p->binding_handle;
3758 torture_assert(tctx, test_SetUserPass(p, tctx, user_handle, password),
3759 "failed to set password");
3761 torture_comment(tctx, "Testing SetUserInfo level 16 (enable account)\n");
3763 torture_assert(tctx,
3764 test_SetUserInfo_acct_flags(b, tctx, user_handle,
3765 acct_flags & ~ACB_DISABLED),
3766 "failed to enable user");
3768 torture_assert(tctx, test_SetUserPass(p, tctx, user_handle, password),
3769 "failed to set password");
3774 static bool test_SetDomainInfo(struct dcerpc_binding_handle *b,
3775 struct torture_context *tctx,
3776 struct policy_handle *domain_handle,
3777 enum samr_DomainInfoClass level,
3778 union samr_DomainInfo *info)
3780 struct samr_SetDomainInfo r;
3782 r.in.domain_handle = domain_handle;
3786 torture_assert_ntstatus_ok(tctx,
3787 dcerpc_samr_SetDomainInfo_r(b, tctx, &r),
3788 "failed to set domain info");
3789 torture_assert_ntstatus_ok(tctx, r.out.result,
3790 "failed to set domain info");
3795 static bool test_SetDomainInfo_ntstatus(struct dcerpc_binding_handle *b,
3796 struct torture_context *tctx,
3797 struct policy_handle *domain_handle,
3798 enum samr_DomainInfoClass level,
3799 union samr_DomainInfo *info,
3802 struct samr_SetDomainInfo r;
3804 r.in.domain_handle = domain_handle;
3808 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &r),
3809 "SetDomainInfo failed");
3810 torture_assert_ntstatus_equal(tctx, r.out.result, expected, "");
3815 static bool test_QueryDomainInfo2_level(struct dcerpc_binding_handle *b,
3816 struct torture_context *tctx,
3817 struct policy_handle *domain_handle,
3818 enum samr_DomainInfoClass level,
3819 union samr_DomainInfo **q_info)
3821 struct samr_QueryDomainInfo2 r;
3823 r.in.domain_handle = domain_handle;
3825 r.out.info = q_info;
3827 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo2_r(b, tctx, &r),
3828 "failed to query domain info");
3829 torture_assert_ntstatus_ok(tctx, r.out.result,
3830 "failed to query domain info");
3835 static bool test_Password_badpwdcount(struct dcerpc_pipe *p,
3836 struct dcerpc_pipe *np,
3837 struct torture_context *tctx,
3838 uint32_t acct_flags,
3839 const char *acct_name,
3840 struct policy_handle *domain_handle,
3841 struct policy_handle *user_handle,
3843 struct cli_credentials *machine_credentials,
3844 const char *comment,
3847 NTSTATUS expected_success_status,
3848 struct samr_DomInfo1 *info1,
3849 struct samr_DomInfo12 *info12)
3851 union samr_DomainInfo info;
3854 uint32_t badpwdcount, tmp;
3855 uint32_t password_history_length = 12;
3856 uint32_t lockout_threshold = 15;
3857 uint32_t lockout_seconds = 5;
3858 uint64_t delta_time_factor = 10 * 1000 * 1000;
3859 struct dcerpc_binding_handle *b = p->binding_handle;
3861 if (torture_setting_bool(tctx, "samba3", false)) {
3862 lockout_seconds = 60;
3865 torture_comment(tctx, "\nTesting bad pwd count with: %s\n", comment);
3867 torture_assert(tctx, password_history_length < lockout_threshold,
3868 "password history length needs to be smaller than account lockout threshold for this test");
3873 info.info1 = *info1;
3874 info.info1.password_history_length = password_history_length;
3875 info.info1.min_password_age = 0;
3877 torture_assert(tctx,
3878 test_SetDomainInfo(b, tctx, domain_handle,
3879 DomainPasswordInformation, &info),
3880 "failed to set password history length and min passwd age");
3882 info.info12 = *info12;
3883 info.info12.lockout_threshold = lockout_threshold;
3885 /* set lockout duration of 5 seconds */
3886 info.info12.lockout_duration = ~(lockout_seconds * delta_time_factor);
3887 info.info12.lockout_window = ~(lockout_seconds * delta_time_factor);
3889 torture_assert(tctx,
3890 test_SetDomainInfo(b, tctx, domain_handle,
3891 DomainLockoutInformation, &info),
3892 "failed to set lockout threshold");
3894 /* reset bad pwd count */
3896 torture_assert(tctx,
3897 test_reset_badpwdcount(p, tctx, user_handle, acct_flags, password), "");
3900 /* enable or disable account */
3902 torture_assert(tctx,
3903 test_SetUserInfo_acct_flags(b, tctx, user_handle,
3904 acct_flags | ACB_DISABLED),
3905 "failed to disable user");
3907 torture_assert(tctx,
3908 test_SetUserInfo_acct_flags(b, tctx, user_handle,
3909 acct_flags & ~ACB_DISABLED),
3910 "failed to enable user");
3914 /* setup password history */
3916 passwords = talloc_array(tctx, char *, password_history_length);
3918 for (i=0; i < password_history_length; i++) {
3920 torture_assert(tctx, test_SetUserPass(p, tctx, user_handle, password),
3921 "failed to set password");
3922 passwords[i] = talloc_strdup(tctx, *password);
3924 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3925 acct_name, passwords[i],
3926 expected_success_status, interactive)) {
3927 torture_fail(tctx, "failed to auth with latest password");
3930 torture_assert(tctx,
3931 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
3933 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
3937 /* test with wrong password */
3939 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3940 acct_name, "random_crap",
3941 NT_STATUS_WRONG_PASSWORD, interactive)) {
3942 torture_fail(tctx, "succeeded to authenticate with wrong password");
3945 torture_assert(tctx,
3946 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
3948 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
3951 /* test with latest good password */
3953 if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
3954 passwords[password_history_length-1],
3955 expected_success_status, interactive)) {
3956 torture_fail(tctx, "succeeded to authenticate with wrong password");
3959 torture_assert(tctx,
3960 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
3963 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
3965 /* only enabled accounts get the bad pwd count reset upon
3966 * successful logon */
3967 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
3973 /* test password history */
3975 for (i=0; i < password_history_length; i++) {
3977 torture_comment(tctx, "Testing bad password count behavior with "
3978 "password #%d of #%d\n", i, password_history_length);
3980 /* - network samlogon will succeed auth and not
3981 * increase badpwdcount for 2 last entries
3982 * - interactive samlogon only for the last one */
3984 if (i == password_history_length - 1 ||
3985 (i == password_history_length - 2 && !interactive)) {
3987 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3988 acct_name, passwords[i],
3989 expected_success_status, interactive)) {
3990 torture_fail(tctx, talloc_asprintf(tctx, "did not successfully to obtain %s for %s login with old password (#%d of #%d in history)",
3991 nt_errstr(expected_success_status),
3992 interactive ? "interactive" : "network", i, password_history_length));
3995 torture_assert(tctx,
3996 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
3999 /* torture_comment(tctx, "expecting bad pwd count to *NOT INCREASE* for pwd history entry %d\n", i); */
4000 torture_assert_int_equal(tctx, badpwdcount, tmp, "unexpected badpwdcount");
4002 /* torture_comment(tctx, "expecting bad pwd count to be 0 for pwd history entry %d\n", i); */
4003 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
4011 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
4012 acct_name, passwords[i],
4013 NT_STATUS_WRONG_PASSWORD, interactive)) {
4014 torture_fail(tctx, talloc_asprintf(tctx, "succeeded to authenticate with old password (#%d of #%d in history)", i, password_history_length));
4017 torture_assert(tctx,
4018 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
4020 /* - network samlogon will fail auth but not increase
4021 * badpwdcount for 3rd last entry
4022 * - interactive samlogon for 3rd and 2nd last entry */
4024 if (i == password_history_length - 3 ||
4025 (i == password_history_length - 2 && interactive)) {
4026 /* torture_comment(tctx, "expecting bad pwd count to *NOT INCREASE * by one for pwd history entry %d\n", i); */
4027 torture_assert_int_equal(tctx, badpwdcount, tmp, "unexpected badpwdcount");
4029 /* torture_comment(tctx, "expecting bad pwd count to increase by one for pwd history entry %d\n", i); */
4030 torture_assert_int_equal(tctx, badpwdcount, tmp + 1, "unexpected badpwdcount");
4039 static bool test_Password_badpwdcount_wrap(struct dcerpc_pipe *p,
4040 struct torture_context *tctx,
4041 uint32_t acct_flags,
4042 const char *acct_name,
4043 struct policy_handle *domain_handle,
4044 struct policy_handle *user_handle,
4046 struct cli_credentials *machine_credentials)
4048 union samr_DomainInfo *q_info, s_info;
4049 struct samr_DomInfo1 info1, _info1;
4050 struct samr_DomInfo12 info12, _info12;
4052 struct dcerpc_binding_handle *b = p->binding_handle;
4053 struct dcerpc_pipe *np;
4057 const char *comment;
4060 NTSTATUS expected_success_status;
4063 .comment = "network logon (disabled account)",
4065 .interactive = false,
4066 .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
4069 .comment = "network logon (enabled account)",
4071 .interactive = false,
4072 .expected_success_status= NT_STATUS_OK
4075 .comment = "interactive logon (disabled account)",
4077 .interactive = true,
4078 .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
4081 .comment = "interactive logon (enabled account)",
4083 .interactive = true,
4084 .expected_success_status= NT_STATUS_OK
4088 torture_assert(tctx, setup_schannel_netlogon_pipe(tctx, machine_credentials, &np), "");
4090 /* backup old policies */
4092 torture_assert(tctx,
4093 test_QueryDomainInfo2_level(b, tctx, domain_handle,
4094 DomainPasswordInformation, &q_info),
4095 "failed to query domain info level 1");
4097 info1 = q_info->info1;
4100 torture_assert(tctx,
4101 test_QueryDomainInfo2_level(b, tctx, domain_handle,
4102 DomainLockoutInformation, &q_info),
4103 "failed to query domain info level 12");
4105 info12 = q_info->info12;
4110 for (i=0; i < ARRAY_SIZE(creds); i++) {
4112 /* skip trust tests for now */
4113 if (acct_flags & ACB_WSTRUST ||
4114 acct_flags & ACB_SVRTRUST ||
4115 acct_flags & ACB_DOMTRUST) {
4119 if (!test_Password_badpwdcount(p, np, tctx, acct_flags, acct_name,
4120 domain_handle, user_handle, password,
4121 machine_credentials,
4124 creds[i].interactive,
4125 creds[i].expected_success_status,
4126 &_info1, &_info12)) {
4127 torture_result(tctx, TORTURE_FAIL, "TEST #%d (%s) failed\n", i, creds[i].comment);
4130 torture_comment(tctx, "TEST #%d (%s) succeeded\n", i, creds[i].comment);
4134 /* restore policies */
4136 s_info.info1 = info1;
4138 torture_assert(tctx,
4139 test_SetDomainInfo(b, tctx, domain_handle,
4140 DomainPasswordInformation, &s_info),
4141 "failed to set password information");
4143 s_info.info12 = info12;
4145 torture_assert(tctx,
4146 test_SetDomainInfo(b, tctx, domain_handle,
4147 DomainLockoutInformation, &s_info),
4148 "failed to set lockout information");
4153 static bool test_QueryUserInfo_lockout(struct dcerpc_binding_handle *b,
4154 struct torture_context *tctx,
4155 struct policy_handle *domain_handle,
4156 const char *acct_name,
4157 uint16_t raw_bad_password_count,
4158 uint16_t effective_bad_password_count,
4159 uint32_t effective_acb_lockout)
4161 struct policy_handle user_handle;
4162 union samr_UserInfo *i;
4163 struct samr_QueryUserInfo r;
4165 NTSTATUS status = test_OpenUser_byname(b, tctx, domain_handle, acct_name, &user_handle);
4166 if (!NT_STATUS_IS_OK(status)) {
4170 r.in.user_handle = &user_handle;
4173 torture_comment(tctx, "Testing QueryUserInfo level %d", r.in.level);
4174 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
4175 "failed to query userinfo");
4176 torture_assert_ntstatus_ok(tctx, r.out.result,
4177 "failed to query userinfo");
4178 torture_comment(tctx, " (acct_flags: 0x%08x) (raw_bad_pwd_count: %u)\n",
4179 i->info3.acct_flags, i->info3.bad_password_count);
4180 torture_assert_int_equal(tctx, i->info3.bad_password_count,
4181 raw_bad_password_count,
4183 torture_assert_int_equal(tctx, i->info3.acct_flags & ACB_AUTOLOCK,
4184 effective_acb_lockout,
4185 "effective acb_lockout");
4188 r.in.user_handle = &user_handle;
4191 torture_comment(tctx, "Testing QueryUserInfo level %d", r.in.level);
4192 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
4193 "failed to query userinfo");
4194 torture_assert_ntstatus_ok(tctx, r.out.result,
4195 "failed to query userinfo");
4196 torture_comment(tctx, " (acct_flags: 0x%08x) (effective_bad_pwd_count: %u)\n",
4197 i->info5.acct_flags, i->info5.bad_password_count);
4198 torture_assert_int_equal(tctx, i->info5.bad_password_count,
4199 effective_bad_password_count,
4200 "effective badpwdcount");
4201 torture_assert_int_equal(tctx, i->info5.acct_flags & ACB_AUTOLOCK,
4202 effective_acb_lockout,
4203 "effective acb_lockout");
4206 r.in.user_handle = &user_handle;
4209 torture_comment(tctx, "Testing QueryUserInfo level %d", r.in.level);
4210 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
4211 "failed to query userinfo");
4212 torture_assert_ntstatus_ok(tctx, r.out.result,
4213 "failed to query userinfo");
4214 torture_comment(tctx, " (acct_flags: 0x%08x)\n",
4215 i->info16.acct_flags);
4216 torture_assert_int_equal(tctx, i->info16.acct_flags & ACB_AUTOLOCK,
4217 effective_acb_lockout,
4218 "effective acb_lockout");
4221 r.in.user_handle = &user_handle;
4224 torture_comment(tctx, "Testing QueryUserInfo level %d", r.in.level);
4225 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
4226 "failed to query userinfo");
4227 torture_assert_ntstatus_ok(tctx, r.out.result,
4228 "failed to query userinfo");
4229 torture_comment(tctx, " (acct_flags: 0x%08x) (effective_bad_pwd_count: %u)\n",
4230 i->info21.acct_flags, i->info21.bad_password_count);
4231 torture_assert_int_equal(tctx, i->info21.bad_password_count,
4232 effective_bad_password_count,
4233 "effective badpwdcount");
4234 torture_assert_int_equal(tctx, i->info21.acct_flags & ACB_AUTOLOCK,
4235 effective_acb_lockout,
4236 "effective acb_lockout");
4239 if (!test_samr_handle_Close(b, tctx, &user_handle)) {
4246 static bool test_Password_lockout(struct dcerpc_pipe *p,
4247 struct dcerpc_pipe *np,
4248 struct torture_context *tctx,
4249 uint32_t acct_flags,
4250 const char *acct_name,
4251 struct policy_handle *domain_handle,
4252 struct policy_handle *user_handle,
4254 struct cli_credentials *machine_credentials,
4255 const char *comment,
4258 uint32_t password_history_length,
4259 NTSTATUS expected_success_status,
4260 struct samr_DomInfo1 *info1,
4261 struct samr_DomInfo12 *info12)
4263 union samr_DomainInfo info;
4264 uint64_t lockout_threshold = 1;
4265 uint32_t lockout_seconds = 5;
4266 uint64_t delta_time_factor = 10 * 1000 * 1000;
4267 struct dcerpc_binding_handle *b = p->binding_handle;
4269 if (torture_setting_bool(tctx, "samba3", false)) {
4270 lockout_seconds = 60;
4273 torture_comment(tctx, "\nTesting account lockout: %s\n", comment);
4277 info.info1 = *info1;
4279 torture_comment(tctx, "setting password history length to %d.\n", password_history_length);
4280 info.info1.password_history_length = password_history_length;
4282 torture_comment(tctx, "setting min password again.\n");
4283 info.info1.min_password_age = 0;
4285 torture_assert(tctx,
4286 test_SetDomainInfo(b, tctx, domain_handle,
4287 DomainPasswordInformation, &info),
4288 "failed to set password history length");
4290 info.info12 = *info12;
4291 info.info12.lockout_threshold = lockout_threshold;
4293 /* set lockout duration < lockout window: should fail */
4294 info.info12.lockout_duration = ~(lockout_seconds * delta_time_factor);
4295 info.info12.lockout_window = ~((lockout_seconds + 1) * delta_time_factor);
4297 torture_assert(tctx,
4298 test_SetDomainInfo_ntstatus(b, tctx, domain_handle,
4299 DomainLockoutInformation, &info,
4300 NT_STATUS_INVALID_PARAMETER),
4301 "setting lockout duration < lockout window gave unexpected result");
4303 info.info12.lockout_duration = 0;
4304 info.info12.lockout_window = 0;
4306 torture_assert(tctx,
4307 test_SetDomainInfo(b, tctx, domain_handle,
4308 DomainLockoutInformation, &info),
4309 "failed to set lockout window and duration to 0");
4312 /* set lockout duration of 5 seconds */
4313 info.info12.lockout_duration = ~(lockout_seconds * delta_time_factor);
4314 info.info12.lockout_window = ~(lockout_seconds * delta_time_factor);
4316 torture_assert(tctx,
4317 test_SetDomainInfo(b, tctx, domain_handle,
4318 DomainLockoutInformation, &info),
4319 "failed to set lockout window and duration to 5 seconds");
4321 /* reset bad pwd count */
4323 torture_assert(tctx,
4324 test_reset_badpwdcount(p, tctx, user_handle, acct_flags, password), "");
4327 /* enable or disable account */
4330 torture_assert(tctx,
4331 test_SetUserInfo_acct_flags(b, tctx, user_handle,
4332 acct_flags | ACB_DISABLED),
4333 "failed to disable user");
4335 torture_assert(tctx,
4336 test_SetUserInfo_acct_flags(b, tctx, user_handle,
4337 acct_flags & ~ACB_DISABLED),
4338 "failed to enable user");
4342 /* test logon with right password */
4344 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
4345 acct_name, *password,
4346 expected_success_status, interactive)) {
4347 torture_fail(tctx, "failed to auth with latest password");
4350 torture_assert(tctx,
4351 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4353 "expected account to not be locked");
4355 /* test with wrong password ==> lockout */
4357 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
4358 acct_name, "random_crap",
4359 NT_STATUS_WRONG_PASSWORD, interactive)) {
4360 torture_fail(tctx, "succeeded to authenticate with wrong password");
4364 * curiously, windows does _not_ return fresh values of
4365 * effective bad_password_count and ACB_AUTOLOCK.
4367 torture_assert(tctx,
4368 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4369 1, 1, ACB_AUTOLOCK),
4370 "expected account to not be locked");
4372 /* test with good password */
4374 if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
4376 NT_STATUS_ACCOUNT_LOCKED_OUT, interactive))
4378 torture_fail(tctx, "authenticate did not return NT_STATUS_ACCOUNT_LOCKED_OUT");
4381 /* bad pwd count should not get updated */
4382 torture_assert(tctx,
4383 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4384 1, 1, ACB_AUTOLOCK),
4385 "expected account to be locked");
4387 torture_assert(tctx,
4388 test_ChangePasswordUser2_ntstatus(p, tctx, acct_name, *password,
4389 NT_STATUS_ACCOUNT_LOCKED_OUT),
4390 "got wrong status from ChangePasswordUser2");
4392 /* bad pwd count should not get updated */
4393 torture_assert(tctx,
4394 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4395 1, 1, ACB_AUTOLOCK),
4396 "expected account to be locked");
4398 torture_assert(tctx,
4399 test_ChangePasswordUser2_ntstatus(p, tctx, acct_name, "random_crap", NT_STATUS_ACCOUNT_LOCKED_OUT),
4400 "got wrong status from ChangePasswordUser2");
4402 /* bad pwd count should not get updated */
4403 torture_assert(tctx,
4404 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4405 1, 1, ACB_AUTOLOCK),
4406 "expected account to be locked");
4408 /* with bad password */
4410 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
4411 acct_name, "random_crap2",
4412 NT_STATUS_ACCOUNT_LOCKED_OUT, interactive))
4414 torture_fail(tctx, "authenticate did not return NT_STATUS_ACCOUNT_LOCKED_OUT");
4417 /* bad pwd count should not get updated */
4418 torture_assert(tctx,
4419 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4420 1, 1, ACB_AUTOLOCK),
4421 "expected account to be locked");
4423 /* let lockout duration expire ==> unlock */
4425 torture_comment(tctx, "let lockout duration expire...\n");
4426 sleep(lockout_seconds + 1);
4428 torture_assert(tctx,
4429 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4431 "expected account to not be locked");
4433 if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
4435 expected_success_status, interactive))
4437 torture_fail(tctx, "failed to authenticate after lockout expired");
4440 if (NT_STATUS_IS_OK(expected_success_status)) {
4441 torture_assert(tctx,
4442 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4444 "expected account to not be locked");
4446 torture_assert(tctx,
4447 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4449 "expected account to not be locked");
4452 torture_assert(tctx,
4453 test_ChangePasswordUser2_ntstatus(p, tctx, acct_name, "random_crap", NT_STATUS_WRONG_PASSWORD),
4454 "got wrong status from ChangePasswordUser2");
4456 torture_assert(tctx,
4457 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4458 1, 1, ACB_AUTOLOCK),
4459 "expected account to be locked");
4461 torture_assert(tctx,
4462 test_ChangePasswordUser2_ntstatus(p, tctx, acct_name, *password, NT_STATUS_ACCOUNT_LOCKED_OUT),
4463 "got wrong status from ChangePasswordUser2");
4465 torture_assert(tctx,
4466 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4467 1, 1, ACB_AUTOLOCK),
4468 "expected account to be locked");
4470 torture_assert(tctx,
4471 test_ChangePasswordUser2_ntstatus(p, tctx, acct_name, "random_crap", NT_STATUS_ACCOUNT_LOCKED_OUT),
4472 "got wrong status from ChangePasswordUser2");
4474 torture_assert(tctx,
4475 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4476 1, 1, ACB_AUTOLOCK),
4477 "expected account to be locked");
4479 /* let lockout duration expire ==> unlock */
4481 torture_comment(tctx, "let lockout duration expire...\n");
4482 sleep(lockout_seconds + 1);
4484 torture_assert(tctx,
4485 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4487 "expected account to not be locked");
4489 if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
4491 expected_success_status, interactive))
4493 torture_fail(tctx, "failed to authenticate after lockout expired");
4496 if (NT_STATUS_IS_OK(expected_success_status)) {
4497 torture_assert(tctx,
4498 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4500 "expected account to not be locked");
4502 torture_assert(tctx,
4503 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4505 "expected account to not be locked");
4508 /* Testing ChangePasswordUser behaviour with 3 attempts */
4509 info.info12.lockout_threshold = 3;
4511 torture_assert(tctx,
4512 test_SetDomainInfo(b, tctx, domain_handle,
4513 DomainLockoutInformation, &info),
4514 "failed to set lockout threshold to 3");
4516 if (NT_STATUS_IS_OK(expected_success_status)) {
4517 torture_assert(tctx,
4518 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4520 "expected account to not be locked");
4522 torture_assert(tctx,
4523 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4525 "expected account to not be locked");
4528 torture_assert(tctx,
4529 test_ChangePasswordUser2_ntstatus(p, tctx, acct_name, "random_crap", NT_STATUS_WRONG_PASSWORD),
4530 "got wrong status from ChangePasswordUser2");
4532 /* bad pwd count will get updated */
4533 torture_assert(tctx,
4534 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4536 "expected account to not be locked");
4538 torture_assert(tctx,
4539 test_ChangePasswordUser2_ntstatus(p, tctx, acct_name, "random_crap", NT_STATUS_WRONG_PASSWORD),
4540 "got wrong status from ChangePasswordUser2");
4542 /* bad pwd count will get updated */
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_ChangePasswordUser2_ntstatus(p, tctx, acct_name, "random_crap", NT_STATUS_WRONG_PASSWORD),
4550 "got wrong status from ChangePasswordUser2");
4552 /* bad pwd count should get updated */
4553 torture_assert(tctx,
4554 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4555 3, 3, ACB_AUTOLOCK),
4556 "expected account to be locked");
4558 torture_assert(tctx,
4559 test_ChangePasswordUser2_ntstatus(p, tctx, acct_name, *password, NT_STATUS_ACCOUNT_LOCKED_OUT),
4560 "got wrong status from ChangePasswordUser2");
4562 /* bad pwd count should not get updated */
4563 torture_assert(tctx,
4564 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4565 3, 3, ACB_AUTOLOCK),
4566 "expected account to be locked");
4568 /* let lockout duration expire ==> unlock */
4570 torture_comment(tctx, "let lockout duration expire...\n");
4571 sleep(lockout_seconds + 1);
4573 torture_assert(tctx,
4574 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4576 "expected account to not be locked");
4578 torture_assert(tctx,
4579 test_ChangePasswordUser2(p, tctx, acct_name, password, NULL, false),
4580 "got wrong status from ChangePasswordUser2");
4582 torture_assert(tctx,
4583 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4585 "expected account to not be locked");
4587 /* Used to reset the badPwdCount for the other tests */
4588 if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
4590 expected_success_status, interactive))
4592 torture_fail(tctx, "failed to authenticate after lockout expired");
4595 if (NT_STATUS_IS_OK(expected_success_status)) {
4596 torture_assert(tctx,
4597 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4599 "expected account to not be locked");
4601 torture_assert(tctx,
4602 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4604 "expected account to not be locked");
4610 static bool test_Password_lockout_wrap(struct dcerpc_pipe *p,
4611 struct torture_context *tctx,
4612 uint32_t acct_flags,
4613 const char *acct_name,
4614 struct policy_handle *domain_handle,
4615 struct policy_handle *user_handle,
4617 struct cli_credentials *machine_credentials)
4619 union samr_DomainInfo *q_info, s_info;
4620 struct samr_DomInfo1 info1, _info1;
4621 struct samr_DomInfo12 info12, _info12;
4623 struct dcerpc_binding_handle *b = p->binding_handle;
4624 struct dcerpc_pipe *np;
4628 const char *comment;
4631 uint32_t password_history_length;
4632 NTSTATUS expected_success_status;
4635 .comment = "network logon (disabled account)",
4637 .interactive = false,
4638 .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
4641 .comment = "network logon (enabled account)",
4643 .interactive = false,
4644 .expected_success_status= NT_STATUS_OK
4647 .comment = "network logon (enabled account, history len = 1)",
4649 .interactive = false,
4650 .expected_success_status= NT_STATUS_OK,
4651 .password_history_length = 1
4654 .comment = "interactive logon (disabled account)",
4656 .interactive = true,
4657 .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
4660 .comment = "interactive logon (enabled account)",
4662 .interactive = true,
4663 .expected_success_status= NT_STATUS_OK
4666 .comment = "interactive logon (enabled account, history len = 1)",
4668 .interactive = true,
4669 .expected_success_status= NT_STATUS_OK,
4670 .password_history_length = 1
4674 torture_assert(tctx, setup_schannel_netlogon_pipe(tctx, machine_credentials, &np), "");
4676 /* backup old policies */
4678 torture_assert(tctx,
4679 test_QueryDomainInfo2_level(b, tctx, domain_handle,
4680 DomainPasswordInformation, &q_info),
4681 "failed to query domain info level 1");
4683 info1 = q_info->info1;
4686 torture_assert(tctx,
4687 test_QueryDomainInfo2_level(b, tctx, domain_handle,
4688 DomainLockoutInformation, &q_info),
4689 "failed to query domain info level 12");
4691 info12 = q_info->info12;
4696 for (i=0; i < ARRAY_SIZE(creds); i++) {
4698 /* skip trust tests for now */
4699 if (acct_flags & ACB_WSTRUST ||
4700 acct_flags & ACB_SVRTRUST ||
4701 acct_flags & ACB_DOMTRUST) {
4705 test_passed = test_Password_lockout(p, np, tctx, acct_flags, acct_name,
4706 domain_handle, user_handle, password,
4707 machine_credentials,
4710 creds[i].interactive,
4711 creds[i].password_history_length,
4712 creds[i].expected_success_status,
4716 torture_result(tctx, TORTURE_FAIL, "TEST #%d (%s) failed\n", i, creds[i].comment);
4719 torture_comment(tctx, "TEST #%d (%s) succeeded\n", i, creds[i].comment);
4723 /* restore policies */
4725 s_info.info1 = info1;
4727 torture_assert(tctx,
4728 test_SetDomainInfo(b, tctx, domain_handle,
4729 DomainPasswordInformation, &s_info),
4730 "failed to set password information");
4732 s_info.info12 = info12;
4734 torture_assert(tctx,
4735 test_SetDomainInfo(b, tctx, domain_handle,
4736 DomainLockoutInformation, &s_info),
4737 "failed to set lockout information");
4742 static bool test_DeleteUser_with_privs(struct dcerpc_pipe *p,
4743 struct dcerpc_pipe *lp,
4744 struct torture_context *tctx,
4745 struct policy_handle *domain_handle,
4746 struct policy_handle *lsa_handle,
4747 struct policy_handle *user_handle,
4748 const struct dom_sid *domain_sid,
4750 struct cli_credentials *machine_credentials)
4753 struct dcerpc_binding_handle *b = p->binding_handle;
4754 struct dcerpc_binding_handle *lb = lp->binding_handle;
4756 struct policy_handle lsa_acct_handle;
4757 struct dom_sid *user_sid;
4759 user_sid = dom_sid_add_rid(tctx, domain_sid, rid);
4762 struct lsa_EnumAccountRights r;
4763 struct lsa_RightSet rights;
4765 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4767 r.in.handle = lsa_handle;
4768 r.in.sid = user_sid;
4769 r.out.rights = &rights;
4771 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
4772 "lsa_EnumAccountRights failed");
4773 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4774 "Expected enum rights for account to fail");
4778 struct lsa_RightSet rights;
4779 struct lsa_StringLarge names[2];
4780 struct lsa_AddAccountRights r;
4782 torture_comment(tctx, "Testing LSA AddAccountRights\n");
4784 init_lsa_StringLarge(&names[0], "SeMachineAccountPrivilege");
4785 init_lsa_StringLarge(&names[1], NULL);
4788 rights.names = names;
4790 r.in.handle = lsa_handle;
4791 r.in.sid = user_sid;
4792 r.in.rights = &rights;
4794 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_AddAccountRights_r(lb, tctx, &r),
4795 "lsa_AddAccountRights failed");
4796 torture_assert_ntstatus_ok(tctx, r.out.result,
4797 "Failed to add privileges");
4801 struct lsa_RightSet rights;
4802 struct lsa_StringLarge names[2];
4803 struct lsa_AddAccountRights r;
4805 torture_comment(tctx, "Testing LSA AddAccountRights 1\n");
4807 init_lsa_StringLarge(&names[0], "SeInteractiveLogonRight");
4808 init_lsa_StringLarge(&names[1], NULL);
4811 rights.names = names;
4813 r.in.handle = lsa_handle;
4814 r.in.sid = user_sid;
4815 r.in.rights = &rights;
4817 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_AddAccountRights_r(lb, tctx, &r),
4818 "lsa_AddAccountRights 1 failed");
4820 if (torture_setting_bool(tctx, "nt4_dc", false)) {
4822 * The NT4 DC doesn't implement Rights.
4824 torture_assert_ntstatus_equal(tctx, r.out.result,
4825 NT_STATUS_NO_SUCH_PRIVILEGE,
4826 "Add rights failed with incorrect error");
4828 torture_assert_ntstatus_ok(tctx, r.out.result,
4829 "Failed to add rights");
4836 struct lsa_EnumAccounts r;
4837 uint32_t resume_handle = 0;
4838 struct lsa_SidArray lsa_sid_array;
4840 bool found_sid = false;
4842 torture_comment(tctx, "Testing LSA EnumAccounts\n");
4844 r.in.handle = lsa_handle;
4845 r.in.num_entries = 0x1000;
4846 r.in.resume_handle = &resume_handle;
4847 r.out.sids = &lsa_sid_array;
4848 r.out.resume_handle = &resume_handle;
4850 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(lb, tctx, &r),
4851 "lsa_EnumAccounts failed");
4852 torture_assert_ntstatus_ok(tctx, r.out.result,
4853 "Failed to enum accounts");
4855 for (i=0; i < lsa_sid_array.num_sids; i++) {
4856 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
4861 torture_assert(tctx, found_sid,
4862 "failed to list privileged account");
4866 struct lsa_EnumAccountRights r;
4867 struct lsa_RightSet user_rights;
4868 uint32_t expected_count = 2;
4870 if (torture_setting_bool(tctx, "nt4_dc", false)) {
4872 * NT4 DC doesn't store rights.
4877 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4879 r.in.handle = lsa_handle;
4880 r.in.sid = user_sid;
4881 r.out.rights = &user_rights;
4883 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
4884 "lsa_EnumAccountRights failed");
4885 torture_assert_ntstatus_ok(tctx, r.out.result,
4886 "Failed to enum rights for account");
4888 if (user_rights.count < expected_count) {
4889 torture_result(tctx, TORTURE_FAIL, "failed to find newly added rights");
4895 struct lsa_OpenAccount r;
4897 torture_comment(tctx, "Testing LSA OpenAccount\n");
4899 r.in.handle = lsa_handle;
4900 r.in.sid = user_sid;
4901 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4902 r.out.acct_handle = &lsa_acct_handle;
4904 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenAccount_r(lb, tctx, &r),
4905 "lsa_OpenAccount failed");
4906 torture_assert_ntstatus_ok(tctx, r.out.result,
4907 "Failed to open lsa account");
4911 struct lsa_GetSystemAccessAccount r;
4912 uint32_t access_mask;
4914 torture_comment(tctx, "Testing LSA GetSystemAccessAccount\n");
4916 r.in.handle = &lsa_acct_handle;
4917 r.out.access_mask = &access_mask;
4919 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetSystemAccessAccount_r(lb, tctx, &r),
4920 "lsa_GetSystemAccessAccount failed");
4921 torture_assert_ntstatus_ok(tctx, r.out.result,
4922 "Failed to get lsa system access account");
4928 torture_comment(tctx, "Testing LSA Close\n");
4930 r.in.handle = &lsa_acct_handle;
4931 r.out.handle = &lsa_acct_handle;
4933 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_Close_r(lb, tctx, &r),
4934 "lsa_Close failed");
4935 torture_assert_ntstatus_ok(tctx, r.out.result,
4936 "Failed to close lsa");
4940 struct samr_DeleteUser r;
4942 torture_comment(tctx, "Testing SAMR DeleteUser\n");
4944 r.in.user_handle = user_handle;
4945 r.out.user_handle = user_handle;
4947 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, tctx, &r),
4948 "DeleteUser failed");
4949 torture_assert_ntstatus_ok(tctx, r.out.result,
4950 "DeleteUser failed");
4954 struct lsa_EnumAccounts r;
4955 uint32_t resume_handle = 0;
4956 struct lsa_SidArray lsa_sid_array;
4958 bool found_sid = false;
4960 torture_comment(tctx, "Testing LSA EnumAccounts\n");
4962 r.in.handle = lsa_handle;
4963 r.in.num_entries = 0x1000;
4964 r.in.resume_handle = &resume_handle;
4965 r.out.sids = &lsa_sid_array;
4966 r.out.resume_handle = &resume_handle;
4968 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(lb, tctx, &r),
4969 "lsa_EnumAccounts failed");
4970 torture_assert_ntstatus_ok(tctx, r.out.result,
4971 "Failed to enum accounts");
4973 for (i=0; i < lsa_sid_array.num_sids; i++) {
4974 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
4979 torture_assert(tctx, found_sid,
4980 "failed to list privileged account");
4984 struct lsa_EnumAccountRights r;
4985 struct lsa_RightSet user_rights;
4987 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4989 r.in.handle = lsa_handle;
4990 r.in.sid = user_sid;
4991 r.out.rights = &user_rights;
4993 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
4994 "lsa_EnumAccountRights failed");
4995 torture_assert_ntstatus_ok(tctx, r.out.result,
4996 "Failed to enum rights for account");
4998 if (user_rights.count < 1) {
4999 torture_result(tctx, TORTURE_FAIL, "failed to find newly added rights");
5005 struct lsa_OpenAccount r;
5007 torture_comment(tctx, "Testing LSA OpenAccount\n");
5009 r.in.handle = lsa_handle;
5010 r.in.sid = user_sid;
5011 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5012 r.out.acct_handle = &lsa_acct_handle;
5014 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenAccount_r(lb, tctx, &r),
5015 "lsa_OpenAccount failed");
5016 torture_assert_ntstatus_ok(tctx, r.out.result,
5017 "Failed to open lsa account");
5021 struct lsa_GetSystemAccessAccount r;
5022 uint32_t access_mask;
5024 torture_comment(tctx, "Testing LSA GetSystemAccessAccount\n");
5026 r.in.handle = &lsa_acct_handle;
5027 r.out.access_mask = &access_mask;
5029 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetSystemAccessAccount_r(lb, tctx, &r),
5030 "lsa_GetSystemAccessAccount failed");
5031 torture_assert_ntstatus_ok(tctx, r.out.result,
5032 "Failed to get lsa system access account");
5036 struct lsa_DeleteObject r;
5038 torture_comment(tctx, "Testing LSA DeleteObject\n");
5040 r.in.handle = &lsa_acct_handle;
5041 r.out.handle = &lsa_acct_handle;
5043 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_DeleteObject_r(lb, tctx, &r),
5044 "lsa_DeleteObject failed");
5045 torture_assert_ntstatus_ok(tctx, r.out.result,
5046 "Failed to delete object");
5050 struct lsa_EnumAccounts r;
5051 uint32_t resume_handle = 0;
5052 struct lsa_SidArray lsa_sid_array;
5054 bool found_sid = false;
5056 torture_comment(tctx, "Testing LSA EnumAccounts\n");
5058 r.in.handle = lsa_handle;
5059 r.in.num_entries = 0x1000;
5060 r.in.resume_handle = &resume_handle;
5061 r.out.sids = &lsa_sid_array;
5062 r.out.resume_handle = &resume_handle;
5064 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(lb, tctx, &r),
5065 "lsa_EnumAccounts failed");
5066 torture_assert_ntstatus_ok(tctx, r.out.result,
5067 "Failed to enum accounts");
5069 for (i=0; i < lsa_sid_array.num_sids; i++) {
5070 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
5075 torture_assert(tctx, !found_sid,
5076 "should not have listed privileged account");
5080 struct lsa_EnumAccountRights r;
5081 struct lsa_RightSet user_rights;
5083 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
5085 r.in.handle = lsa_handle;
5086 r.in.sid = user_sid;
5087 r.out.rights = &user_rights;
5089 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
5090 "lsa_EnumAccountRights failed");
5091 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND,
5092 "Failed to enum rights for account");
5098 static bool test_user_ops(struct dcerpc_pipe *p,
5099 struct torture_context *tctx,
5100 struct policy_handle *user_handle,
5101 struct policy_handle *domain_handle,
5102 const struct dom_sid *domain_sid,
5103 uint32_t base_acct_flags,
5104 const char *base_acct_name, enum torture_samr_choice which_ops,
5105 struct cli_credentials *machine_credentials)
5107 char *password = NULL;
5108 struct samr_QueryUserInfo q;
5109 union samr_UserInfo *info;
5111 struct dcerpc_binding_handle *b = p->binding_handle;
5116 const uint32_t password_fields[] = {
5117 SAMR_FIELD_NT_PASSWORD_PRESENT,
5118 SAMR_FIELD_LM_PASSWORD_PRESENT,
5119 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
5123 status = test_LookupName(b, tctx, domain_handle, base_acct_name, &rid);
5124 if (!NT_STATUS_IS_OK(status)) {
5128 switch (which_ops) {
5129 case TORTURE_SAMR_USER_ATTRIBUTES:
5130 if (!test_QuerySecurity(b, tctx, user_handle)) {
5134 if (!test_QueryUserInfo(b, tctx, user_handle)) {
5138 if (!test_QueryUserInfo2(b, tctx, user_handle)) {
5142 if (!test_SetUserInfo(b, tctx, user_handle, base_acct_flags,
5147 if (!test_GetUserPwInfo(b, tctx, user_handle)) {
5151 if (!test_TestPrivateFunctionsUser(b, tctx, user_handle)) {
5155 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
5159 case TORTURE_SAMR_PASSWORDS:
5160 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
5161 char simple_pass[9];
5162 char *v = generate_random_str(tctx, 1);
5164 ZERO_STRUCT(simple_pass);
5165 memset(simple_pass, *v, sizeof(simple_pass) - 1);
5167 torture_comment(tctx, "Testing machine account password policy rules\n");
5169 /* Workstation trust accounts don't seem to need to honour password quality policy */
5170 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
5174 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
5178 /* reset again, to allow another 'user' password change */
5179 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
5183 /* Try a 'short' password */
5184 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
5188 /* Try a compleatly random password */
5189 if (!test_ChangePasswordRandomBytes(p, tctx, base_acct_name, user_handle, &password)) {
5194 for (i = 0; password_fields[i]; i++) {
5195 if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
5199 /* check it was set right */
5200 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
5205 for (i = 0; password_fields[i]; i++) {
5206 if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
5210 /* check it was set right */
5211 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
5216 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
5220 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
5224 if (!test_SetUserPass_18(p, tctx, user_handle, &password)) {
5228 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
5232 for (i = 0; password_fields[i]; i++) {
5234 if (password_fields[i] == SAMR_FIELD_LM_PASSWORD_PRESENT) {
5235 /* we need to skip as that would break
5236 * the ChangePasswordUser3 verify */
5240 if (!test_SetUserPass_21(p, tctx, user_handle, password_fields[i], &password)) {
5244 /* check it was set right */
5245 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
5250 q.in.user_handle = user_handle;
5254 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
5255 "QueryUserInfo failed");
5256 if (!NT_STATUS_IS_OK(q.out.result)) {
5257 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level %u failed - %s\n",
5258 q.in.level, nt_errstr(q.out.result));
5261 uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
5262 if ((info->info5.acct_flags) != expected_flags) {
5264 if (!torture_setting_bool(tctx, "samba3", false)) {
5265 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
5266 info->info5.acct_flags,
5271 if (info->info5.rid != rid) {
5272 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
5273 info->info5.rid, rid);
5280 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
5282 /* test last password change timestamp behaviour */
5283 torture_assert(tctx, test_SetPassword_pwdlastset(p, tctx, base_acct_flags,
5285 user_handle, &password,
5286 machine_credentials),
5287 "pwdLastSet test failed\n");
5290 case TORTURE_SAMR_PASSWORDS_BADPWDCOUNT:
5292 /* test bad pwd count change behaviour */
5293 torture_assert(tctx, test_Password_badpwdcount_wrap(p, tctx, base_acct_flags,
5296 user_handle, &password,
5297 machine_credentials),
5298 "badPwdCount test failed\n");
5301 case TORTURE_SAMR_PASSWORDS_LOCKOUT:
5303 torture_assert(tctx, test_Password_lockout_wrap(p, tctx, base_acct_flags,
5306 user_handle, &password,
5307 machine_credentials),
5308 "Lockout test failed");
5312 case TORTURE_SAMR_USER_PRIVILEGES: {
5314 struct dcerpc_pipe *lp;
5315 struct policy_handle *lsa_handle;
5316 struct dcerpc_binding_handle *lb;
5318 status = torture_rpc_connection(tctx, &lp, &ndr_table_lsarpc);
5319 torture_assert_ntstatus_ok(tctx, status, "Failed to open LSA pipe");
5320 lb = lp->binding_handle;
5322 if (!test_lsa_OpenPolicy2(lb, tctx, &lsa_handle)) {
5326 if (!test_DeleteUser_with_privs(p, lp, tctx,
5327 domain_handle, lsa_handle, user_handle,
5329 machine_credentials)) {
5333 if (!test_lsa_Close(lb, tctx, lsa_handle)) {
5338 torture_result(tctx, TORTURE_FAIL, "privileged user delete test failed\n");
5343 case TORTURE_SAMR_OTHER:
5344 case TORTURE_SAMR_MANY_ACCOUNTS:
5345 case TORTURE_SAMR_MANY_GROUPS:
5346 case TORTURE_SAMR_MANY_ALIASES:
5347 /* We just need the account to exist */
5353 static bool test_alias_ops(struct dcerpc_binding_handle *b,
5354 struct torture_context *tctx,
5355 struct policy_handle *alias_handle,
5356 const struct dom_sid *domain_sid)
5360 if (!torture_setting_bool(tctx, "samba3", false)) {
5361 if (!test_QuerySecurity(b, tctx, alias_handle)) {
5366 if (!test_QueryAliasInfo(b, tctx, alias_handle)) {
5370 if (!test_SetAliasInfo(b, tctx, alias_handle)) {
5374 if (!test_AddMemberToAlias(b, tctx, alias_handle, domain_sid)) {
5378 if (torture_setting_bool(tctx, "samba3", false) ||
5379 torture_setting_bool(tctx, "samba4", false)) {
5380 torture_comment(tctx, "skipping MultipleMembers Alias tests against Samba\n");
5384 if (!test_AddMultipleMembersToAlias(b, tctx, alias_handle)) {
5392 static bool test_DeleteUser(struct dcerpc_binding_handle *b,
5393 struct torture_context *tctx,
5394 struct policy_handle *user_handle)
5396 struct samr_DeleteUser d;
5397 torture_comment(tctx, "Testing DeleteUser\n");
5399 d.in.user_handle = user_handle;
5400 d.out.user_handle = user_handle;
5402 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, tctx, &d),
5403 "DeleteUser failed");
5404 torture_assert_ntstatus_ok(tctx, d.out.result, "DeleteUser");
5409 bool test_DeleteUser_byname(struct dcerpc_binding_handle *b,
5410 struct torture_context *tctx,
5411 struct policy_handle *handle, const char *name)
5414 struct samr_DeleteUser d;
5415 struct policy_handle user_handle;
5418 status = test_LookupName(b, tctx, handle, name, &rid);
5419 if (!NT_STATUS_IS_OK(status)) {
5423 status = test_OpenUser_byname(b, tctx, handle, name, &user_handle);
5424 if (!NT_STATUS_IS_OK(status)) {
5428 d.in.user_handle = &user_handle;
5429 d.out.user_handle = &user_handle;
5430 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, tctx, &d),
5431 "DeleteUser failed");
5432 if (!NT_STATUS_IS_OK(d.out.result)) {
5433 status = d.out.result;
5440 torture_result(tctx, TORTURE_FAIL, "DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
5445 static bool test_DeleteGroup_byname(struct dcerpc_binding_handle *b,
5446 struct torture_context *tctx,
5447 struct policy_handle *handle, const char *name)
5450 struct samr_OpenGroup r;
5451 struct samr_DeleteDomainGroup d;
5452 struct policy_handle group_handle;
5455 status = test_LookupName(b, tctx, handle, name, &rid);
5456 if (!NT_STATUS_IS_OK(status)) {
5460 r.in.domain_handle = handle;
5461 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5463 r.out.group_handle = &group_handle;
5464 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenGroup_r(b, tctx, &r),
5465 "OpenGroup failed");
5466 if (!NT_STATUS_IS_OK(r.out.result)) {
5467 status = r.out.result;
5471 d.in.group_handle = &group_handle;
5472 d.out.group_handle = &group_handle;
5473 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomainGroup_r(b, tctx, &d),
5474 "DeleteDomainGroup failed");
5475 if (!NT_STATUS_IS_OK(d.out.result)) {
5476 status = d.out.result;
5483 torture_result(tctx, TORTURE_FAIL, "DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
5488 static bool test_DeleteAlias_byname(struct dcerpc_binding_handle *b,
5489 struct torture_context *tctx,
5490 struct policy_handle *domain_handle,
5494 struct samr_OpenAlias r;
5495 struct samr_DeleteDomAlias d;
5496 struct policy_handle alias_handle;
5499 torture_comment(tctx, "Testing DeleteAlias_byname\n");
5501 status = test_LookupName(b, tctx, domain_handle, name, &rid);
5502 if (!NT_STATUS_IS_OK(status)) {
5506 r.in.domain_handle = domain_handle;
5507 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5509 r.out.alias_handle = &alias_handle;
5510 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenAlias_r(b, tctx, &r),
5511 "OpenAlias failed");
5512 if (!NT_STATUS_IS_OK(r.out.result)) {
5513 status = r.out.result;
5517 d.in.alias_handle = &alias_handle;
5518 d.out.alias_handle = &alias_handle;
5519 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomAlias_r(b, tctx, &d),
5520 "DeleteDomAlias failed");
5521 if (!NT_STATUS_IS_OK(d.out.result)) {
5522 status = d.out.result;
5529 torture_result(tctx, TORTURE_FAIL, "DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
5533 static bool test_DeleteAlias(struct dcerpc_binding_handle *b,
5534 struct torture_context *tctx,
5535 struct policy_handle *alias_handle)
5537 struct samr_DeleteDomAlias d;
5540 torture_comment(tctx, "Testing DeleteAlias\n");
5542 d.in.alias_handle = alias_handle;
5543 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 torture_result(tctx, TORTURE_FAIL, "DeleteAlias failed - %s\n", nt_errstr(d.out.result));
5555 static bool test_CreateAlias(struct dcerpc_binding_handle *b,
5556 struct torture_context *tctx,
5557 struct policy_handle *domain_handle,
5558 const char *alias_name,
5559 struct policy_handle *alias_handle,
5560 const struct dom_sid *domain_sid,
5563 struct samr_CreateDomAlias r;
5564 struct lsa_String name;
5568 init_lsa_String(&name, alias_name);
5569 r.in.domain_handle = domain_handle;
5570 r.in.alias_name = &name;
5571 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5572 r.out.alias_handle = alias_handle;
5575 torture_comment(tctx, "Testing CreateAlias (%s)\n", r.in.alias_name->string);
5577 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomAlias_r(b, tctx, &r),
5578 "CreateDomAlias failed");
5580 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5581 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED)) {
5582 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.alias_name->string);
5585 torture_result(tctx, TORTURE_FAIL, "Server should have refused create of '%s', got %s instead\n", r.in.alias_name->string,
5586 nt_errstr(r.out.result));
5591 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ALIAS_EXISTS)) {
5592 if (!test_DeleteAlias_byname(b, tctx, domain_handle, r.in.alias_name->string)) {
5595 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomAlias_r(b, tctx, &r),
5596 "CreateDomAlias failed");
5599 if (!NT_STATUS_IS_OK(r.out.result)) {
5600 torture_result(tctx, TORTURE_FAIL, "CreateAlias failed - %s\n", nt_errstr(r.out.result));
5608 if (!test_alias_ops(b, tctx, alias_handle, domain_sid)) {
5615 static bool test_ChangePassword(struct dcerpc_pipe *p,
5616 struct torture_context *tctx,
5617 const char *acct_name,
5618 struct policy_handle *domain_handle, char **password)
5621 struct dcerpc_binding_handle *b = p->binding_handle;
5627 if (!test_ChangePasswordUser(b, tctx, acct_name, domain_handle, password)) {
5631 if (!test_ChangePasswordUser2(p, tctx, acct_name, password, 0, true)) {
5635 if (!test_OemChangePasswordUser2(p, tctx, acct_name, domain_handle, password)) {
5639 /* test what happens when setting the old password again */
5640 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, *password, 0, true)) {
5645 char simple_pass[9];
5646 char *v = generate_random_str(tctx, 1);
5648 ZERO_STRUCT(simple_pass);
5649 memset(simple_pass, *v, sizeof(simple_pass) - 1);
5651 /* test what happens when picking a simple password */
5652 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, simple_pass, 0, true)) {
5657 /* set samr_SetDomainInfo level 1 with min_length 5 */
5659 struct samr_QueryDomainInfo r;
5660 union samr_DomainInfo *info = NULL;
5661 struct samr_SetDomainInfo s;
5662 uint16_t len_old, len;
5663 uint32_t pwd_prop_old;
5664 int64_t min_pwd_age_old;
5668 r.in.domain_handle = domain_handle;
5672 torture_comment(tctx, "Testing samr_QueryDomainInfo level 1\n");
5673 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &r),
5674 "QueryDomainInfo failed");
5675 if (!NT_STATUS_IS_OK(r.out.result)) {
5679 s.in.domain_handle = domain_handle;
5683 /* remember the old min length, so we can reset it */
5684 len_old = s.in.info->info1.min_password_length;
5685 s.in.info->info1.min_password_length = len;
5686 pwd_prop_old = s.in.info->info1.password_properties;
5687 /* turn off password complexity checks for this test */
5688 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
5690 min_pwd_age_old = s.in.info->info1.min_password_age;
5691 s.in.info->info1.min_password_age = 0;
5693 torture_comment(tctx, "Testing samr_SetDomainInfo level 1\n");
5694 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
5695 "SetDomainInfo failed");
5696 if (!NT_STATUS_IS_OK(s.out.result)) {
5700 torture_comment(tctx, "calling test_ChangePasswordUser3 with too short password\n");
5702 if (!test_ChangePasswordUser3(p, tctx, acct_name, len - 1, password, NULL, 0, true)) {
5706 s.in.info->info1.min_password_length = len_old;
5707 s.in.info->info1.password_properties = pwd_prop_old;
5708 s.in.info->info1.min_password_age = min_pwd_age_old;
5710 torture_comment(tctx, "Testing samr_SetDomainInfo level 1\n");
5711 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
5712 "SetDomainInfo failed");
5713 if (!NT_STATUS_IS_OK(s.out.result)) {
5720 struct samr_OpenUser r;
5721 struct samr_QueryUserInfo q;
5722 union samr_UserInfo *info;
5723 struct samr_LookupNames n;
5724 struct policy_handle user_handle;
5725 struct samr_Ids rids, types;
5727 n.in.domain_handle = domain_handle;
5729 n.in.names = talloc_array(tctx, struct lsa_String, 1);
5730 n.in.names[0].string = acct_name;
5732 n.out.types = &types;
5734 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupNames_r(b, tctx, &n),
5735 "LookupNames failed");
5736 if (!NT_STATUS_IS_OK(n.out.result)) {
5737 torture_result(tctx, TORTURE_FAIL, "LookupNames failed - %s\n", nt_errstr(n.out.result));
5741 r.in.domain_handle = domain_handle;
5742 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5743 r.in.rid = n.out.rids->ids[0];
5744 r.out.user_handle = &user_handle;
5746 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
5748 if (!NT_STATUS_IS_OK(r.out.result)) {
5749 torture_result(tctx, TORTURE_FAIL, "OpenUser(%u) failed - %s\n", n.out.rids->ids[0], nt_errstr(r.out.result));
5753 q.in.user_handle = &user_handle;
5757 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
5758 "QueryUserInfo failed");
5759 if (!NT_STATUS_IS_OK(q.out.result)) {
5760 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo failed - %s\n", nt_errstr(q.out.result));
5764 torture_comment(tctx, "calling test_ChangePasswordUser3 with too early password change\n");
5766 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL,
5767 info->info5.last_password_change, true)) {
5772 /* we change passwords twice - this has the effect of verifying
5773 they were changed correctly for the final call */
5774 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
5778 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
5785 static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
5786 struct policy_handle *domain_handle,
5787 const char *user_name,
5788 struct policy_handle *user_handle_out,
5789 struct dom_sid *domain_sid,
5790 enum torture_samr_choice which_ops,
5791 struct cli_credentials *machine_credentials,
5795 TALLOC_CTX *user_ctx;
5797 struct samr_CreateUser r;
5798 struct samr_QueryUserInfo q;
5799 union samr_UserInfo *info;
5800 struct samr_DeleteUser d;
5803 /* This call creates a 'normal' account - check that it really does */
5804 const uint32_t acct_flags = ACB_NORMAL;
5805 struct lsa_String name;
5807 struct dcerpc_binding_handle *b = p->binding_handle;
5809 struct policy_handle user_handle;
5810 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
5811 init_lsa_String(&name, user_name);
5813 r.in.domain_handle = domain_handle;
5814 r.in.account_name = &name;
5815 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5816 r.out.user_handle = &user_handle;
5819 torture_comment(tctx, "Testing CreateUser(%s)\n", r.in.account_name->string);
5821 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser_r(b, user_ctx, &r),
5822 "CreateUser failed");
5824 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5825 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
5826 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.account_name->string);
5829 torture_result(tctx, TORTURE_FAIL, "Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
5830 nt_errstr(r.out.result));
5835 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_USER_EXISTS)) {
5836 if (!test_DeleteUser_byname(b, tctx, domain_handle, r.in.account_name->string)) {
5837 talloc_free(user_ctx);
5840 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser_r(b, user_ctx, &r),
5841 "CreateUser failed");
5844 if (!NT_STATUS_IS_OK(r.out.result)) {
5845 talloc_free(user_ctx);
5846 torture_result(tctx, TORTURE_FAIL, "CreateUser failed - %s\n", nt_errstr(r.out.result));
5851 if (user_handle_out) {
5852 *user_handle_out = user_handle;
5858 q.in.user_handle = &user_handle;
5862 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, user_ctx, &q),
5863 "QueryUserInfo failed");
5864 if (!NT_STATUS_IS_OK(q.out.result)) {
5865 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level %u failed - %s\n",
5866 q.in.level, nt_errstr(q.out.result));
5869 if ((info->info16.acct_flags & acct_flags) != acct_flags) {
5870 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
5871 info->info16.acct_flags,
5877 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
5878 domain_sid, acct_flags, name.string, which_ops,
5879 machine_credentials)) {
5883 if (user_handle_out) {
5884 *user_handle_out = user_handle;
5886 torture_comment(tctx, "Testing DeleteUser (createuser test)\n");
5888 d.in.user_handle = &user_handle;
5889 d.out.user_handle = &user_handle;
5891 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, user_ctx, &d),
5892 "DeleteUser failed");
5893 if (!NT_STATUS_IS_OK(d.out.result)) {
5894 torture_result(tctx, TORTURE_FAIL, "DeleteUser failed - %s\n", nt_errstr(d.out.result));
5901 talloc_free(user_ctx);
5907 static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
5908 struct policy_handle *domain_handle,
5909 struct dom_sid *domain_sid,
5910 enum torture_samr_choice which_ops,
5911 struct cli_credentials *machine_credentials)
5913 struct samr_CreateUser2 r;
5914 struct samr_QueryUserInfo q;
5915 union samr_UserInfo *info;
5916 struct samr_DeleteUser d;
5917 struct policy_handle user_handle;
5919 struct lsa_String name;
5922 struct dcerpc_binding_handle *b = p->binding_handle;
5925 uint32_t acct_flags;
5926 const char *account_name;
5928 } account_types[] = {
5929 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
5930 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5931 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5932 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
5933 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5934 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5935 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
5936 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5937 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5938 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_ACCESS_DENIED },
5939 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
5940 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
5941 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5942 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5943 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
5946 for (i = 0; account_types[i].account_name; i++) {
5947 TALLOC_CTX *user_ctx;
5948 uint32_t acct_flags = account_types[i].acct_flags;
5949 uint32_t access_granted;
5950 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
5951 init_lsa_String(&name, account_types[i].account_name);
5953 r.in.domain_handle = domain_handle;
5954 r.in.account_name = &name;
5955 r.in.acct_flags = acct_flags;
5956 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5957 r.out.user_handle = &user_handle;
5958 r.out.access_granted = &access_granted;
5961 torture_comment(tctx, "Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
5963 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser2_r(b, user_ctx, &r),
5964 "CreateUser2 failed");
5966 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5967 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
5968 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.account_name->string);
5971 torture_result(tctx, TORTURE_FAIL, "Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
5972 nt_errstr(r.out.result));
5978 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_USER_EXISTS)) {
5979 if (!test_DeleteUser_byname(b, tctx, domain_handle, r.in.account_name->string)) {
5980 talloc_free(user_ctx);
5984 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser2_r(b, user_ctx, &r),
5985 "CreateUser2 failed");
5988 if (!NT_STATUS_EQUAL(r.out.result, account_types[i].nt_status)) {
5989 torture_result(tctx, TORTURE_FAIL, "CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
5990 nt_errstr(r.out.result), nt_errstr(account_types[i].nt_status));
5994 if (NT_STATUS_IS_OK(r.out.result)) {
5995 q.in.user_handle = &user_handle;
5999 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, user_ctx, &q),
6000 "QueryUserInfo failed");
6001 if (!NT_STATUS_IS_OK(q.out.result)) {
6002 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level %u failed - %s\n",
6003 q.in.level, nt_errstr(q.out.result));
6006 uint32_t expected_flags = (acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
6007 if (acct_flags == ACB_NORMAL) {
6008 expected_flags |= ACB_PW_EXPIRED;
6010 if ((info->info5.acct_flags) != expected_flags) {
6011 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
6012 info->info5.acct_flags,
6016 switch (acct_flags) {
6018 if (info->info5.primary_gid != DOMAIN_RID_DCS) {
6019 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level 5: DC should have had Primary Group %d, got %d\n",
6020 DOMAIN_RID_DCS, info->info5.primary_gid);
6025 if (info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
6026 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
6027 DOMAIN_RID_DOMAIN_MEMBERS, info->info5.primary_gid);
6032 if (info->info5.primary_gid != DOMAIN_RID_USERS) {
6033 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level 5: Users should have had Primary Group %d, got %d\n",
6034 DOMAIN_RID_USERS, info->info5.primary_gid);
6041 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
6042 domain_sid, acct_flags, name.string, which_ops,
6043 machine_credentials)) {
6047 if (!ndr_policy_handle_empty(&user_handle)) {
6048 torture_comment(tctx, "Testing DeleteUser (createuser2 test)\n");
6050 d.in.user_handle = &user_handle;
6051 d.out.user_handle = &user_handle;
6053 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, user_ctx, &d),
6054 "DeleteUser failed");
6055 if (!NT_STATUS_IS_OK(d.out.result)) {
6056 torture_result(tctx, TORTURE_FAIL, "DeleteUser failed - %s\n", nt_errstr(d.out.result));
6061 talloc_free(user_ctx);
6067 static bool test_QueryAliasInfo(struct dcerpc_binding_handle *b,
6068 struct torture_context *tctx,
6069 struct policy_handle *handle)
6071 struct samr_QueryAliasInfo r;
6072 union samr_AliasInfo *info;
6073 uint16_t levels[] = {1, 2, 3};
6077 for (i=0;i<ARRAY_SIZE(levels);i++) {
6078 torture_comment(tctx, "Testing QueryAliasInfo level %u\n", levels[i]);
6080 r.in.alias_handle = handle;
6081 r.in.level = levels[i];
6084 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryAliasInfo_r(b, tctx, &r),
6085 "QueryAliasInfo failed");
6086 if (!NT_STATUS_IS_OK(r.out.result)) {
6087 torture_result(tctx, TORTURE_FAIL, "QueryAliasInfo level %u failed - %s\n",
6088 levels[i], nt_errstr(r.out.result));
6096 static bool test_QueryGroupInfo(struct dcerpc_binding_handle *b,
6097 struct torture_context *tctx,
6098 struct policy_handle *handle)
6100 struct samr_QueryGroupInfo r;
6101 union samr_GroupInfo *info;
6102 uint16_t levels[] = {1, 2, 3, 4, 5};
6106 for (i=0;i<ARRAY_SIZE(levels);i++) {
6107 torture_comment(tctx, "Testing QueryGroupInfo level %u\n", levels[i]);
6109 r.in.group_handle = handle;
6110 r.in.level = levels[i];
6113 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupInfo_r(b, tctx, &r),
6114 "QueryGroupInfo failed");
6115 if (!NT_STATUS_IS_OK(r.out.result)) {
6116 torture_result(tctx, TORTURE_FAIL, "QueryGroupInfo level %u failed - %s\n",
6117 levels[i], nt_errstr(r.out.result));
6125 static bool test_QueryGroupMember(struct dcerpc_binding_handle *b,
6126 struct torture_context *tctx,
6127 struct policy_handle *handle)
6129 struct samr_QueryGroupMember r;
6130 struct samr_RidAttrArray *rids = NULL;
6133 torture_comment(tctx, "Testing QueryGroupMember\n");
6135 r.in.group_handle = handle;
6138 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupMember_r(b, tctx, &r),
6139 "QueryGroupMember failed");
6140 if (!NT_STATUS_IS_OK(r.out.result)) {
6141 torture_result(tctx, TORTURE_FAIL, "QueryGroupMember failed - %s\n", nt_errstr(r.out.result));
6149 static bool test_SetGroupInfo(struct dcerpc_binding_handle *b,
6150 struct torture_context *tctx,
6151 struct policy_handle *handle)
6153 struct samr_QueryGroupInfo r;
6154 union samr_GroupInfo *info;
6155 struct samr_SetGroupInfo s;
6156 uint16_t levels[] = {1, 2, 3, 4};
6157 uint16_t set_ok[] = {0, 1, 1, 1};
6161 for (i=0;i<ARRAY_SIZE(levels);i++) {
6162 torture_comment(tctx, "Testing QueryGroupInfo level %u\n", levels[i]);
6164 r.in.group_handle = handle;
6165 r.in.level = levels[i];
6168 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupInfo_r(b, tctx, &r),
6169 "QueryGroupInfo failed");
6170 if (!NT_STATUS_IS_OK(r.out.result)) {
6171 torture_result(tctx, TORTURE_FAIL, "QueryGroupInfo level %u failed - %s\n",
6172 levels[i], nt_errstr(r.out.result));
6176 torture_comment(tctx, "Testing SetGroupInfo level %u\n", levels[i]);
6178 s.in.group_handle = handle;
6179 s.in.level = levels[i];
6180 s.in.info = *r.out.info;
6183 /* disabled this, as it changes the name only from the point of view of samr,
6184 but leaves the name from the point of view of w2k3 internals (and ldap). This means
6185 the name is still reserved, so creating the old name fails, but deleting by the old name
6187 if (s.in.level == 2) {
6188 init_lsa_String(&s.in.info->string, "NewName");
6192 if (s.in.level == 4) {
6193 init_lsa_String(&s.in.info->description, "test description");
6196 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetGroupInfo_r(b, tctx, &s),
6197 "SetGroupInfo failed");
6199 if (!NT_STATUS_IS_OK(s.out.result)) {
6200 torture_result(tctx, TORTURE_FAIL, "SetGroupInfo level %u failed - %s\n",
6201 r.in.level, nt_errstr(s.out.result));
6206 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, s.out.result)) {
6207 torture_result(tctx, TORTURE_FAIL, "SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
6208 r.in.level, nt_errstr(s.out.result));
6218 static bool test_QueryUserInfo(struct dcerpc_binding_handle *b,
6219 struct torture_context *tctx,
6220 struct policy_handle *handle)
6222 struct samr_QueryUserInfo r;
6223 union samr_UserInfo *info;
6224 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
6225 11, 12, 13, 14, 16, 17, 20, 21};
6229 for (i=0;i<ARRAY_SIZE(levels);i++) {
6230 torture_comment(tctx, "Testing QueryUserInfo level %u\n", levels[i]);
6232 r.in.user_handle = handle;
6233 r.in.level = levels[i];
6236 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
6237 "QueryUserInfo failed");
6238 if (!NT_STATUS_IS_OK(r.out.result)) {
6239 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level %u failed - %s\n",
6240 levels[i], nt_errstr(r.out.result));
6248 static bool test_QueryUserInfo2(struct dcerpc_binding_handle *b,
6249 struct torture_context *tctx,
6250 struct policy_handle *handle)
6252 struct samr_QueryUserInfo2 r;
6253 union samr_UserInfo *info;
6254 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
6255 11, 12, 13, 14, 16, 17, 20, 21};
6259 for (i=0;i<ARRAY_SIZE(levels);i++) {
6260 torture_comment(tctx, "Testing QueryUserInfo2 level %u\n", levels[i]);
6262 r.in.user_handle = handle;
6263 r.in.level = levels[i];
6266 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo2_r(b, tctx, &r),
6267 "QueryUserInfo2 failed");
6268 if (!NT_STATUS_IS_OK(r.out.result)) {
6269 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo2 level %u failed - %s\n",
6270 levels[i], nt_errstr(r.out.result));
6278 static bool test_OpenUser(struct dcerpc_binding_handle *b,
6279 struct torture_context *tctx,
6280 struct policy_handle *handle, uint32_t rid)
6282 struct samr_OpenUser r;
6283 struct policy_handle user_handle;
6286 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
6288 r.in.domain_handle = handle;
6289 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6291 r.out.user_handle = &user_handle;
6293 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
6295 if (!NT_STATUS_IS_OK(r.out.result)) {
6296 torture_result(tctx, TORTURE_FAIL, "OpenUser(%u) failed - %s\n", rid, nt_errstr(r.out.result));
6300 if (!test_QuerySecurity(b, tctx, &user_handle)) {
6304 if (!test_QueryUserInfo(b, tctx, &user_handle)) {
6308 if (!test_QueryUserInfo2(b, tctx, &user_handle)) {
6312 if (!test_GetUserPwInfo(b, tctx, &user_handle)) {
6316 if (!test_GetGroupsForUser(b, tctx, &user_handle)) {
6320 if (!test_samr_handle_Close(b, tctx, &user_handle)) {
6327 static bool test_OpenGroup(struct dcerpc_binding_handle *b,
6328 struct torture_context *tctx,
6329 struct policy_handle *handle, uint32_t rid)
6331 struct samr_OpenGroup r;
6332 struct policy_handle group_handle;
6335 torture_comment(tctx, "Testing OpenGroup(%u)\n", rid);
6337 r.in.domain_handle = handle;
6338 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6340 r.out.group_handle = &group_handle;
6342 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenGroup_r(b, tctx, &r),
6343 "OpenGroup failed");
6344 if (!NT_STATUS_IS_OK(r.out.result)) {
6345 torture_result(tctx, TORTURE_FAIL, "OpenGroup(%u) failed - %s\n", rid, nt_errstr(r.out.result));
6349 if (!torture_setting_bool(tctx, "samba3", false)) {
6350 if (!test_QuerySecurity(b, tctx, &group_handle)) {
6355 if (!test_QueryGroupInfo(b, tctx, &group_handle)) {
6359 if (!test_QueryGroupMember(b, tctx, &group_handle)) {
6363 if (!test_samr_handle_Close(b, tctx, &group_handle)) {
6370 static bool test_OpenAlias(struct dcerpc_binding_handle *b,
6371 struct torture_context *tctx,
6372 struct policy_handle *handle, uint32_t rid)
6374 struct samr_OpenAlias r;
6375 struct policy_handle alias_handle;
6378 torture_comment(tctx, "Testing OpenAlias(%u)\n", rid);
6380 r.in.domain_handle = handle;
6381 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6383 r.out.alias_handle = &alias_handle;
6385 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenAlias_r(b, tctx, &r),
6386 "OpenAlias failed");
6387 if (!NT_STATUS_IS_OK(r.out.result)) {
6388 torture_result(tctx, TORTURE_FAIL, "OpenAlias(%u) failed - %s\n", rid, nt_errstr(r.out.result));
6392 if (!torture_setting_bool(tctx, "samba3", false)) {
6393 if (!test_QuerySecurity(b, tctx, &alias_handle)) {
6398 if (!test_QueryAliasInfo(b, tctx, &alias_handle)) {
6402 if (!test_GetMembersInAlias(b, tctx, &alias_handle)) {
6406 if (!test_samr_handle_Close(b, tctx, &alias_handle)) {
6413 static bool check_mask(struct dcerpc_binding_handle *b,
6414 struct torture_context *tctx,
6415 struct policy_handle *handle, uint32_t rid,
6416 uint32_t acct_flag_mask)
6418 struct samr_OpenUser r;
6419 struct samr_QueryUserInfo q;
6420 union samr_UserInfo *info;
6421 struct policy_handle user_handle;
6424 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
6426 r.in.domain_handle = handle;
6427 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6429 r.out.user_handle = &user_handle;
6431 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
6433 if (!NT_STATUS_IS_OK(r.out.result)) {
6434 torture_result(tctx, TORTURE_FAIL, "OpenUser(%u) failed - %s\n", rid, nt_errstr(r.out.result));
6438 q.in.user_handle = &user_handle;
6442 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
6443 "QueryUserInfo failed");
6444 if (!NT_STATUS_IS_OK(q.out.result)) {
6445 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level 16 failed - %s\n",
6446 nt_errstr(q.out.result));
6449 if ((acct_flag_mask & info->info16.acct_flags) == 0) {
6450 torture_result(tctx, TORTURE_FAIL, "Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
6451 acct_flag_mask, info->info16.acct_flags, rid);
6456 if (!test_samr_handle_Close(b, tctx, &user_handle)) {
6463 static bool test_EnumDomainUsers_all(struct dcerpc_binding_handle *b,
6464 struct torture_context *tctx,
6465 struct policy_handle *handle)
6467 struct samr_EnumDomainUsers r;
6468 uint32_t mask, resume_handle=0;
6471 struct samr_LookupNames n;
6472 struct samr_LookupRids lr ;
6473 struct lsa_Strings names;
6474 struct samr_Ids rids, types;
6475 struct samr_SamArray *sam = NULL;
6476 uint32_t num_entries = 0;
6478 uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
6479 ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
6480 ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
6483 torture_comment(tctx, "Testing EnumDomainUsers\n");
6485 for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
6486 r.in.domain_handle = handle;
6487 r.in.resume_handle = &resume_handle;
6488 r.in.acct_flags = mask = masks[mask_idx];
6489 r.in.max_size = (uint32_t)-1;
6490 r.out.resume_handle = &resume_handle;
6491 r.out.num_entries = &num_entries;
6494 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainUsers_r(b, tctx, &r),
6495 "EnumDomainUsers failed");
6496 if (!NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) &&
6497 !NT_STATUS_IS_OK(r.out.result)) {
6498 torture_result(tctx, TORTURE_FAIL, "EnumDomainUsers failed - %s\n", nt_errstr(r.out.result));
6502 torture_assert(tctx, sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
6504 if (sam->count == 0) {
6508 for (i=0;i<sam->count;i++) {
6510 if (!check_mask(b, tctx, handle, sam->entries[i].idx, mask)) {
6513 } else if (!test_OpenUser(b, tctx, handle, sam->entries[i].idx)) {
6519 torture_comment(tctx, "Testing LookupNames\n");
6520 n.in.domain_handle = handle;
6521 n.in.num_names = sam->count;
6522 n.in.names = talloc_array(tctx, struct lsa_String, sam->count);
6524 n.out.types = &types;
6525 for (i=0;i<sam->count;i++) {
6526 n.in.names[i].string = sam->entries[i].name.string;
6528 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupNames_r(b, tctx, &n),
6529 "LookupNames failed");
6530 if (!NT_STATUS_IS_OK(n.out.result)) {
6531 torture_result(tctx, TORTURE_FAIL, "LookupNames failed - %s\n", nt_errstr(n.out.result));
6536 torture_comment(tctx, "Testing LookupRids\n");
6537 lr.in.domain_handle = handle;
6538 lr.in.num_rids = sam->count;
6539 lr.in.rids = talloc_array(tctx, uint32_t, sam->count);
6540 lr.out.names = &names;
6541 lr.out.types = &types;
6542 for (i=0;i<sam->count;i++) {
6543 lr.in.rids[i] = sam->entries[i].idx;
6545 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupRids_r(b, tctx, &lr),
6546 "LookupRids failed");
6547 torture_assert_ntstatus_ok(tctx, lr.out.result, "LookupRids");
6553 try blasting the server with a bunch of sync requests
6555 static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, struct torture_context *tctx,
6556 struct policy_handle *handle)
6558 struct samr_EnumDomainUsers r;
6559 uint32_t resume_handle=0;
6561 #define ASYNC_COUNT 100
6562 struct tevent_req *req[ASYNC_COUNT];
6564 if (!torture_setting_bool(tctx, "dangerous", false)) {
6565 torture_skip(tctx, "samr async test disabled - enable dangerous tests to use\n");
6568 torture_comment(tctx, "Testing EnumDomainUsers_async\n");
6570 r.in.domain_handle = handle;
6571 r.in.resume_handle = &resume_handle;
6572 r.in.acct_flags = 0;
6573 r.in.max_size = (uint32_t)-1;
6574 r.out.resume_handle = &resume_handle;
6576 for (i=0;i<ASYNC_COUNT;i++) {
6577 req[i] = dcerpc_samr_EnumDomainUsers_r_send(tctx, tctx->ev, p->binding_handle, &r);
6580 for (i=0;i<ASYNC_COUNT;i++) {
6581 tevent_req_poll(req[i], tctx->ev);
6582 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainUsers_r_recv(req[i], tctx),
6583 talloc_asprintf(tctx, "EnumDomainUsers[%d] failed - %s\n",
6584 i, nt_errstr(r.out.result)));
6587 torture_comment(tctx, "%d async requests OK\n", i);
6592 static bool test_EnumDomainGroups_all(struct dcerpc_binding_handle *b,
6593 struct torture_context *tctx,
6594 struct policy_handle *handle)
6596 struct samr_EnumDomainGroups r;
6597 uint32_t resume_handle=0;
6598 struct samr_SamArray *sam = NULL;
6599 uint32_t num_entries = 0;
6602 bool universal_group_found = false;
6604 torture_comment(tctx, "Testing EnumDomainGroups\n");
6606 r.in.domain_handle = handle;
6607 r.in.resume_handle = &resume_handle;
6608 r.in.max_size = (uint32_t)-1;
6609 r.out.resume_handle = &resume_handle;
6610 r.out.num_entries = &num_entries;
6613 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainGroups_r(b, tctx, &r),
6614 "EnumDomainGroups failed");
6615 if (!NT_STATUS_IS_OK(r.out.result)) {
6616 torture_result(tctx, TORTURE_FAIL, "EnumDomainGroups failed - %s\n", nt_errstr(r.out.result));
6624 for (i=0;i<sam->count;i++) {
6625 if (!test_OpenGroup(b, tctx, handle, sam->entries[i].idx)) {
6628 if ((ret == true) && (strcasecmp(sam->entries[i].name.string,
6629 "Enterprise Admins") == 0)) {
6630 universal_group_found = true;
6634 /* when we are running this on s4 we should get back at least the
6635 * "Enterprise Admins" universal group. If we don't get a group entry
6636 * at all we probably are performing the test on the builtin domain.
6637 * So ignore this case. */
6638 if (torture_setting_bool(tctx, "samba4", false)) {
6639 if ((sam->count > 0) && (!universal_group_found)) {
6647 static bool test_EnumDomainAliases_all(struct dcerpc_binding_handle *b,
6648 struct torture_context *tctx,
6649 struct policy_handle *handle)
6651 struct samr_EnumDomainAliases r;
6652 uint32_t resume_handle=0;
6653 struct samr_SamArray *sam = NULL;
6654 uint32_t num_entries = 0;
6658 torture_comment(tctx, "Testing EnumDomainAliases\n");
6660 r.in.domain_handle = handle;
6661 r.in.resume_handle = &resume_handle;
6662 r.in.max_size = (uint32_t)-1;
6664 r.out.num_entries = &num_entries;
6665 r.out.resume_handle = &resume_handle;
6667 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainAliases_r(b, tctx, &r),
6668 "EnumDomainAliases failed");
6669 if (!NT_STATUS_IS_OK(r.out.result)) {
6670 torture_result(tctx, TORTURE_FAIL, "EnumDomainAliases failed - %s\n", nt_errstr(r.out.result));
6678 for (i=0;i<sam->count;i++) {
6679 if (!test_OpenAlias(b, tctx, handle, sam->entries[i].idx)) {
6687 static bool test_GetDisplayEnumerationIndex(struct dcerpc_binding_handle *b,
6688 struct torture_context *tctx,
6689 struct policy_handle *handle)
6691 struct samr_GetDisplayEnumerationIndex r;
6693 uint16_t levels[] = {1, 2, 3, 4, 5};
6694 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
6695 struct lsa_String name;
6699 for (i=0;i<ARRAY_SIZE(levels);i++) {
6700 torture_comment(tctx, "Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
6702 init_lsa_String(&name, TEST_ACCOUNT_NAME);
6704 r.in.domain_handle = handle;
6705 r.in.level = levels[i];
6709 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex_r(b, tctx, &r),
6710 "GetDisplayEnumerationIndex failed");
6713 !NT_STATUS_IS_OK(r.out.result) &&
6714 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
6715 torture_result(tctx, TORTURE_FAIL, "GetDisplayEnumerationIndex level %u failed - %s\n",
6716 levels[i], nt_errstr(r.out.result));
6720 init_lsa_String(&name, "zzzzzzzz");
6722 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex_r(b, tctx, &r),
6723 "GetDisplayEnumerationIndex failed");
6725 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
6726 torture_result(tctx, TORTURE_FAIL, "GetDisplayEnumerationIndex level %u failed - %s\n",
6727 levels[i], nt_errstr(r.out.result));
6735 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_binding_handle *b,
6736 struct torture_context *tctx,
6737 struct policy_handle *handle)
6739 struct samr_GetDisplayEnumerationIndex2 r;
6741 uint16_t levels[] = {1, 2, 3, 4, 5};
6742 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
6743 struct lsa_String name;
6747 for (i=0;i<ARRAY_SIZE(levels);i++) {
6748 torture_comment(tctx, "Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
6750 init_lsa_String(&name, TEST_ACCOUNT_NAME);
6752 r.in.domain_handle = handle;
6753 r.in.level = levels[i];
6757 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex2_r(b, tctx, &r),
6758 "GetDisplayEnumerationIndex2 failed");
6760 !NT_STATUS_IS_OK(r.out.result) &&
6761 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
6762 torture_result(tctx, TORTURE_FAIL, "GetDisplayEnumerationIndex2 level %u failed - %s\n",
6763 levels[i], nt_errstr(r.out.result));
6767 init_lsa_String(&name, "zzzzzzzz");
6769 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex2_r(b, tctx, &r),
6770 "GetDisplayEnumerationIndex2 failed");
6771 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
6772 torture_result(tctx, TORTURE_FAIL, "GetDisplayEnumerationIndex2 level %u failed - %s\n",
6773 levels[i], nt_errstr(r.out.result));
6781 #define STRING_EQUAL_QUERY(s1, s2, user) \
6782 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
6783 /* odd, but valid */ \
6784 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
6785 torture_result(tctx, TORTURE_FAIL, "%s mismatch for %s: %s != %s (%s)\n", \
6786 #s1, user.string, s1.string, s2.string, __location__); \
6789 #define INT_EQUAL_QUERY(s1, s2, user) \
6791 torture_result(tctx, TORTURE_FAIL, "%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
6792 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
6796 static bool test_each_DisplayInfo_user(struct dcerpc_binding_handle *b,
6797 struct torture_context *tctx,
6798 struct samr_QueryDisplayInfo *querydisplayinfo,
6799 bool *seen_testuser)
6801 struct samr_OpenUser r;
6802 struct samr_QueryUserInfo q;
6803 union samr_UserInfo *info;
6804 struct policy_handle user_handle;
6806 r.in.domain_handle = querydisplayinfo->in.domain_handle;
6807 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6808 for (i = 0; ; i++) {
6809 switch (querydisplayinfo->in.level) {
6811 if (i >= querydisplayinfo->out.info->info1.count) {
6814 r.in.rid = querydisplayinfo->out.info->info1.entries[i].rid;
6817 if (i >= querydisplayinfo->out.info->info2.count) {
6820 r.in.rid = querydisplayinfo->out.info->info2.entries[i].rid;
6826 /* Not interested in validating just the account name */
6830 r.out.user_handle = &user_handle;
6832 switch (querydisplayinfo->in.level) {
6835 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
6837 if (!NT_STATUS_IS_OK(r.out.result)) {
6838 torture_result(tctx, TORTURE_FAIL, "OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(r.out.result));
6843 q.in.user_handle = &user_handle;
6846 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
6847 "QueryUserInfo failed");
6848 if (!NT_STATUS_IS_OK(r.out.result)) {
6849 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(r.out.result));
6853 switch (querydisplayinfo->in.level) {
6855 if (seen_testuser && strcmp(info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
6856 *seen_testuser = true;
6858 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].full_name,
6859 info->info21.full_name, info->info21.account_name);
6860 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].account_name,
6861 info->info21.account_name, info->info21.account_name);
6862 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].description,
6863 info->info21.description, info->info21.account_name);
6864 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].rid,
6865 info->info21.rid, info->info21.account_name);
6866 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].acct_flags,
6867 info->info21.acct_flags, info->info21.account_name);
6871 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].account_name,
6872 info->info21.account_name, info->info21.account_name);
6873 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].description,
6874 info->info21.description, info->info21.account_name);
6875 INT_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].rid,
6876 info->info21.rid, info->info21.account_name);
6877 INT_EQUAL_QUERY((querydisplayinfo->out.info->info2.entries[i].acct_flags & ~ACB_NORMAL),
6878 info->info21.acct_flags, info->info21.account_name);
6880 if (!(querydisplayinfo->out.info->info2.entries[i].acct_flags & ACB_NORMAL)) {
6881 torture_result(tctx, TORTURE_FAIL, "Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
6882 info->info21.account_name.string);
6885 if (!(info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
6886 torture_result(tctx, TORTURE_FAIL, "Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
6887 info->info21.account_name.string,
6888 querydisplayinfo->out.info->info2.entries[i].acct_flags,
6889 info->info21.acct_flags);
6896 if (!test_samr_handle_Close(b, tctx, &user_handle)) {
6903 static bool test_QueryDisplayInfo(struct dcerpc_binding_handle *b,
6904 struct torture_context *tctx,
6905 struct policy_handle *handle)
6907 struct samr_QueryDisplayInfo r;
6908 struct samr_QueryDomainInfo dom_info;
6909 union samr_DomainInfo *info = NULL;
6911 uint16_t levels[] = {1, 2, 3, 4, 5};
6913 bool seen_testuser = false;
6914 uint32_t total_size;
6915 uint32_t returned_size;
6916 union samr_DispInfo disp_info;
6919 for (i=0;i<ARRAY_SIZE(levels);i++) {
6920 torture_comment(tctx, "Testing QueryDisplayInfo level %u\n", levels[i]);
6923 r.out.result = STATUS_MORE_ENTRIES;
6924 while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES)) {
6925 r.in.domain_handle = handle;
6926 r.in.level = levels[i];
6927 r.in.max_entries = 2;
6928 r.in.buf_size = (uint32_t)-1;
6929 r.out.total_size = &total_size;
6930 r.out.returned_size = &returned_size;
6931 r.out.info = &disp_info;
6933 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &r),
6934 "QueryDisplayInfo failed");
6935 if (!NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(r.out.result)) {
6936 torture_result(tctx, TORTURE_FAIL, "QueryDisplayInfo level %u failed - %s\n",
6937 levels[i], nt_errstr(r.out.result));
6940 switch (r.in.level) {
6942 if (!test_each_DisplayInfo_user(b, tctx, &r, &seen_testuser)) {
6945 r.in.start_idx += r.out.info->info1.count;
6948 if (!test_each_DisplayInfo_user(b, tctx, &r, NULL)) {
6951 r.in.start_idx += r.out.info->info2.count;
6954 r.in.start_idx += r.out.info->info3.count;
6957 r.in.start_idx += r.out.info->info4.count;
6960 r.in.start_idx += r.out.info->info5.count;
6964 dom_info.in.domain_handle = handle;
6965 dom_info.in.level = 2;
6966 dom_info.out.info = &info;
6968 /* Check number of users returned is correct */
6969 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &dom_info),
6970 "QueryDomainInfo failed");
6971 if (!NT_STATUS_IS_OK(dom_info.out.result)) {
6972 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo level %u failed - %s\n",
6973 r.in.level, nt_errstr(dom_info.out.result));
6977 switch (r.in.level) {
6980 if (info->general.num_users < r.in.start_idx) {
6981 /* On AD deployments this numbers don't match
6982 * since QueryDisplayInfo returns universal and
6983 * global groups, QueryDomainInfo only global
6985 if (torture_setting_bool(tctx, "samba3", false)) {
6986 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
6987 r.in.start_idx, info->general.num_groups,
6988 info->general.domain_name.string);
6992 if (!seen_testuser) {
6993 struct policy_handle user_handle;
6994 if (NT_STATUS_IS_OK(test_OpenUser_byname(b, tctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
6995 torture_result(tctx, TORTURE_FAIL, "Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
6996 info->general.domain_name.string);
6998 test_samr_handle_Close(b, tctx, &user_handle);
7004 if (info->general.num_groups != r.in.start_idx) {
7005 /* On AD deployments this numbers don't match
7006 * since QueryDisplayInfo returns universal and
7007 * global groups, QueryDomainInfo only global
7009 if (torture_setting_bool(tctx, "samba3", false)) {
7010 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
7011 r.in.start_idx, info->general.num_groups,
7012 info->general.domain_name.string);
7025 static bool test_QueryDisplayInfo2(struct dcerpc_binding_handle *b,
7026 struct torture_context *tctx,
7027 struct policy_handle *handle)
7029 struct samr_QueryDisplayInfo2 r;
7031 uint16_t levels[] = {1, 2, 3, 4, 5};
7033 uint32_t total_size;
7034 uint32_t returned_size;
7035 union samr_DispInfo info;
7037 for (i=0;i<ARRAY_SIZE(levels);i++) {
7038 torture_comment(tctx, "Testing QueryDisplayInfo2 level %u\n", levels[i]);
7040 r.in.domain_handle = handle;
7041 r.in.level = levels[i];
7043 r.in.max_entries = 1000;
7044 r.in.buf_size = (uint32_t)-1;
7045 r.out.total_size = &total_size;
7046 r.out.returned_size = &returned_size;
7049 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo2_r(b, tctx, &r),
7050 "QueryDisplayInfo2 failed");
7051 if (!NT_STATUS_IS_OK(r.out.result)) {
7052 torture_result(tctx, TORTURE_FAIL, "QueryDisplayInfo2 level %u failed - %s\n",
7053 levels[i], nt_errstr(r.out.result));
7061 static bool test_QueryDisplayInfo3(struct dcerpc_binding_handle *b,
7062 struct torture_context *tctx,
7063 struct policy_handle *handle)
7065 struct samr_QueryDisplayInfo3 r;
7067 uint16_t levels[] = {1, 2, 3, 4, 5};
7069 uint32_t total_size;
7070 uint32_t returned_size;
7071 union samr_DispInfo info;
7073 for (i=0;i<ARRAY_SIZE(levels);i++) {
7074 torture_comment(tctx, "Testing QueryDisplayInfo3 level %u\n", levels[i]);
7076 r.in.domain_handle = handle;
7077 r.in.level = levels[i];
7079 r.in.max_entries = 1000;
7080 r.in.buf_size = (uint32_t)-1;
7081 r.out.total_size = &total_size;
7082 r.out.returned_size = &returned_size;
7085 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo3_r(b, tctx, &r),
7086 "QueryDisplayInfo3 failed");
7087 if (!NT_STATUS_IS_OK(r.out.result)) {
7088 torture_result(tctx, TORTURE_FAIL, "QueryDisplayInfo3 level %u failed - %s\n",
7089 levels[i], nt_errstr(r.out.result));
7098 static bool test_QueryDisplayInfo_continue(struct dcerpc_binding_handle *b,
7099 struct torture_context *tctx,
7100 struct policy_handle *handle)
7102 struct samr_QueryDisplayInfo r;
7104 uint32_t total_size;
7105 uint32_t returned_size;
7106 union samr_DispInfo info;
7108 torture_comment(tctx, "Testing QueryDisplayInfo continuation\n");
7110 r.in.domain_handle = handle;
7113 r.in.max_entries = 1;
7114 r.in.buf_size = (uint32_t)-1;
7115 r.out.total_size = &total_size;
7116 r.out.returned_size = &returned_size;
7120 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &r),
7121 "QueryDisplayInfo failed");
7122 if (NT_STATUS_IS_OK(r.out.result) && *r.out.returned_size != 0) {
7123 if (r.out.info->info1.entries[0].idx != r.in.start_idx + 1) {
7124 torture_result(tctx, TORTURE_FAIL, "expected idx %d but got %d\n",
7126 r.out.info->info1.entries[0].idx);
7130 if (!NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) &&
7131 !NT_STATUS_IS_OK(r.out.result)) {
7132 torture_result(tctx, TORTURE_FAIL, "QueryDisplayInfo level %u failed - %s\n",
7133 r.in.level, nt_errstr(r.out.result));
7138 } while ((NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) ||
7139 NT_STATUS_IS_OK(r.out.result)) &&
7140 *r.out.returned_size != 0);
7145 static bool test_QueryDomainInfo(struct dcerpc_pipe *p,
7146 struct torture_context *tctx,
7147 struct policy_handle *handle)
7149 struct samr_QueryDomainInfo r;
7150 union samr_DomainInfo *info = NULL;
7151 struct samr_SetDomainInfo s;
7152 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
7153 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
7156 struct dcerpc_binding_handle *b = p->binding_handle;
7157 const char *domain_comment = talloc_asprintf(tctx,
7158 "Tortured by Samba4 RPC-SAMR: %s",
7159 timestring(tctx, time(NULL)));
7161 s.in.domain_handle = handle;
7163 s.in.info = talloc(tctx, union samr_DomainInfo);
7165 s.in.info->oem.oem_information.string = domain_comment;
7166 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
7167 "SetDomainInfo failed");
7168 if (!NT_STATUS_IS_OK(s.out.result)) {
7169 torture_result(tctx, TORTURE_FAIL, "SetDomainInfo level %u (set comment) failed - %s\n",
7170 s.in.level, nt_errstr(s.out.result));
7174 for (i=0;i<ARRAY_SIZE(levels);i++) {
7175 torture_comment(tctx, "Testing QueryDomainInfo level %u\n", levels[i]);
7177 r.in.domain_handle = handle;
7178 r.in.level = levels[i];
7181 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &r),
7182 "QueryDomainInfo failed");
7183 if (!NT_STATUS_IS_OK(r.out.result)) {
7184 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo level %u failed - %s\n",
7185 r.in.level, nt_errstr(r.out.result));
7190 switch (levels[i]) {
7192 if (strcmp(info->general.oem_information.string, domain_comment) != 0) {
7193 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
7194 levels[i], info->general.oem_information.string, domain_comment);
7195 if (!torture_setting_bool(tctx, "samba3", false)) {
7199 if (!info->general.primary.string) {
7200 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo level %u returned no PDC name\n",
7203 } else if (info->general.role == SAMR_ROLE_DOMAIN_PDC) {
7204 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), info->general.primary.string) != 0) {
7205 if (torture_setting_bool(tctx, "samba3", false)) {
7206 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",
7207 levels[i], info->general.primary.string, dcerpc_server_name(p));
7213 if (strcmp(info->oem.oem_information.string, domain_comment) != 0) {
7214 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
7215 levels[i], info->oem.oem_information.string, domain_comment);
7216 if (!torture_setting_bool(tctx, "samba3", false)) {
7222 if (!info->info6.primary.string) {
7223 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo level %u returned no PDC name\n",
7229 if (strcmp(info->general2.general.oem_information.string, domain_comment) != 0) {
7230 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
7231 levels[i], info->general2.general.oem_information.string, domain_comment);
7232 if (!torture_setting_bool(tctx, "samba3", false)) {
7239 torture_comment(tctx, "Testing SetDomainInfo level %u\n", levels[i]);
7241 s.in.domain_handle = handle;
7242 s.in.level = levels[i];
7245 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
7246 "SetDomainInfo failed");
7248 if (!NT_STATUS_IS_OK(s.out.result)) {
7249 torture_result(tctx, TORTURE_FAIL, "SetDomainInfo level %u failed - %s\n",
7250 r.in.level, nt_errstr(s.out.result));
7255 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, s.out.result)) {
7256 torture_result(tctx, TORTURE_FAIL, "SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
7257 r.in.level, nt_errstr(s.out.result));
7263 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &r),
7264 "QueryDomainInfo failed");
7265 if (!NT_STATUS_IS_OK(r.out.result)) {
7266 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo level %u failed - %s\n",
7267 r.in.level, nt_errstr(r.out.result));
7277 static bool test_QueryDomainInfo2(struct dcerpc_binding_handle *b,
7278 struct torture_context *tctx,
7279 struct policy_handle *handle)
7281 struct samr_QueryDomainInfo2 r;
7282 union samr_DomainInfo *info = NULL;
7283 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
7287 for (i=0;i<ARRAY_SIZE(levels);i++) {
7288 torture_comment(tctx, "Testing QueryDomainInfo2 level %u\n", levels[i]);
7290 r.in.domain_handle = handle;
7291 r.in.level = levels[i];
7294 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo2_r(b, tctx, &r),
7295 "QueryDomainInfo2 failed");
7296 if (!NT_STATUS_IS_OK(r.out.result)) {
7297 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo2 level %u failed - %s\n",
7298 r.in.level, nt_errstr(r.out.result));
7307 /* Test whether querydispinfo level 5 and enumdomgroups return the same
7308 set of group names. */
7309 static bool test_GroupList(struct dcerpc_binding_handle *b,
7310 struct torture_context *tctx,
7311 struct dom_sid *domain_sid,
7312 struct policy_handle *handle)
7314 struct samr_EnumDomainGroups q1;
7315 struct samr_QueryDisplayInfo q2;
7317 uint32_t resume_handle=0;
7318 struct samr_SamArray *sam = NULL;
7319 uint32_t num_entries = 0;
7322 uint32_t total_size;
7323 uint32_t returned_size;
7324 union samr_DispInfo info;
7326 size_t num_names = 0;
7327 const char **names = NULL;
7329 bool builtin_domain = dom_sid_compare(domain_sid,
7330 &global_sid_Builtin) == 0;
7332 torture_comment(tctx, "Testing coherency of querydispinfo vs enumdomgroups\n");
7334 q1.in.domain_handle = handle;
7335 q1.in.resume_handle = &resume_handle;
7337 q1.out.resume_handle = &resume_handle;
7338 q1.out.num_entries = &num_entries;
7341 status = STATUS_MORE_ENTRIES;
7342 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
7343 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainGroups_r(b, tctx, &q1),
7344 "EnumDomainGroups failed");
7345 status = q1.out.result;
7347 if (!NT_STATUS_IS_OK(status) &&
7348 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
7351 for (i=0; i<*q1.out.num_entries; i++) {
7352 add_string_to_array(tctx,
7353 sam->entries[i].name.string,
7354 &names, &num_names);
7358 torture_assert_ntstatus_ok(tctx, status, "EnumDomainGroups");
7360 torture_assert(tctx, sam, "EnumDomainGroups failed to return sam");
7362 if (builtin_domain) {
7363 torture_assert(tctx, num_names == 0,
7364 "EnumDomainGroups shouldn't return any group in the builtin domain!");
7367 q2.in.domain_handle = handle;
7369 q2.in.start_idx = 0;
7370 q2.in.max_entries = 5;
7371 q2.in.buf_size = (uint32_t)-1;
7372 q2.out.total_size = &total_size;
7373 q2.out.returned_size = &returned_size;
7374 q2.out.info = &info;
7376 status = STATUS_MORE_ENTRIES;
7377 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
7378 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &q2),
7379 "QueryDisplayInfo failed");
7380 status = q2.out.result;
7381 if (!NT_STATUS_IS_OK(status) &&
7382 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
7385 for (i=0; i<q2.out.info->info5.count; i++) {
7387 const char *name = q2.out.info->info5.entries[i].account_name.string;
7389 for (j=0; j<num_names; j++) {
7390 if (names[j] == NULL)
7392 if (strequal(names[j], name)) {
7399 if ((!found) && (!builtin_domain)) {
7400 torture_result(tctx, TORTURE_FAIL, "QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
7405 q2.in.start_idx += q2.out.info->info5.count;
7408 if (!NT_STATUS_IS_OK(status)) {
7409 torture_result(tctx, TORTURE_FAIL, "QueryDisplayInfo level 5 failed - %s\n",
7414 if (builtin_domain) {
7415 torture_assert(tctx, q2.in.start_idx != 0,
7416 "QueryDisplayInfo should return all domain groups also on the builtin domain handle!");
7419 for (i=0; i<num_names; i++) {
7420 if (names[i] != NULL) {
7421 torture_result(tctx, TORTURE_FAIL, "EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
7430 static bool test_DeleteDomainGroup(struct dcerpc_binding_handle *b,
7431 struct torture_context *tctx,
7432 struct policy_handle *group_handle)
7434 struct samr_DeleteDomainGroup d;
7436 torture_comment(tctx, "Testing DeleteDomainGroup\n");
7438 d.in.group_handle = group_handle;
7439 d.out.group_handle = group_handle;
7441 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomainGroup_r(b, tctx, &d),
7442 "DeleteDomainGroup failed");
7443 torture_assert_ntstatus_ok(tctx, d.out.result, "DeleteDomainGroup");
7448 static bool test_TestPrivateFunctionsDomain(struct dcerpc_binding_handle *b,
7449 struct torture_context *tctx,
7450 struct policy_handle *domain_handle)
7452 struct samr_TestPrivateFunctionsDomain r;
7455 torture_comment(tctx, "Testing TestPrivateFunctionsDomain\n");
7457 r.in.domain_handle = domain_handle;
7459 torture_assert_ntstatus_ok(tctx, dcerpc_samr_TestPrivateFunctionsDomain_r(b, tctx, &r),
7460 "TestPrivateFunctionsDomain failed");
7461 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsDomain");
7466 static bool test_RidToSid(struct dcerpc_binding_handle *b,
7467 struct torture_context *tctx,
7468 struct dom_sid *domain_sid,
7469 struct policy_handle *domain_handle)
7471 struct samr_RidToSid r;
7473 struct dom_sid *calc_sid, *out_sid;
7474 int rids[] = { 0, 42, 512, 10200 };
7477 for (i=0;i<ARRAY_SIZE(rids);i++) {
7478 torture_comment(tctx, "Testing RidToSid\n");
7480 calc_sid = dom_sid_dup(tctx, domain_sid);
7481 r.in.domain_handle = domain_handle;
7483 r.out.sid = &out_sid;
7485 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RidToSid_r(b, tctx, &r),
7487 if (!NT_STATUS_IS_OK(r.out.result)) {
7488 torture_result(tctx, TORTURE_FAIL, "RidToSid for %d failed - %s\n", rids[i], nt_errstr(r.out.result));
7491 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
7493 if (!dom_sid_equal(calc_sid, out_sid)) {
7494 torture_result(tctx, TORTURE_FAIL, "RidToSid for %d failed - got %s, expected %s\n", rids[i],
7495 dom_sid_string(tctx, out_sid),
7496 dom_sid_string(tctx, calc_sid));
7505 static bool test_GetBootKeyInformation(struct dcerpc_binding_handle *b,
7506 struct torture_context *tctx,
7507 struct policy_handle *domain_handle)
7509 struct samr_GetBootKeyInformation r;
7511 uint32_t unknown = 0;
7514 torture_comment(tctx, "Testing GetBootKeyInformation\n");
7516 r.in.domain_handle = domain_handle;
7517 r.out.unknown = &unknown;
7519 status = dcerpc_samr_GetBootKeyInformation_r(b, tctx, &r);
7520 if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_OK(r.out.result)) {
7521 status = r.out.result;
7523 if (!NT_STATUS_IS_OK(status)) {
7524 /* w2k3 seems to fail this sometimes and pass it sometimes */
7525 torture_comment(tctx, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
7531 static bool test_AddGroupMember(struct dcerpc_binding_handle *b,
7532 struct torture_context *tctx,
7533 struct policy_handle *domain_handle,
7534 struct policy_handle *group_handle)
7537 struct samr_AddGroupMember r;
7538 struct samr_DeleteGroupMember d;
7539 struct samr_QueryGroupMember q;
7540 struct samr_RidAttrArray *rids = NULL;
7541 struct samr_SetMemberAttributesOfGroup s;
7543 bool found_member = false;
7546 status = test_LookupName(b, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
7547 torture_assert_ntstatus_ok(tctx, status, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME);
7549 r.in.group_handle = group_handle;
7551 r.in.flags = 0; /* ??? */
7553 torture_comment(tctx, "Testing AddGroupMember, QueryGroupMember and DeleteGroupMember\n");
7555 d.in.group_handle = group_handle;
7558 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteGroupMember_r(b, tctx, &d),
7559 "DeleteGroupMember failed");
7560 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_NOT_IN_GROUP, d.out.result, "DeleteGroupMember");
7562 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddGroupMember_r(b, tctx, &r),
7563 "AddGroupMember failed");
7564 torture_assert_ntstatus_ok(tctx, r.out.result, "AddGroupMember");
7566 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddGroupMember_r(b, tctx, &r),
7567 "AddGroupMember failed");
7568 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_IN_GROUP, r.out.result, "AddGroupMember");
7570 if (torture_setting_bool(tctx, "samba4", false) ||
7571 torture_setting_bool(tctx, "samba3", false)) {
7572 torture_comment(tctx, "skipping SetMemberAttributesOfGroup test against Samba\n");
7574 /* this one is quite strange. I am using random inputs in the
7575 hope of triggering an error that might give us a clue */
7577 s.in.group_handle = group_handle;
7578 s.in.unknown1 = random();
7579 s.in.unknown2 = random();
7581 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetMemberAttributesOfGroup_r(b, tctx, &s),
7582 "SetMemberAttributesOfGroup failed");
7583 torture_assert_ntstatus_ok(tctx, s.out.result, "SetMemberAttributesOfGroup");
7586 q.in.group_handle = group_handle;
7589 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupMember_r(b, tctx, &q),
7590 "QueryGroupMember failed");
7591 torture_assert_ntstatus_ok(tctx, q.out.result, "QueryGroupMember");
7592 torture_assert(tctx, rids, "QueryGroupMember did not fill in rids structure");
7594 for (i=0; i < rids->count; i++) {
7595 if (rids->rids[i] == rid) {
7596 found_member = true;
7600 torture_assert(tctx, found_member, "QueryGroupMember did not list newly added member");
7602 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteGroupMember_r(b, tctx, &d),
7603 "DeleteGroupMember failed");
7604 torture_assert_ntstatus_ok(tctx, d.out.result, "DeleteGroupMember");
7607 found_member = false;
7609 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupMember_r(b, tctx, &q),
7610 "QueryGroupMember failed");
7611 torture_assert_ntstatus_ok(tctx, q.out.result, "QueryGroupMember");
7612 torture_assert(tctx, rids, "QueryGroupMember did not fill in rids structure");
7614 for (i=0; i < rids->count; i++) {
7615 if (rids->rids[i] == rid) {
7616 found_member = true;
7620 torture_assert(tctx, !found_member, "QueryGroupMember does still list removed member");
7622 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddGroupMember_r(b, tctx, &r),
7623 "AddGroupMember failed");
7624 torture_assert_ntstatus_ok(tctx, r.out.result, "AddGroupMember");
7630 static bool test_CreateDomainGroup(struct dcerpc_binding_handle *b,
7631 struct torture_context *tctx,
7632 struct policy_handle *domain_handle,
7633 const char *group_name,
7634 struct policy_handle *group_handle,
7635 struct dom_sid *domain_sid,
7638 struct samr_CreateDomainGroup r;
7640 struct lsa_String name;
7643 init_lsa_String(&name, group_name);
7645 r.in.domain_handle = domain_handle;
7647 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7648 r.out.group_handle = group_handle;
7651 torture_comment(tctx, "Testing CreateDomainGroup(%s)\n", r.in.name->string);
7653 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomainGroup_r(b, tctx, &r),
7654 "CreateDomainGroup failed");
7656 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
7657 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED)) {
7658 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.name->string);
7661 torture_result(tctx, TORTURE_FAIL, "Server should have refused create of '%s', got %s instead\n", r.in.name->string,
7662 nt_errstr(r.out.result));
7667 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_GROUP_EXISTS)) {
7668 if (!test_DeleteGroup_byname(b, tctx, domain_handle, r.in.name->string)) {
7669 torture_result(tctx, TORTURE_FAIL, "CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
7670 nt_errstr(r.out.result));
7673 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomainGroup_r(b, tctx, &r),
7674 "CreateDomainGroup failed");
7676 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_USER_EXISTS)) {
7677 if (!test_DeleteUser_byname(b, tctx, domain_handle, r.in.name->string)) {
7679 torture_result(tctx, TORTURE_FAIL, "CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
7680 nt_errstr(r.out.result));
7683 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomainGroup_r(b, tctx, &r),
7684 "CreateDomainGroup failed");
7686 torture_assert_ntstatus_ok(tctx, r.out.result, "CreateDomainGroup");
7692 if (!test_AddGroupMember(b, tctx, domain_handle, group_handle)) {
7693 torture_result(tctx, TORTURE_FAIL, "CreateDomainGroup failed - %s\n", nt_errstr(r.out.result));
7697 if (!test_SetGroupInfo(b, tctx, group_handle)) {
7706 its not totally clear what this does. It seems to accept any sid you like.
7708 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_binding_handle *b,
7709 struct torture_context *tctx,
7710 struct policy_handle *domain_handle)
7712 struct samr_RemoveMemberFromForeignDomain r;
7714 r.in.domain_handle = domain_handle;
7715 r.in.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-12-34-56-78");
7717 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RemoveMemberFromForeignDomain_r(b, tctx, &r),
7718 "RemoveMemberFromForeignDomain failed");
7719 torture_assert_ntstatus_ok(tctx, r.out.result, "RemoveMemberFromForeignDomain");
7724 static bool test_EnumDomainUsers(struct dcerpc_binding_handle *b,
7725 struct torture_context *tctx,
7726 struct policy_handle *domain_handle,
7727 uint32_t *total_num_entries_p)
7730 struct samr_EnumDomainUsers r;
7731 uint32_t resume_handle = 0;
7732 uint32_t num_entries = 0;
7733 uint32_t total_num_entries = 0;
7734 struct samr_SamArray *sam;
7736 r.in.domain_handle = domain_handle;
7737 r.in.acct_flags = 0;
7738 r.in.max_size = (uint32_t)-1;
7739 r.in.resume_handle = &resume_handle;
7742 r.out.num_entries = &num_entries;
7743 r.out.resume_handle = &resume_handle;
7745 torture_comment(tctx, "Testing EnumDomainUsers\n");
7748 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainUsers_r(b, tctx, &r),
7749 "EnumDomainUsers failed");
7750 if (NT_STATUS_IS_ERR(r.out.result)) {
7751 torture_assert_ntstatus_ok(tctx, r.out.result,
7752 "failed to enumerate users");
7754 status = r.out.result;
7756 total_num_entries += num_entries;
7757 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7759 if (total_num_entries_p) {
7760 *total_num_entries_p = total_num_entries;
7766 static bool test_EnumDomainGroups(struct dcerpc_binding_handle *b,
7767 struct torture_context *tctx,
7768 struct policy_handle *domain_handle,
7769 uint32_t *total_num_entries_p)
7772 struct samr_EnumDomainGroups r;
7773 uint32_t resume_handle = 0;
7774 uint32_t num_entries = 0;
7775 uint32_t total_num_entries = 0;
7776 struct samr_SamArray *sam;
7778 r.in.domain_handle = domain_handle;
7779 r.in.max_size = (uint32_t)-1;
7780 r.in.resume_handle = &resume_handle;
7783 r.out.num_entries = &num_entries;
7784 r.out.resume_handle = &resume_handle;
7786 torture_comment(tctx, "Testing EnumDomainGroups\n");
7789 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainGroups_r(b, tctx, &r),
7790 "EnumDomainGroups failed");
7791 if (NT_STATUS_IS_ERR(r.out.result)) {
7792 torture_assert_ntstatus_ok(tctx, r.out.result,
7793 "failed to enumerate groups");
7795 status = r.out.result;
7797 total_num_entries += num_entries;
7798 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7800 if (total_num_entries_p) {
7801 *total_num_entries_p = total_num_entries;
7807 static bool test_EnumDomainAliases(struct dcerpc_binding_handle *b,
7808 struct torture_context *tctx,
7809 struct policy_handle *domain_handle,
7810 uint32_t *total_num_entries_p)
7813 struct samr_EnumDomainAliases r;
7814 uint32_t resume_handle = 0;
7815 uint32_t num_entries = 0;
7816 uint32_t total_num_entries = 0;
7817 struct samr_SamArray *sam;
7819 r.in.domain_handle = domain_handle;
7820 r.in.max_size = (uint32_t)-1;
7821 r.in.resume_handle = &resume_handle;
7824 r.out.num_entries = &num_entries;
7825 r.out.resume_handle = &resume_handle;
7827 torture_comment(tctx, "Testing EnumDomainAliases\n");
7830 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainAliases_r(b, tctx, &r),
7831 "EnumDomainAliases failed");
7832 if (NT_STATUS_IS_ERR(r.out.result)) {
7833 torture_assert_ntstatus_ok(tctx, r.out.result,
7834 "failed to enumerate aliases");
7836 status = r.out.result;
7838 total_num_entries += num_entries;
7839 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7841 if (total_num_entries_p) {
7842 *total_num_entries_p = total_num_entries;
7848 static bool test_QueryDisplayInfo_level(struct dcerpc_binding_handle *b,
7849 struct torture_context *tctx,
7850 struct policy_handle *handle,
7852 uint32_t *total_num_entries_p)
7855 struct samr_QueryDisplayInfo r;
7856 uint32_t total_num_entries = 0;
7858 r.in.domain_handle = handle;
7861 r.in.max_entries = (uint32_t)-1;
7862 r.in.buf_size = (uint32_t)-1;
7864 torture_comment(tctx, "Testing QueryDisplayInfo\n");
7867 uint32_t total_size;
7868 uint32_t returned_size;
7869 union samr_DispInfo info;
7871 r.out.total_size = &total_size;
7872 r.out.returned_size = &returned_size;
7875 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &r),
7876 "failed to query displayinfo");
7877 if (NT_STATUS_IS_ERR(r.out.result)) {
7878 torture_assert_ntstatus_ok(tctx, r.out.result,
7879 "failed to query displayinfo");
7881 status = r.out.result;
7883 if (*r.out.returned_size == 0) {
7887 switch (r.in.level) {
7889 total_num_entries += info.info1.count;
7890 r.in.start_idx += info.info1.entries[info.info1.count - 1].idx + 1;
7893 total_num_entries += info.info2.count;
7894 r.in.start_idx += info.info2.entries[info.info2.count - 1].idx + 1;
7897 total_num_entries += info.info3.count;
7898 r.in.start_idx += info.info3.entries[info.info3.count - 1].idx + 1;
7901 total_num_entries += info.info4.count;
7902 r.in.start_idx += info.info4.entries[info.info4.count - 1].idx + 1;
7905 total_num_entries += info.info5.count;
7906 r.in.start_idx += info.info5.entries[info.info5.count - 1].idx + 1;
7912 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7914 if (total_num_entries_p) {
7915 *total_num_entries_p = total_num_entries;
7921 static bool test_ManyObjects(struct dcerpc_pipe *p,
7922 struct torture_context *tctx,
7923 struct policy_handle *domain_handle,
7924 struct dom_sid *domain_sid,
7925 struct torture_samr_context *ctx)
7927 uint32_t num_total = ctx->num_objects_large_dc;
7928 uint32_t num_enum = 0;
7929 uint32_t num_disp = 0;
7930 uint32_t num_created = 0;
7931 uint32_t num_anounced = 0;
7933 struct dcerpc_binding_handle *b = p->binding_handle;
7935 struct policy_handle *handles = talloc_zero_array(tctx, struct policy_handle, num_total);
7940 struct samr_QueryDomainInfo2 r;
7941 union samr_DomainInfo *info;
7942 r.in.domain_handle = domain_handle;
7946 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo2_r(b, tctx, &r),
7947 "QueryDomainInfo2 failed");
7948 torture_assert_ntstatus_ok(tctx, r.out.result,
7949 "failed to query domain info");
7951 switch (ctx->choice) {
7952 case TORTURE_SAMR_MANY_ACCOUNTS:
7953 num_anounced = info->general.num_users;
7955 case TORTURE_SAMR_MANY_GROUPS:
7956 num_anounced = info->general.num_groups;
7958 case TORTURE_SAMR_MANY_ALIASES:
7959 num_anounced = info->general.num_aliases;
7968 for (i=0; i < num_total; i++) {
7970 const char *name = NULL;
7972 switch (ctx->choice) {
7973 case TORTURE_SAMR_MANY_ACCOUNTS:
7974 name = talloc_asprintf(tctx, "%s%04d", TEST_ACCOUNT_NAME, i);
7975 torture_assert(tctx,
7976 test_CreateUser(p, tctx, domain_handle, name, &handles[i], domain_sid, 0, NULL, false),
7977 "failed to create user");
7979 case TORTURE_SAMR_MANY_GROUPS:
7980 name = talloc_asprintf(tctx, "%s%04d", TEST_GROUPNAME, i);
7981 torture_assert(tctx,
7982 test_CreateDomainGroup(b, tctx, domain_handle, name, &handles[i], domain_sid, false),
7983 "failed to create group");
7985 case TORTURE_SAMR_MANY_ALIASES:
7986 name = talloc_asprintf(tctx, "%s%04d", TEST_ALIASNAME, i);
7987 torture_assert(tctx,
7988 test_CreateAlias(b, tctx, domain_handle, name, &handles[i], domain_sid, false),
7989 "failed to create alias");
7994 if (!ndr_policy_handle_empty(&handles[i])) {
8001 switch (ctx->choice) {
8002 case TORTURE_SAMR_MANY_ACCOUNTS:
8003 torture_assert(tctx,
8004 test_EnumDomainUsers(b, tctx, domain_handle, &num_enum),
8005 "failed to enum users");
8007 case TORTURE_SAMR_MANY_GROUPS:
8008 torture_assert(tctx,
8009 test_EnumDomainGroups(b, tctx, domain_handle, &num_enum),
8010 "failed to enum groups");
8012 case TORTURE_SAMR_MANY_ALIASES:
8013 torture_assert(tctx,
8014 test_EnumDomainAliases(b, tctx, domain_handle, &num_enum),
8015 "failed to enum aliases");
8023 switch (ctx->choice) {
8024 case TORTURE_SAMR_MANY_ACCOUNTS:
8025 torture_assert(tctx,
8026 test_QueryDisplayInfo_level(b, tctx, domain_handle, 1, &num_disp),
8027 "failed to query display info");
8029 case TORTURE_SAMR_MANY_GROUPS:
8030 torture_assert(tctx,
8031 test_QueryDisplayInfo_level(b, tctx, domain_handle, 3, &num_disp),
8032 "failed to query display info");
8034 case TORTURE_SAMR_MANY_ALIASES:
8035 /* no aliases in dispinfo */
8041 /* close or delete */
8043 for (i=0; i < num_total; i++) {
8045 if (ndr_policy_handle_empty(&handles[i])) {
8049 if (torture_setting_bool(tctx, "samba3", false)) {
8050 torture_assert(tctx,
8051 test_samr_handle_Close(b, tctx, &handles[i]),
8052 "failed to close handle");
8054 switch (ctx->choice) {
8055 case TORTURE_SAMR_MANY_ACCOUNTS:
8056 torture_assert(tctx,
8057 test_DeleteUser(b, tctx, &handles[i]),
8058 "failed to delete user");
8060 case TORTURE_SAMR_MANY_GROUPS:
8061 torture_assert(tctx,
8062 test_DeleteDomainGroup(b, tctx, &handles[i]),
8063 "failed to delete group");
8065 case TORTURE_SAMR_MANY_ALIASES:
8066 torture_assert(tctx,
8067 test_DeleteAlias(b, tctx, &handles[i]),
8068 "failed to delete alias");
8076 talloc_free(handles);
8078 if (ctx->choice == TORTURE_SAMR_MANY_ACCOUNTS && num_enum != num_anounced + num_created) {
8079 torture_comment(tctx,
8080 "unexpected number of results (%u) returned in enum call, expected %u\n",
8081 num_enum, num_anounced + num_created);
8083 torture_comment(tctx,
8084 "unexpected number of results (%u) returned in dispinfo, call, expected %u\n",
8085 num_disp, num_anounced + num_created);
8091 static bool test_Connect(struct dcerpc_binding_handle *b,
8092 struct torture_context *tctx,
8093 struct policy_handle *handle);
8095 static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
8096 struct torture_samr_context *ctx, struct dom_sid *sid)
8098 struct samr_OpenDomain r;
8099 struct policy_handle domain_handle;
8100 struct policy_handle alias_handle;
8101 struct policy_handle user_handle;
8102 struct policy_handle group_handle;
8104 struct dcerpc_binding_handle *b = p->binding_handle;
8106 ZERO_STRUCT(alias_handle);
8107 ZERO_STRUCT(user_handle);
8108 ZERO_STRUCT(group_handle);
8109 ZERO_STRUCT(domain_handle);
8111 torture_comment(tctx, "Testing OpenDomain of %s\n", dom_sid_string(tctx, sid));
8113 r.in.connect_handle = &ctx->handle;
8114 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
8116 r.out.domain_handle = &domain_handle;
8118 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenDomain_r(b, tctx, &r),
8119 "OpenDomain failed");
8120 torture_assert_ntstatus_ok(tctx, r.out.result, "OpenDomain failed");
8122 /* run the domain tests with the main handle closed - this tests
8123 the servers reference counting */
8124 torture_assert(tctx, test_samr_handle_Close(b, tctx, &ctx->handle), "Failed to close SAMR handle");
8126 switch (ctx->choice) {
8127 case TORTURE_SAMR_PASSWORDS:
8128 case TORTURE_SAMR_USER_PRIVILEGES:
8129 if (!torture_setting_bool(tctx, "samba3", false)) {
8130 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, NULL);
8132 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
8134 torture_result(tctx, TORTURE_FAIL, "Testing PASSWORDS or PRIVILEGES on domain %s failed!\n", dom_sid_string(tctx, sid));
8137 case TORTURE_SAMR_USER_ATTRIBUTES:
8138 if (!torture_setting_bool(tctx, "samba3", false)) {
8139 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, NULL);
8141 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
8142 /* This test needs 'complex' users to validate */
8143 ret &= test_QueryDisplayInfo(b, tctx, &domain_handle);
8145 torture_result(tctx, TORTURE_FAIL, "Testing ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
8148 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
8149 case TORTURE_SAMR_PASSWORDS_BADPWDCOUNT:
8150 case TORTURE_SAMR_PASSWORDS_LOCKOUT:
8151 if (!torture_setting_bool(tctx, "samba3", false)) {
8152 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, ctx->machine_credentials);
8154 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, ctx->machine_credentials, true);
8156 torture_result(tctx, TORTURE_FAIL, "Testing PASSWORDS PWDLASTSET or BADPWDCOUNT on domain %s failed!\n", dom_sid_string(tctx, sid));
8159 case TORTURE_SAMR_MANY_ACCOUNTS:
8160 case TORTURE_SAMR_MANY_GROUPS:
8161 case TORTURE_SAMR_MANY_ALIASES:
8162 ret &= test_ManyObjects(p, tctx, &domain_handle, sid, ctx);
8164 torture_result(tctx, TORTURE_FAIL, "Testing MANY-{ACCOUNTS,GROUPS,ALIASES} on domain %s failed!\n", dom_sid_string(tctx, sid));
8167 case TORTURE_SAMR_OTHER:
8168 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
8170 torture_result(tctx, TORTURE_FAIL, "Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid));
8172 if (!torture_setting_bool(tctx, "samba3", false)) {
8173 ret &= test_QuerySecurity(b, tctx, &domain_handle);
8175 ret &= test_RemoveMemberFromForeignDomain(b, tctx, &domain_handle);
8176 ret &= test_CreateAlias(b, tctx, &domain_handle, TEST_ALIASNAME, &alias_handle, sid, true);
8177 ret &= test_CreateDomainGroup(b, tctx, &domain_handle, TEST_GROUPNAME, &group_handle, sid, true);
8178 ret &= test_GetAliasMembership(b, tctx, &domain_handle);
8179 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
8180 ret &= test_QueryDomainInfo2(b, tctx, &domain_handle);
8181 ret &= test_EnumDomainUsers_all(b, tctx, &domain_handle);
8182 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
8183 ret &= test_EnumDomainGroups_all(b, tctx, &domain_handle);
8184 ret &= test_EnumDomainAliases_all(b, tctx, &domain_handle);
8185 ret &= test_QueryDisplayInfo2(b, tctx, &domain_handle);
8186 ret &= test_QueryDisplayInfo3(b, tctx, &domain_handle);
8187 ret &= test_QueryDisplayInfo_continue(b, tctx, &domain_handle);
8189 if (torture_setting_bool(tctx, "samba4", false)) {
8190 torture_comment(tctx, "skipping GetDisplayEnumerationIndex test against Samba4\n");
8192 ret &= test_GetDisplayEnumerationIndex(b, tctx, &domain_handle);
8193 ret &= test_GetDisplayEnumerationIndex2(b, tctx, &domain_handle);
8195 ret &= test_GroupList(b, tctx, sid, &domain_handle);
8196 ret &= test_TestPrivateFunctionsDomain(b, tctx, &domain_handle);
8197 ret &= test_RidToSid(b, tctx, sid, &domain_handle);
8198 ret &= test_GetBootKeyInformation(b, tctx, &domain_handle);
8200 torture_comment(tctx, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx, sid));
8205 if (!ndr_policy_handle_empty(&user_handle) &&
8206 !test_DeleteUser(b, tctx, &user_handle)) {
8210 if (!ndr_policy_handle_empty(&alias_handle) &&
8211 !test_DeleteAlias(b, tctx, &alias_handle)) {
8215 if (!ndr_policy_handle_empty(&group_handle) &&
8216 !test_DeleteDomainGroup(b, tctx, &group_handle)) {
8220 torture_assert(tctx, test_samr_handle_Close(b, tctx, &domain_handle), "Failed to close SAMR domain handle");
8222 torture_assert(tctx, test_Connect(b, tctx, &ctx->handle), "Faile to re-connect SAMR handle");
8223 /* reconnect the main handle */
8226 torture_result(tctx, TORTURE_FAIL, "Testing domain %s failed!\n", dom_sid_string(tctx, sid));
8232 static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
8233 struct torture_samr_context *ctx, const char *domain)
8235 struct samr_LookupDomain r;
8236 struct dom_sid2 *sid = NULL;
8237 struct lsa_String n1;
8238 struct lsa_String n2;
8240 struct dcerpc_binding_handle *b = p->binding_handle;
8242 torture_comment(tctx, "Testing LookupDomain(%s)\n", domain);
8244 /* check for correct error codes */
8245 r.in.connect_handle = &ctx->handle;
8246 r.in.domain_name = &n2;
8250 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupDomain_r(b, tctx, &r),
8251 "LookupDomain failed");
8252 torture_assert_ntstatus_equal(tctx, NT_STATUS_INVALID_PARAMETER, r.out.result, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
8254 init_lsa_String(&n2, "xxNODOMAINxx");
8256 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupDomain_r(b, tctx, &r),
8257 "LookupDomain failed");
8258 torture_assert_ntstatus_equal(tctx, NT_STATUS_NO_SUCH_DOMAIN, r.out.result, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
8260 r.in.connect_handle = &ctx->handle;
8262 init_lsa_String(&n1, domain);
8263 r.in.domain_name = &n1;
8265 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupDomain_r(b, tctx, &r),
8266 "LookupDomain failed");
8267 torture_assert_ntstatus_ok(tctx, r.out.result, "LookupDomain");
8269 if (!test_GetDomPwInfo(p, tctx, &n1)) {
8273 if (!test_OpenDomain(p, tctx, ctx, *r.out.sid)) {
8281 static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
8282 struct torture_samr_context *ctx)
8284 struct samr_EnumDomains r;
8285 uint32_t resume_handle = 0;
8286 uint32_t num_entries = 0;
8287 struct samr_SamArray *sam = NULL;
8290 struct dcerpc_binding_handle *b = p->binding_handle;
8292 r.in.connect_handle = &ctx->handle;
8293 r.in.resume_handle = &resume_handle;
8294 r.in.buf_size = (uint32_t)-1;
8295 r.out.resume_handle = &resume_handle;
8296 r.out.num_entries = &num_entries;
8299 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomains_r(b, tctx, &r),
8300 "EnumDomains failed");
8301 torture_assert_ntstatus_ok(tctx, r.out.result, "EnumDomains failed");
8307 for (i=0;i<sam->count;i++) {
8308 if (!test_LookupDomain(p, tctx, ctx,
8309 sam->entries[i].name.string)) {
8314 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomains_r(b, tctx, &r),
8315 "EnumDomains failed");
8316 torture_assert_ntstatus_ok(tctx, r.out.result, "EnumDomains failed");
8322 static bool test_Connect(struct dcerpc_binding_handle *b,
8323 struct torture_context *tctx,
8324 struct policy_handle *handle)
8326 struct samr_Connect r;
8327 struct samr_Connect2 r2;
8328 struct samr_Connect3 r3;
8329 struct samr_Connect4 r4;
8330 struct samr_Connect5 r5;
8331 union samr_ConnectInfo info;
8332 struct policy_handle h;
8333 uint32_t level_out = 0;
8334 bool ret = true, got_handle = false;
8336 torture_comment(tctx, "Testing samr_Connect\n");
8338 r.in.system_name = NULL;
8339 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
8340 r.out.connect_handle = &h;
8342 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect_r(b, tctx, &r),
8344 if (!NT_STATUS_IS_OK(r.out.result)) {
8345 torture_comment(tctx, "Connect failed - %s\n", nt_errstr(r.out.result));
8352 torture_comment(tctx, "Testing samr_Connect2\n");
8354 r2.in.system_name = NULL;
8355 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
8356 r2.out.connect_handle = &h;
8358 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect2_r(b, tctx, &r2),
8360 if (!NT_STATUS_IS_OK(r2.out.result)) {
8361 torture_comment(tctx, "Connect2 failed - %s\n", nt_errstr(r2.out.result));
8365 test_samr_handle_Close(b, tctx, handle);
8371 torture_comment(tctx, "Testing samr_Connect3\n");
8373 r3.in.system_name = NULL;
8375 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
8376 r3.out.connect_handle = &h;
8378 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect3_r(b, tctx, &r3),
8380 if (!NT_STATUS_IS_OK(r3.out.result)) {
8381 torture_result(tctx, TORTURE_FAIL, "Connect3 failed - %s\n", nt_errstr(r3.out.result));
8385 test_samr_handle_Close(b, tctx, handle);
8391 torture_comment(tctx, "Testing samr_Connect4\n");
8393 r4.in.system_name = "";
8394 r4.in.client_version = 0;
8395 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
8396 r4.out.connect_handle = &h;
8398 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect4_r(b, tctx, &r4),
8400 if (!NT_STATUS_IS_OK(r4.out.result)) {
8401 torture_result(tctx, TORTURE_FAIL, "Connect4 failed - %s\n", nt_errstr(r4.out.result));
8405 test_samr_handle_Close(b, tctx, handle);
8411 torture_comment(tctx, "Testing samr_Connect5\n");
8413 info.info1.client_version = 0;
8414 info.info1.unknown2 = 0;
8416 r5.in.system_name = "";
8417 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
8419 r5.out.level_out = &level_out;
8420 r5.in.info_in = &info;
8421 r5.out.info_out = &info;
8422 r5.out.connect_handle = &h;
8424 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect5_r(b, tctx, &r5),
8426 if (!NT_STATUS_IS_OK(r5.out.result)) {
8427 torture_result(tctx, TORTURE_FAIL, "Connect5 failed - %s\n", nt_errstr(r5.out.result));
8431 test_samr_handle_Close(b, tctx, handle);
8441 static bool test_samr_ValidatePassword(struct torture_context *tctx,
8442 struct dcerpc_pipe *p)
8444 struct samr_ValidatePassword r;
8445 union samr_ValidatePasswordReq req;
8446 union samr_ValidatePasswordRep *repp = NULL;
8448 const char *passwords[] = { "penguin", "p@ssw0rd", "p@ssw0rd123$", NULL };
8450 struct dcerpc_binding_handle *b = p->binding_handle;
8452 torture_comment(tctx, "Testing samr_ValidatePassword\n");
8454 if (p->conn->transport.transport != NCACN_IP_TCP) {
8455 torture_comment(tctx, "samr_ValidatePassword only should succeed over NCACN_IP_TCP!\n");
8459 r.in.level = NetValidatePasswordReset;
8464 req.req3.account.string = "non-existent-account-aklsdji";
8466 for (i=0; passwords[i]; i++) {
8467 req.req3.password.string = passwords[i];
8469 status = dcerpc_samr_ValidatePassword_r(b, tctx, &r);
8470 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE)) {
8471 torture_skip(tctx, "ValidatePassword not supported by server\n");
8473 torture_assert_ntstatus_ok(tctx, status,
8474 "samr_ValidatePassword failed");
8475 torture_assert_ntstatus_ok(tctx, r.out.result,
8476 "samr_ValidatePassword failed");
8477 torture_comment(tctx, "Server %s password '%s' with code %i\n",
8478 repp->ctr3.status==SAMR_VALIDATION_STATUS_SUCCESS?"allowed":"refused",
8479 req.req3.password.string, repp->ctr3.status);
8485 bool torture_rpc_samr(struct torture_context *torture)
8488 struct dcerpc_pipe *p;
8490 struct torture_samr_context *ctx;
8491 struct dcerpc_binding_handle *b;
8493 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8494 if (!NT_STATUS_IS_OK(status)) {
8497 b = p->binding_handle;
8499 ctx = talloc_zero(torture, struct torture_samr_context);
8501 ctx->choice = TORTURE_SAMR_OTHER;
8503 ret &= test_Connect(b, torture, &ctx->handle);
8505 if (!torture_setting_bool(torture, "samba3", false)) {
8506 ret &= test_QuerySecurity(b, torture, &ctx->handle);
8509 ret &= test_EnumDomains(p, torture, ctx);
8511 ret &= test_SetDsrmPassword(b, torture, &ctx->handle);
8513 ret &= test_Shutdown(b, torture, &ctx->handle);
8515 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8521 bool torture_rpc_samr_users(struct torture_context *torture)
8524 struct dcerpc_pipe *p;
8526 struct torture_samr_context *ctx;
8527 struct dcerpc_binding_handle *b;
8529 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8530 if (!NT_STATUS_IS_OK(status)) {
8533 b = p->binding_handle;
8535 ctx = talloc_zero(torture, struct torture_samr_context);
8537 ctx->choice = TORTURE_SAMR_USER_ATTRIBUTES;
8539 ret &= test_Connect(b, torture, &ctx->handle);
8541 if (!torture_setting_bool(torture, "samba3", false)) {
8542 ret &= test_QuerySecurity(b, torture, &ctx->handle);
8545 ret &= test_EnumDomains(p, torture, ctx);
8547 ret &= test_SetDsrmPassword(b, torture, &ctx->handle);
8549 ret &= test_Shutdown(b, torture, &ctx->handle);
8551 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8557 bool torture_rpc_samr_passwords(struct torture_context *torture)
8560 struct dcerpc_pipe *p;
8562 struct torture_samr_context *ctx;
8563 struct dcerpc_binding_handle *b;
8565 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8566 if (!NT_STATUS_IS_OK(status)) {
8569 b = p->binding_handle;
8571 ctx = talloc_zero(torture, struct torture_samr_context);
8573 ctx->choice = TORTURE_SAMR_PASSWORDS;
8575 ret &= test_Connect(b, torture, &ctx->handle);
8577 ret &= test_EnumDomains(p, torture, ctx);
8579 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8584 static bool torture_rpc_samr_pwdlastset(struct torture_context *torture,
8585 struct dcerpc_pipe *p2,
8586 struct cli_credentials *machine_credentials)
8589 struct dcerpc_pipe *p;
8591 struct torture_samr_context *ctx;
8592 struct dcerpc_binding_handle *b;
8594 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8595 if (!NT_STATUS_IS_OK(status)) {
8598 b = p->binding_handle;
8600 ctx = talloc_zero(torture, struct torture_samr_context);
8602 ctx->choice = TORTURE_SAMR_PASSWORDS_PWDLASTSET;
8603 ctx->machine_credentials = machine_credentials;
8605 ret &= test_Connect(b, torture, &ctx->handle);
8607 ret &= test_EnumDomains(p, torture, ctx);
8609 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8614 struct torture_suite *torture_rpc_samr_passwords_pwdlastset(TALLOC_CTX *mem_ctx)
8616 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.passwords.pwdlastset");
8617 struct torture_rpc_tcase *tcase;
8619 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8621 TEST_ACCOUNT_NAME_PWD);
8623 torture_rpc_tcase_add_test_creds(tcase, "pwdLastSet",
8624 torture_rpc_samr_pwdlastset);
8629 static bool torture_rpc_samr_users_privileges_delete_user(struct torture_context *torture,
8630 struct dcerpc_pipe *p2,
8631 struct cli_credentials *machine_credentials)
8634 struct dcerpc_pipe *p;
8636 struct torture_samr_context *ctx;
8637 struct dcerpc_binding_handle *b;
8639 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8640 if (!NT_STATUS_IS_OK(status)) {
8643 b = p->binding_handle;
8645 ctx = talloc_zero(torture, struct torture_samr_context);
8647 ctx->choice = TORTURE_SAMR_USER_PRIVILEGES;
8648 ctx->machine_credentials = machine_credentials;
8650 ret &= test_Connect(b, torture, &ctx->handle);
8652 ret &= test_EnumDomains(p, torture, ctx);
8654 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8659 struct torture_suite *torture_rpc_samr_user_privileges(TALLOC_CTX *mem_ctx)
8661 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.users.privileges");
8662 struct torture_rpc_tcase *tcase;
8664 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8666 TEST_ACCOUNT_NAME_PWD);
8668 torture_rpc_tcase_add_test_creds(tcase, "delete_privileged_user",
8669 torture_rpc_samr_users_privileges_delete_user);
8674 static bool torture_rpc_samr_many_accounts(struct torture_context *torture,
8675 struct dcerpc_pipe *p2,
8679 struct dcerpc_pipe *p;
8681 struct torture_samr_context *ctx =
8682 talloc_get_type_abort(data, struct torture_samr_context);
8683 struct dcerpc_binding_handle *b;
8685 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8686 if (!NT_STATUS_IS_OK(status)) {
8689 b = p->binding_handle;
8691 ctx->choice = TORTURE_SAMR_MANY_ACCOUNTS;
8692 ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
8693 ctx->num_objects_large_dc);
8695 ret &= test_Connect(b, torture, &ctx->handle);
8697 ret &= test_EnumDomains(p, torture, ctx);
8699 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8704 static bool torture_rpc_samr_many_groups(struct torture_context *torture,
8705 struct dcerpc_pipe *p2,
8709 struct dcerpc_pipe *p;
8711 struct torture_samr_context *ctx =
8712 talloc_get_type_abort(data, struct torture_samr_context);
8713 struct dcerpc_binding_handle *b;
8715 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8716 if (!NT_STATUS_IS_OK(status)) {
8719 b = p->binding_handle;
8721 ctx->choice = TORTURE_SAMR_MANY_GROUPS;
8722 ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
8723 ctx->num_objects_large_dc);
8725 ret &= test_Connect(b, torture, &ctx->handle);
8727 ret &= test_EnumDomains(p, torture, ctx);
8729 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8734 static bool torture_rpc_samr_many_aliases(struct torture_context *torture,
8735 struct dcerpc_pipe *p2,
8739 struct dcerpc_pipe *p;
8741 struct torture_samr_context *ctx =
8742 talloc_get_type_abort(data, struct torture_samr_context);
8743 struct dcerpc_binding_handle *b;
8745 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8746 if (!NT_STATUS_IS_OK(status)) {
8749 b = p->binding_handle;
8751 ctx->choice = TORTURE_SAMR_MANY_ALIASES;
8752 ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
8753 ctx->num_objects_large_dc);
8755 ret &= test_Connect(b, torture, &ctx->handle);
8757 ret &= test_EnumDomains(p, torture, ctx);
8759 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8764 struct torture_suite *torture_rpc_samr_large_dc(TALLOC_CTX *mem_ctx)
8766 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.large-dc");
8767 struct torture_rpc_tcase *tcase;
8768 struct torture_samr_context *ctx;
8770 tcase = torture_suite_add_rpc_iface_tcase(suite, "samr", &ndr_table_samr);
8772 ctx = talloc_zero(suite, struct torture_samr_context);
8773 ctx->num_objects_large_dc = 150;
8775 torture_rpc_tcase_add_test_ex(tcase, "many_aliases",
8776 torture_rpc_samr_many_aliases, ctx);
8777 torture_rpc_tcase_add_test_ex(tcase, "many_groups",
8778 torture_rpc_samr_many_groups, ctx);
8779 torture_rpc_tcase_add_test_ex(tcase, "many_accounts",
8780 torture_rpc_samr_many_accounts, ctx);
8785 static bool torture_rpc_samr_badpwdcount(struct torture_context *torture,
8786 struct dcerpc_pipe *p2,
8787 struct cli_credentials *machine_credentials)
8790 struct dcerpc_pipe *p;
8792 struct torture_samr_context *ctx;
8793 struct dcerpc_binding_handle *b;
8795 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8796 if (!NT_STATUS_IS_OK(status)) {
8799 b = p->binding_handle;
8801 ctx = talloc_zero(torture, struct torture_samr_context);
8803 ctx->choice = TORTURE_SAMR_PASSWORDS_BADPWDCOUNT;
8804 ctx->machine_credentials = machine_credentials;
8806 ret &= test_Connect(b, torture, &ctx->handle);
8808 ret &= test_EnumDomains(p, torture, ctx);
8810 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8815 struct torture_suite *torture_rpc_samr_passwords_badpwdcount(TALLOC_CTX *mem_ctx)
8817 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.passwords.badpwdcount");
8818 struct torture_rpc_tcase *tcase;
8820 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8822 TEST_ACCOUNT_NAME_PWD);
8824 torture_rpc_tcase_add_test_creds(tcase, "badPwdCount",
8825 torture_rpc_samr_badpwdcount);
8830 static bool torture_rpc_samr_lockout(struct torture_context *torture,
8831 struct dcerpc_pipe *p2,
8832 struct cli_credentials *machine_credentials)
8835 struct dcerpc_pipe *p;
8837 struct torture_samr_context *ctx;
8838 struct dcerpc_binding_handle *b;
8840 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8841 if (!NT_STATUS_IS_OK(status)) {
8844 b = p->binding_handle;
8846 ctx = talloc_zero(torture, struct torture_samr_context);
8848 ctx->choice = TORTURE_SAMR_PASSWORDS_LOCKOUT;
8849 ctx->machine_credentials = machine_credentials;
8851 ret &= test_Connect(b, torture, &ctx->handle);
8853 ret &= test_EnumDomains(p, torture, ctx);
8855 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8860 struct torture_suite *torture_rpc_samr_passwords_lockout(TALLOC_CTX *mem_ctx)
8862 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.passwords.lockout");
8863 struct torture_rpc_tcase *tcase;
8865 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8867 TEST_ACCOUNT_NAME_PWD);
8869 torture_rpc_tcase_add_test_creds(tcase, "lockout",
8870 torture_rpc_samr_lockout);
8875 struct torture_suite *torture_rpc_samr_passwords_validate(TALLOC_CTX *mem_ctx)
8877 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.passwords.validate");
8878 struct torture_rpc_tcase *tcase;
8880 tcase = torture_suite_add_rpc_iface_tcase(suite, "samr",
8882 torture_rpc_tcase_add_test(tcase, "validate",
8883 test_samr_ValidatePassword);