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
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "torture/torture.h"
24 #include "system/time.h"
25 #include "librpc/gen_ndr/lsa.h"
26 #include "librpc/gen_ndr/ndr_netlogon.h"
27 #include "librpc/gen_ndr/ndr_netlogon_c.h"
28 #include "librpc/gen_ndr/ndr_samr_c.h"
29 #include "../lib/crypto/crypto.h"
30 #include "libcli/auth/libcli_auth.h"
31 #include "libcli/security/security.h"
32 #include "torture/rpc/rpc.h"
33 #include "param/param.h"
37 #define TEST_ACCOUNT_NAME "samrtorturetest"
38 #define TEST_ACCOUNT_NAME_PWD "samrpwdlastset"
39 #define TEST_ALIASNAME "samrtorturetestalias"
40 #define TEST_GROUPNAME "samrtorturetestgroup"
41 #define TEST_MACHINENAME "samrtestmach$"
42 #define TEST_DOMAINNAME "samrtestdom$"
44 enum torture_samr_choice {
45 TORTURE_SAMR_PASSWORDS,
46 TORTURE_SAMR_PASSWORDS_PWDLASTSET,
47 TORTURE_SAMR_USER_ATTRIBUTES,
51 static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
52 struct policy_handle *handle);
54 static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
55 struct policy_handle *handle);
57 static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
58 struct policy_handle *handle);
60 static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
61 const char *acct_name,
62 struct policy_handle *domain_handle, char **password);
64 static void init_lsa_String(struct lsa_String *string, const char *s)
69 static void init_lsa_BinaryString(struct lsa_BinaryString *string, const char *s, uint32_t length)
71 string->length = length;
72 string->size = length;
73 string->array = (uint16_t *)discard_const(s);
76 bool test_samr_handle_Close(struct dcerpc_pipe *p, struct torture_context *tctx,
77 struct policy_handle *handle)
83 r.out.handle = handle;
85 status = dcerpc_samr_Close(p, tctx, &r);
86 torture_assert_ntstatus_ok(tctx, status, "Close");
91 static bool test_Shutdown(struct dcerpc_pipe *p, struct torture_context *tctx,
92 struct policy_handle *handle)
95 struct samr_Shutdown r;
97 if (!torture_setting_bool(tctx, "dangerous", false)) {
98 torture_skip(tctx, "samr_Shutdown disabled - enable dangerous tests to use\n");
102 r.in.connect_handle = handle;
104 torture_comment(tctx, "testing samr_Shutdown\n");
106 status = dcerpc_samr_Shutdown(p, tctx, &r);
107 torture_assert_ntstatus_ok(tctx, status, "samr_Shutdown");
112 static bool test_SetDsrmPassword(struct dcerpc_pipe *p, struct torture_context *tctx,
113 struct policy_handle *handle)
116 struct samr_SetDsrmPassword r;
117 struct lsa_String string;
118 struct samr_Password hash;
120 if (!torture_setting_bool(tctx, "dangerous", false)) {
121 torture_skip(tctx, "samr_SetDsrmPassword disabled - enable dangerous tests to use");
124 E_md4hash("TeSTDSRM123", hash.hash);
126 init_lsa_String(&string, "Administrator");
132 torture_comment(tctx, "testing samr_SetDsrmPassword\n");
134 status = dcerpc_samr_SetDsrmPassword(p, tctx, &r);
135 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_SUPPORTED, "samr_SetDsrmPassword");
141 static bool test_QuerySecurity(struct dcerpc_pipe *p,
142 struct torture_context *tctx,
143 struct policy_handle *handle)
146 struct samr_QuerySecurity r;
147 struct samr_SetSecurity s;
148 struct sec_desc_buf *sdbuf = NULL;
150 r.in.handle = handle;
152 r.out.sdbuf = &sdbuf;
154 status = dcerpc_samr_QuerySecurity(p, tctx, &r);
155 torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
157 torture_assert(tctx, sdbuf != NULL, "sdbuf is NULL");
159 s.in.handle = handle;
163 if (torture_setting_bool(tctx, "samba4", false)) {
164 torture_skip(tctx, "skipping SetSecurity test against Samba4\n");
167 status = dcerpc_samr_SetSecurity(p, tctx, &s);
168 torture_assert_ntstatus_ok(tctx, status, "SetSecurity");
170 status = dcerpc_samr_QuerySecurity(p, tctx, &r);
171 torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
177 static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
178 struct policy_handle *handle, uint32_t base_acct_flags,
179 const char *base_account_name)
182 struct samr_SetUserInfo s;
183 struct samr_SetUserInfo2 s2;
184 struct samr_QueryUserInfo q;
185 struct samr_QueryUserInfo q0;
186 union samr_UserInfo u;
187 union samr_UserInfo *info;
189 const char *test_account_name;
191 uint32_t user_extra_flags = 0;
192 if (base_acct_flags == ACB_NORMAL) {
193 /* When created, accounts are expired by default */
194 user_extra_flags = ACB_PW_EXPIRED;
197 s.in.user_handle = handle;
200 s2.in.user_handle = handle;
203 q.in.user_handle = handle;
207 #define TESTCALL(call, r) \
208 status = dcerpc_samr_ ##call(p, tctx, &r); \
209 if (!NT_STATUS_IS_OK(status)) { \
210 torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
211 r.in.level, nt_errstr(status), __location__); \
216 #define STRING_EQUAL(s1, s2, field) \
217 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
218 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
219 #field, s2, __location__); \
224 #define MEM_EQUAL(s1, s2, length, field) \
225 if ((s1 && !s2) || (s2 && !s1) || memcmp(s1, s2, length)) { \
226 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
227 #field, (const char *)s2, __location__); \
232 #define INT_EQUAL(i1, i2, field) \
234 torture_comment(tctx, "Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \
235 #field, (unsigned long long)i2, (unsigned long long)i1, __location__); \
240 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
241 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
243 TESTCALL(QueryUserInfo, q) \
245 s2.in.level = lvl1; \
248 ZERO_STRUCT(u.info21); \
249 u.info21.fields_present = fpval; \
251 init_lsa_String(&u.info ## lvl1.field1, value); \
252 TESTCALL(SetUserInfo, s) \
253 TESTCALL(SetUserInfo2, s2) \
254 init_lsa_String(&u.info ## lvl1.field1, ""); \
255 TESTCALL(QueryUserInfo, q); \
257 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
259 TESTCALL(QueryUserInfo, q) \
261 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
264 #define TEST_USERINFO_BINARYSTRING(lvl1, field1, lvl2, field2, value, fpval) do { \
265 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
267 TESTCALL(QueryUserInfo, q) \
269 s2.in.level = lvl1; \
272 ZERO_STRUCT(u.info21); \
273 u.info21.fields_present = fpval; \
275 init_lsa_BinaryString(&u.info ## lvl1.field1, value, strlen(value)); \
276 TESTCALL(SetUserInfo, s) \
277 TESTCALL(SetUserInfo2, s2) \
278 init_lsa_BinaryString(&u.info ## lvl1.field1, "", 1); \
279 TESTCALL(QueryUserInfo, q); \
281 MEM_EQUAL(u.info ## lvl1.field1.array, value, strlen(value), field1); \
283 TESTCALL(QueryUserInfo, q) \
285 MEM_EQUAL(u.info ## lvl2.field2.array, value, strlen(value), field2); \
288 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
289 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
291 TESTCALL(QueryUserInfo, q) \
293 s2.in.level = lvl1; \
296 uint8_t *bits = u.info21.logon_hours.bits; \
297 ZERO_STRUCT(u.info21); \
298 if (fpval == SAMR_FIELD_LOGON_HOURS) { \
299 u.info21.logon_hours.units_per_week = 168; \
300 u.info21.logon_hours.bits = bits; \
302 u.info21.fields_present = fpval; \
304 u.info ## lvl1.field1 = value; \
305 TESTCALL(SetUserInfo, s) \
306 TESTCALL(SetUserInfo2, s2) \
307 u.info ## lvl1.field1 = 0; \
308 TESTCALL(QueryUserInfo, q); \
310 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
312 TESTCALL(QueryUserInfo, q) \
314 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
317 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
318 TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
322 do { TESTCALL(QueryUserInfo, q0) } while (0);
324 /* Samba 3 cannot store comment fields atm. - gd */
325 if (!torture_setting_bool(tctx, "samba3", false)) {
326 TEST_USERINFO_STRING(2, comment, 1, comment, "xx2-1 comment", 0);
327 TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
328 TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment",
332 test_account_name = talloc_asprintf(tctx, "%sxx7-1", base_account_name);
333 TEST_USERINFO_STRING(7, account_name, 1, account_name, base_account_name, 0);
334 test_account_name = talloc_asprintf(tctx, "%sxx7-3", base_account_name);
335 TEST_USERINFO_STRING(7, account_name, 3, account_name, base_account_name, 0);
336 test_account_name = talloc_asprintf(tctx, "%sxx7-5", base_account_name);
337 TEST_USERINFO_STRING(7, account_name, 5, account_name, base_account_name, 0);
338 test_account_name = talloc_asprintf(tctx, "%sxx7-6", base_account_name);
339 TEST_USERINFO_STRING(7, account_name, 6, account_name, base_account_name, 0);
340 test_account_name = talloc_asprintf(tctx, "%sxx7-7", base_account_name);
341 TEST_USERINFO_STRING(7, account_name, 7, account_name, base_account_name, 0);
342 test_account_name = talloc_asprintf(tctx, "%sxx7-21", base_account_name);
343 TEST_USERINFO_STRING(7, account_name, 21, account_name, base_account_name, 0);
344 test_account_name = base_account_name;
345 TEST_USERINFO_STRING(21, account_name, 21, account_name, base_account_name,
346 SAMR_FIELD_ACCOUNT_NAME);
348 TEST_USERINFO_STRING(6, full_name, 1, full_name, "xx6-1 full_name", 0);
349 TEST_USERINFO_STRING(6, full_name, 3, full_name, "xx6-3 full_name", 0);
350 TEST_USERINFO_STRING(6, full_name, 5, full_name, "xx6-5 full_name", 0);
351 TEST_USERINFO_STRING(6, full_name, 6, full_name, "xx6-6 full_name", 0);
352 TEST_USERINFO_STRING(6, full_name, 8, full_name, "xx6-8 full_name", 0);
353 TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
354 TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
355 TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name",
356 SAMR_FIELD_FULL_NAME);
358 TEST_USERINFO_STRING(6, full_name, 1, full_name, "", 0);
359 TEST_USERINFO_STRING(6, full_name, 3, full_name, "", 0);
360 TEST_USERINFO_STRING(6, full_name, 5, full_name, "", 0);
361 TEST_USERINFO_STRING(6, full_name, 6, full_name, "", 0);
362 TEST_USERINFO_STRING(6, full_name, 8, full_name, "", 0);
363 TEST_USERINFO_STRING(6, full_name, 21, full_name, "", 0);
364 TEST_USERINFO_STRING(8, full_name, 21, full_name, "", 0);
365 TEST_USERINFO_STRING(21, full_name, 21, full_name, "",
366 SAMR_FIELD_FULL_NAME);
368 TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
369 TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
370 TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
371 TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script",
372 SAMR_FIELD_LOGON_SCRIPT);
374 TEST_USERINFO_STRING(12, profile_path, 3, profile_path, "xx12-3 profile_path", 0);
375 TEST_USERINFO_STRING(12, profile_path, 5, profile_path, "xx12-5 profile_path", 0);
376 TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
377 TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path",
378 SAMR_FIELD_PROFILE_PATH);
380 TEST_USERINFO_STRING(10, home_directory, 3, home_directory, "xx10-3 home_directory", 0);
381 TEST_USERINFO_STRING(10, home_directory, 5, home_directory, "xx10-5 home_directory", 0);
382 TEST_USERINFO_STRING(10, home_directory, 21, home_directory, "xx10-21 home_directory", 0);
383 TEST_USERINFO_STRING(21, home_directory, 21, home_directory, "xx21-21 home_directory",
384 SAMR_FIELD_HOME_DIRECTORY);
385 TEST_USERINFO_STRING(21, home_directory, 10, home_directory, "xx21-10 home_directory",
386 SAMR_FIELD_HOME_DIRECTORY);
388 TEST_USERINFO_STRING(10, home_drive, 3, home_drive, "xx10-3 home_drive", 0);
389 TEST_USERINFO_STRING(10, home_drive, 5, home_drive, "xx10-5 home_drive", 0);
390 TEST_USERINFO_STRING(10, home_drive, 21, home_drive, "xx10-21 home_drive", 0);
391 TEST_USERINFO_STRING(21, home_drive, 21, home_drive, "xx21-21 home_drive",
392 SAMR_FIELD_HOME_DRIVE);
393 TEST_USERINFO_STRING(21, home_drive, 10, home_drive, "xx21-10 home_drive",
394 SAMR_FIELD_HOME_DRIVE);
396 TEST_USERINFO_STRING(13, description, 1, description, "xx13-1 description", 0);
397 TEST_USERINFO_STRING(13, description, 5, description, "xx13-5 description", 0);
398 TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
399 TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description",
400 SAMR_FIELD_DESCRIPTION);
402 TEST_USERINFO_STRING(14, workstations, 3, workstations, "14workstation3", 0);
403 TEST_USERINFO_STRING(14, workstations, 5, workstations, "14workstation4", 0);
404 TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
405 TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21",
406 SAMR_FIELD_WORKSTATIONS);
407 TEST_USERINFO_STRING(21, workstations, 3, workstations, "21workstation3",
408 SAMR_FIELD_WORKSTATIONS);
409 TEST_USERINFO_STRING(21, workstations, 5, workstations, "21workstation5",
410 SAMR_FIELD_WORKSTATIONS);
411 TEST_USERINFO_STRING(21, workstations, 14, workstations, "21workstation14",
412 SAMR_FIELD_WORKSTATIONS);
414 TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
415 TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "xx21-21 parameters",
416 SAMR_FIELD_PARAMETERS);
417 TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "xx21-20 parameters",
418 SAMR_FIELD_PARAMETERS);
419 /* also empty user parameters are allowed */
420 TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "", 0);
421 TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "",
422 SAMR_FIELD_PARAMETERS);
423 TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "",
424 SAMR_FIELD_PARAMETERS);
426 /* Samba 3 cannot store country_code and copy_page atm. - gd */
427 if (!torture_setting_bool(tctx, "samba3", false)) {
428 TEST_USERINFO_INT(2, country_code, 2, country_code, __LINE__, 0);
429 TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
430 TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__,
431 SAMR_FIELD_COUNTRY_CODE);
432 TEST_USERINFO_INT(21, country_code, 2, country_code, __LINE__,
433 SAMR_FIELD_COUNTRY_CODE);
435 TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
436 TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__,
437 SAMR_FIELD_CODE_PAGE);
438 TEST_USERINFO_INT(21, code_page, 2, code_page, __LINE__,
439 SAMR_FIELD_CODE_PAGE);
442 if (!torture_setting_bool(tctx, "samba3", false)) {
443 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, __LINE__, 0);
444 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, __LINE__, 0);
445 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, __LINE__,
446 SAMR_FIELD_ACCT_EXPIRY);
447 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, __LINE__,
448 SAMR_FIELD_ACCT_EXPIRY);
449 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, __LINE__,
450 SAMR_FIELD_ACCT_EXPIRY);
452 /* Samba 3 can only store seconds / time_t in passdb - gd */
454 unix_to_nt_time(&nt, time(NULL) + __LINE__);
455 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, nt, 0);
456 unix_to_nt_time(&nt, time(NULL) + __LINE__);
457 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, nt, 0);
458 unix_to_nt_time(&nt, time(NULL) + __LINE__);
459 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
460 unix_to_nt_time(&nt, time(NULL) + __LINE__);
461 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
462 unix_to_nt_time(&nt, time(NULL) + __LINE__);
463 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
466 TEST_USERINFO_INT(4, logon_hours.bits[3], 3, logon_hours.bits[3], 1, 0);
467 TEST_USERINFO_INT(4, logon_hours.bits[3], 5, logon_hours.bits[3], 2, 0);
468 TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
469 TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4,
470 SAMR_FIELD_LOGON_HOURS);
472 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
473 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
474 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
476 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
477 (base_acct_flags | ACB_DISABLED),
478 (base_acct_flags | ACB_DISABLED | user_extra_flags),
481 /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
482 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
483 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
484 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
486 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
487 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
488 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
492 /* The 'autolock' flag doesn't stick - check this */
493 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
494 (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK),
495 (base_acct_flags | ACB_DISABLED | user_extra_flags),
498 /* Removing the 'disabled' flag doesn't stick - check this */
499 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
501 (base_acct_flags | ACB_DISABLED | user_extra_flags),
504 /* The 'store plaintext' flag does stick */
505 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
506 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED),
507 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags),
509 /* The 'use DES' flag does stick */
510 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
511 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY),
512 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags),
514 /* The 'don't require kerberos pre-authentication flag does stick */
515 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
516 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH),
517 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags),
519 /* The 'no kerberos PAC required' flag sticks */
520 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
521 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD),
522 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags),
525 TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags,
526 (base_acct_flags | ACB_DISABLED),
527 (base_acct_flags | ACB_DISABLED | user_extra_flags),
528 SAMR_FIELD_ACCT_FLAGS);
531 /* these fail with win2003 - it appears you can't set the primary gid?
532 the set succeeds, but the gid isn't changed. Very weird! */
533 TEST_USERINFO_INT(9, primary_gid, 1, primary_gid, 513);
534 TEST_USERINFO_INT(9, primary_gid, 3, primary_gid, 513);
535 TEST_USERINFO_INT(9, primary_gid, 5, primary_gid, 513);
536 TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
543 generate a random password for password change tests
545 static char *samr_rand_pass_silent(TALLOC_CTX *mem_ctx, int min_len)
547 size_t len = MAX(8, min_len) + (random() % 6);
548 char *s = generate_random_str(mem_ctx, len);
552 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
554 char *s = samr_rand_pass_silent(mem_ctx, min_len);
555 printf("Generated password '%s'\n", s);
561 generate a random password for password change tests
563 static DATA_BLOB samr_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
566 DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
567 generate_random_buffer(password.data, password.length);
569 for (i=0; i < len; i++) {
570 if (((uint16_t *)password.data)[i] == 0) {
571 ((uint16_t *)password.data)[i] = 1;
579 generate a random password for password change tests (fixed length)
581 static char *samr_rand_pass_fixed_len(TALLOC_CTX *mem_ctx, int len)
583 char *s = generate_random_str(mem_ctx, len);
584 printf("Generated password '%s'\n", s);
588 static bool test_SetUserPass(struct dcerpc_pipe *p, struct torture_context *tctx,
589 struct policy_handle *handle, char **password)
592 struct samr_SetUserInfo s;
593 union samr_UserInfo u;
595 DATA_BLOB session_key;
597 struct samr_GetUserPwInfo pwp;
598 struct samr_PwInfo info;
599 int policy_min_pw_len = 0;
600 pwp.in.user_handle = handle;
601 pwp.out.info = &info;
603 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
604 if (NT_STATUS_IS_OK(status)) {
605 policy_min_pw_len = pwp.out.info->min_password_length;
607 newpass = samr_rand_pass(tctx, policy_min_pw_len);
609 s.in.user_handle = handle;
613 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
614 u.info24.password_expired = 0;
616 status = dcerpc_fetch_session_key(p, &session_key);
617 if (!NT_STATUS_IS_OK(status)) {
618 printf("SetUserInfo level %u - no session key - %s\n",
619 s.in.level, nt_errstr(status));
623 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
625 torture_comment(tctx, "Testing SetUserInfo level 24 (set password)\n");
627 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
628 if (!NT_STATUS_IS_OK(status)) {
629 printf("SetUserInfo level %u failed - %s\n",
630 s.in.level, nt_errstr(status));
640 static bool test_SetUserPass_23(struct dcerpc_pipe *p, struct torture_context *tctx,
641 struct policy_handle *handle, uint32_t fields_present,
645 struct samr_SetUserInfo s;
646 union samr_UserInfo u;
648 DATA_BLOB session_key;
650 struct samr_GetUserPwInfo pwp;
651 struct samr_PwInfo info;
652 int policy_min_pw_len = 0;
653 pwp.in.user_handle = handle;
654 pwp.out.info = &info;
656 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
657 if (NT_STATUS_IS_OK(status)) {
658 policy_min_pw_len = pwp.out.info->min_password_length;
660 newpass = samr_rand_pass(tctx, policy_min_pw_len);
662 s.in.user_handle = handle;
668 u.info23.info.fields_present = fields_present;
670 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
672 status = dcerpc_fetch_session_key(p, &session_key);
673 if (!NT_STATUS_IS_OK(status)) {
674 printf("SetUserInfo level %u - no session key - %s\n",
675 s.in.level, nt_errstr(status));
679 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
681 torture_comment(tctx, "Testing SetUserInfo level 23 (set password)\n");
683 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
684 if (!NT_STATUS_IS_OK(status)) {
685 printf("SetUserInfo level %u failed - %s\n",
686 s.in.level, nt_errstr(status));
692 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
694 status = dcerpc_fetch_session_key(p, &session_key);
695 if (!NT_STATUS_IS_OK(status)) {
696 printf("SetUserInfo level %u - no session key - %s\n",
697 s.in.level, nt_errstr(status));
701 /* This should break the key nicely */
702 session_key.length--;
703 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
705 torture_comment(tctx, "Testing SetUserInfo level 23 (set password) with wrong password\n");
707 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
708 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
709 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
710 s.in.level, nt_errstr(status));
718 static bool test_SetUserPassEx(struct dcerpc_pipe *p, struct torture_context *tctx,
719 struct policy_handle *handle, bool makeshort,
723 struct samr_SetUserInfo s;
724 union samr_UserInfo u;
726 DATA_BLOB session_key;
727 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
728 uint8_t confounder[16];
730 struct MD5Context ctx;
731 struct samr_GetUserPwInfo pwp;
732 struct samr_PwInfo info;
733 int policy_min_pw_len = 0;
734 pwp.in.user_handle = handle;
735 pwp.out.info = &info;
737 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
738 if (NT_STATUS_IS_OK(status)) {
739 policy_min_pw_len = pwp.out.info->min_password_length;
741 if (makeshort && policy_min_pw_len) {
742 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len - 1);
744 newpass = samr_rand_pass(tctx, policy_min_pw_len);
747 s.in.user_handle = handle;
751 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
752 u.info26.password_expired = 0;
754 status = dcerpc_fetch_session_key(p, &session_key);
755 if (!NT_STATUS_IS_OK(status)) {
756 printf("SetUserInfo level %u - no session key - %s\n",
757 s.in.level, nt_errstr(status));
761 generate_random_buffer((uint8_t *)confounder, 16);
764 MD5Update(&ctx, confounder, 16);
765 MD5Update(&ctx, session_key.data, session_key.length);
766 MD5Final(confounded_session_key.data, &ctx);
768 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
769 memcpy(&u.info26.password.data[516], confounder, 16);
771 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex)\n");
773 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
774 if (!NT_STATUS_IS_OK(status)) {
775 printf("SetUserInfo level %u failed - %s\n",
776 s.in.level, nt_errstr(status));
782 /* This should break the key nicely */
783 confounded_session_key.data[0]++;
785 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
786 memcpy(&u.info26.password.data[516], confounder, 16);
788 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
790 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
791 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
792 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
793 s.in.level, nt_errstr(status));
802 static bool test_SetUserPass_25(struct dcerpc_pipe *p, struct torture_context *tctx,
803 struct policy_handle *handle, uint32_t fields_present,
807 struct samr_SetUserInfo s;
808 union samr_UserInfo u;
810 DATA_BLOB session_key;
811 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
812 struct MD5Context ctx;
813 uint8_t confounder[16];
815 struct samr_GetUserPwInfo pwp;
816 struct samr_PwInfo info;
817 int policy_min_pw_len = 0;
818 pwp.in.user_handle = handle;
819 pwp.out.info = &info;
821 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
822 if (NT_STATUS_IS_OK(status)) {
823 policy_min_pw_len = pwp.out.info->min_password_length;
825 newpass = samr_rand_pass(tctx, policy_min_pw_len);
827 s.in.user_handle = handle;
833 u.info25.info.fields_present = fields_present;
835 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
837 status = dcerpc_fetch_session_key(p, &session_key);
838 if (!NT_STATUS_IS_OK(status)) {
839 printf("SetUserInfo level %u - no session key - %s\n",
840 s.in.level, nt_errstr(status));
844 generate_random_buffer((uint8_t *)confounder, 16);
847 MD5Update(&ctx, confounder, 16);
848 MD5Update(&ctx, session_key.data, session_key.length);
849 MD5Final(confounded_session_key.data, &ctx);
851 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
852 memcpy(&u.info25.password.data[516], confounder, 16);
854 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex)\n");
856 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
857 if (!NT_STATUS_IS_OK(status)) {
858 printf("SetUserInfo level %u failed - %s\n",
859 s.in.level, nt_errstr(status));
865 /* This should break the key nicely */
866 confounded_session_key.data[0]++;
868 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
869 memcpy(&u.info25.password.data[516], confounder, 16);
871 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
873 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
874 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
875 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
876 s.in.level, nt_errstr(status));
883 static bool test_SetUserPass_18(struct dcerpc_pipe *p, struct torture_context *tctx,
884 struct policy_handle *handle, char **password)
887 struct samr_SetUserInfo s;
888 union samr_UserInfo u;
890 DATA_BLOB session_key;
892 struct samr_GetUserPwInfo pwp;
893 struct samr_PwInfo info;
894 int policy_min_pw_len = 0;
895 uint8_t lm_hash[16], nt_hash[16];
897 pwp.in.user_handle = handle;
898 pwp.out.info = &info;
900 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
901 if (NT_STATUS_IS_OK(status)) {
902 policy_min_pw_len = pwp.out.info->min_password_length;
904 newpass = samr_rand_pass(tctx, policy_min_pw_len);
906 s.in.user_handle = handle;
912 u.info18.nt_pwd_active = true;
913 u.info18.lm_pwd_active = true;
915 E_md4hash(newpass, nt_hash);
916 E_deshash(newpass, lm_hash);
918 status = dcerpc_fetch_session_key(p, &session_key);
919 if (!NT_STATUS_IS_OK(status)) {
920 printf("SetUserInfo level %u - no session key - %s\n",
921 s.in.level, nt_errstr(status));
927 in = data_blob_const(nt_hash, 16);
928 out = data_blob_talloc_zero(tctx, 16);
929 sess_crypt_blob(&out, &in, &session_key, true);
930 memcpy(u.info18.nt_pwd.hash, out.data, out.length);
934 in = data_blob_const(lm_hash, 16);
935 out = data_blob_talloc_zero(tctx, 16);
936 sess_crypt_blob(&out, &in, &session_key, true);
937 memcpy(u.info18.lm_pwd.hash, out.data, out.length);
940 torture_comment(tctx, "Testing SetUserInfo level 18 (set password hash)\n");
942 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
943 if (!NT_STATUS_IS_OK(status)) {
944 printf("SetUserInfo level %u failed - %s\n",
945 s.in.level, nt_errstr(status));
954 static bool test_SetUserPass_21(struct dcerpc_pipe *p, struct torture_context *tctx,
955 struct policy_handle *handle, uint32_t fields_present,
959 struct samr_SetUserInfo s;
960 union samr_UserInfo u;
962 DATA_BLOB session_key;
964 struct samr_GetUserPwInfo pwp;
965 struct samr_PwInfo info;
966 int policy_min_pw_len = 0;
967 uint8_t lm_hash[16], nt_hash[16];
969 pwp.in.user_handle = handle;
970 pwp.out.info = &info;
972 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
973 if (NT_STATUS_IS_OK(status)) {
974 policy_min_pw_len = pwp.out.info->min_password_length;
976 newpass = samr_rand_pass(tctx, policy_min_pw_len);
978 s.in.user_handle = handle;
982 E_md4hash(newpass, nt_hash);
983 E_deshash(newpass, lm_hash);
987 u.info21.fields_present = fields_present;
989 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
990 u.info21.lm_owf_password.length = 16;
991 u.info21.lm_owf_password.size = 16;
992 u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
993 u.info21.lm_password_set = true;
996 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
997 u.info21.nt_owf_password.length = 16;
998 u.info21.nt_owf_password.size = 16;
999 u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
1000 u.info21.nt_password_set = true;
1003 status = dcerpc_fetch_session_key(p, &session_key);
1004 if (!NT_STATUS_IS_OK(status)) {
1005 printf("SetUserInfo level %u - no session key - %s\n",
1006 s.in.level, nt_errstr(status));
1010 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1012 in = data_blob_const(u.info21.lm_owf_password.array,
1013 u.info21.lm_owf_password.length);
1014 out = data_blob_talloc_zero(tctx, 16);
1015 sess_crypt_blob(&out, &in, &session_key, true);
1016 u.info21.lm_owf_password.array = (uint16_t *)out.data;
1019 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1021 in = data_blob_const(u.info21.nt_owf_password.array,
1022 u.info21.nt_owf_password.length);
1023 out = data_blob_talloc_zero(tctx, 16);
1024 sess_crypt_blob(&out, &in, &session_key, true);
1025 u.info21.nt_owf_password.array = (uint16_t *)out.data;
1028 torture_comment(tctx, "Testing SetUserInfo level 21 (set password hash)\n");
1030 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1031 if (!NT_STATUS_IS_OK(status)) {
1032 printf("SetUserInfo level %u failed - %s\n",
1033 s.in.level, nt_errstr(status));
1036 *password = newpass;
1039 /* try invalid length */
1040 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1042 u.info21.nt_owf_password.length++;
1044 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1046 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1047 printf("SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1048 s.in.level, nt_errstr(status));
1053 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1055 u.info21.lm_owf_password.length++;
1057 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1059 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1060 printf("SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1061 s.in.level, nt_errstr(status));
1069 static bool test_SetUserPass_level_ex(struct dcerpc_pipe *p,
1070 struct torture_context *tctx,
1071 struct policy_handle *handle,
1073 uint32_t fields_present,
1074 char **password, uint8_t password_expired,
1076 bool *matched_expected_error)
1079 NTSTATUS expected_error = NT_STATUS_OK;
1080 struct samr_SetUserInfo s;
1081 struct samr_SetUserInfo2 s2;
1082 union samr_UserInfo u;
1084 DATA_BLOB session_key;
1085 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
1086 struct MD5Context ctx;
1087 uint8_t confounder[16];
1089 struct samr_GetUserPwInfo pwp;
1090 struct samr_PwInfo info;
1091 int policy_min_pw_len = 0;
1092 const char *comment = NULL;
1093 uint8_t lm_hash[16], nt_hash[16];
1095 pwp.in.user_handle = handle;
1096 pwp.out.info = &info;
1098 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1099 if (NT_STATUS_IS_OK(status)) {
1100 policy_min_pw_len = pwp.out.info->min_password_length;
1102 newpass = samr_rand_pass_silent(tctx, policy_min_pw_len);
1105 s2.in.user_handle = handle;
1107 s2.in.level = level;
1109 s.in.user_handle = handle;
1114 if (fields_present & SAMR_FIELD_COMMENT) {
1115 comment = talloc_asprintf(tctx, "comment: %ld\n", time(NULL));
1122 E_md4hash(newpass, nt_hash);
1123 E_deshash(newpass, lm_hash);
1125 u.info18.nt_pwd_active = true;
1126 u.info18.lm_pwd_active = true;
1127 u.info18.password_expired = password_expired;
1129 memcpy(u.info18.lm_pwd.hash, lm_hash, 16);
1130 memcpy(u.info18.nt_pwd.hash, nt_hash, 16);
1134 E_md4hash(newpass, nt_hash);
1135 E_deshash(newpass, lm_hash);
1137 u.info21.fields_present = fields_present;
1138 u.info21.password_expired = password_expired;
1139 u.info21.comment.string = comment;
1141 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1142 u.info21.lm_owf_password.length = 16;
1143 u.info21.lm_owf_password.size = 16;
1144 u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
1145 u.info21.lm_password_set = true;
1148 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1149 u.info21.nt_owf_password.length = 16;
1150 u.info21.nt_owf_password.size = 16;
1151 u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
1152 u.info21.nt_password_set = true;
1157 u.info23.info.fields_present = fields_present;
1158 u.info23.info.password_expired = password_expired;
1159 u.info23.info.comment.string = comment;
1161 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
1165 u.info24.password_expired = password_expired;
1167 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
1171 u.info25.info.fields_present = fields_present;
1172 u.info25.info.password_expired = password_expired;
1173 u.info25.info.comment.string = comment;
1175 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
1179 u.info26.password_expired = password_expired;
1181 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
1186 status = dcerpc_fetch_session_key(p, &session_key);
1187 if (!NT_STATUS_IS_OK(status)) {
1188 printf("SetUserInfo level %u - no session key - %s\n",
1189 s.in.level, nt_errstr(status));
1193 generate_random_buffer((uint8_t *)confounder, 16);
1196 MD5Update(&ctx, confounder, 16);
1197 MD5Update(&ctx, session_key.data, session_key.length);
1198 MD5Final(confounded_session_key.data, &ctx);
1204 in = data_blob_const(u.info18.nt_pwd.hash, 16);
1205 out = data_blob_talloc_zero(tctx, 16);
1206 sess_crypt_blob(&out, &in, &session_key, true);
1207 memcpy(u.info18.nt_pwd.hash, out.data, out.length);
1211 in = data_blob_const(u.info18.lm_pwd.hash, 16);
1212 out = data_blob_talloc_zero(tctx, 16);
1213 sess_crypt_blob(&out, &in, &session_key, true);
1214 memcpy(u.info18.lm_pwd.hash, out.data, out.length);
1219 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1221 in = data_blob_const(u.info21.lm_owf_password.array,
1222 u.info21.lm_owf_password.length);
1223 out = data_blob_talloc_zero(tctx, 16);
1224 sess_crypt_blob(&out, &in, &session_key, true);
1225 u.info21.lm_owf_password.array = (uint16_t *)out.data;
1227 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1229 in = data_blob_const(u.info21.nt_owf_password.array,
1230 u.info21.nt_owf_password.length);
1231 out = data_blob_talloc_zero(tctx, 16);
1232 sess_crypt_blob(&out, &in, &session_key, true);
1233 u.info21.nt_owf_password.array = (uint16_t *)out.data;
1237 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
1240 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
1243 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
1244 memcpy(&u.info25.password.data[516], confounder, 16);
1247 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
1248 memcpy(&u.info26.password.data[516], confounder, 16);
1253 status = dcerpc_samr_SetUserInfo2(p, tctx, &s2);
1255 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1258 if (!NT_STATUS_IS_OK(status)) {
1259 if (fields_present == 0) {
1260 expected_error = NT_STATUS_INVALID_PARAMETER;
1262 if (fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
1263 expected_error = NT_STATUS_ACCESS_DENIED;
1267 if (!NT_STATUS_IS_OK(expected_error)) {
1269 torture_assert_ntstatus_equal(tctx,
1271 expected_error, "SetUserInfo2 failed");
1273 torture_assert_ntstatus_equal(tctx,
1275 expected_error, "SetUserInfo failed");
1277 *matched_expected_error = true;
1281 if (!NT_STATUS_IS_OK(status)) {
1282 printf("SetUserInfo%s level %u failed - %s\n",
1283 use_setinfo2 ? "2":"", level, nt_errstr(status));
1286 *password = newpass;
1292 static bool test_SetAliasInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1293 struct policy_handle *handle)
1296 struct samr_SetAliasInfo r;
1297 struct samr_QueryAliasInfo q;
1298 union samr_AliasInfo *info;
1299 uint16_t levels[] = {2, 3};
1303 /* Ignoring switch level 1, as that includes the number of members for the alias
1304 * and setting this to a wrong value might have negative consequences
1307 for (i=0;i<ARRAY_SIZE(levels);i++) {
1308 torture_comment(tctx, "Testing SetAliasInfo level %u\n", levels[i]);
1310 r.in.alias_handle = handle;
1311 r.in.level = levels[i];
1312 r.in.info = talloc(tctx, union samr_AliasInfo);
1313 switch (r.in.level) {
1314 case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
1315 case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
1316 "Test Description, should test I18N as well"); break;
1317 case ALIASINFOALL: printf("ALIASINFOALL ignored\n"); break;
1320 status = dcerpc_samr_SetAliasInfo(p, tctx, &r);
1321 if (!NT_STATUS_IS_OK(status)) {
1322 printf("SetAliasInfo level %u failed - %s\n",
1323 levels[i], nt_errstr(status));
1327 q.in.alias_handle = handle;
1328 q.in.level = levels[i];
1331 status = dcerpc_samr_QueryAliasInfo(p, tctx, &q);
1332 if (!NT_STATUS_IS_OK(status)) {
1333 printf("QueryAliasInfo level %u failed - %s\n",
1334 levels[i], nt_errstr(status));
1342 static bool test_GetGroupsForUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1343 struct policy_handle *user_handle)
1345 struct samr_GetGroupsForUser r;
1346 struct samr_RidWithAttributeArray *rids = NULL;
1349 torture_comment(tctx, "testing GetGroupsForUser\n");
1351 r.in.user_handle = user_handle;
1354 status = dcerpc_samr_GetGroupsForUser(p, tctx, &r);
1355 torture_assert_ntstatus_ok(tctx, status, "GetGroupsForUser");
1361 static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1362 struct lsa_String *domain_name)
1365 struct samr_GetDomPwInfo r;
1366 struct samr_PwInfo info;
1368 r.in.domain_name = domain_name;
1371 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1373 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1374 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1376 r.in.domain_name->string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1377 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1379 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1380 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1382 r.in.domain_name->string = "\\\\__NONAME__";
1383 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1385 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1386 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1388 r.in.domain_name->string = "\\\\Builtin";
1389 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1391 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1392 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1397 static bool test_GetUserPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1398 struct policy_handle *handle)
1401 struct samr_GetUserPwInfo r;
1402 struct samr_PwInfo info;
1404 torture_comment(tctx, "Testing GetUserPwInfo\n");
1406 r.in.user_handle = handle;
1409 status = dcerpc_samr_GetUserPwInfo(p, tctx, &r);
1410 torture_assert_ntstatus_ok(tctx, status, "GetUserPwInfo");
1415 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, struct torture_context *tctx,
1416 struct policy_handle *domain_handle, const char *name,
1420 struct samr_LookupNames n;
1421 struct lsa_String sname[2];
1422 struct samr_Ids rids, types;
1424 init_lsa_String(&sname[0], name);
1426 n.in.domain_handle = domain_handle;
1430 n.out.types = &types;
1431 status = dcerpc_samr_LookupNames(p, tctx, &n);
1432 if (NT_STATUS_IS_OK(status)) {
1433 *rid = n.out.rids->ids[0];
1438 init_lsa_String(&sname[1], "xxNONAMExx");
1440 status = dcerpc_samr_LookupNames(p, tctx, &n);
1441 if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
1442 printf("LookupNames[2] failed - %s\n", nt_errstr(status));
1443 if (NT_STATUS_IS_OK(status)) {
1444 return NT_STATUS_UNSUCCESSFUL;
1450 status = dcerpc_samr_LookupNames(p, tctx, &n);
1451 if (!NT_STATUS_IS_OK(status)) {
1452 printf("LookupNames[0] failed - %s\n", nt_errstr(status));
1456 init_lsa_String(&sname[0], "xxNONAMExx");
1458 status = dcerpc_samr_LookupNames(p, tctx, &n);
1459 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1460 printf("LookupNames[1 bad name] failed - %s\n", nt_errstr(status));
1461 if (NT_STATUS_IS_OK(status)) {
1462 return NT_STATUS_UNSUCCESSFUL;
1467 init_lsa_String(&sname[0], "xxNONAMExx");
1468 init_lsa_String(&sname[1], "xxNONAME2xx");
1470 status = dcerpc_samr_LookupNames(p, tctx, &n);
1471 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1472 printf("LookupNames[2 bad names] failed - %s\n", nt_errstr(status));
1473 if (NT_STATUS_IS_OK(status)) {
1474 return NT_STATUS_UNSUCCESSFUL;
1479 return NT_STATUS_OK;
1482 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1483 struct policy_handle *domain_handle,
1484 const char *name, struct policy_handle *user_handle)
1487 struct samr_OpenUser r;
1490 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
1491 if (!NT_STATUS_IS_OK(status)) {
1495 r.in.domain_handle = domain_handle;
1496 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1498 r.out.user_handle = user_handle;
1499 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
1500 if (!NT_STATUS_IS_OK(status)) {
1501 printf("OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(status));
1508 static bool test_ChangePasswordNT3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1509 struct policy_handle *handle)
1512 struct samr_ChangePasswordUser r;
1514 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1515 struct policy_handle user_handle;
1516 char *oldpass = "test";
1517 char *newpass = "test2";
1518 uint8_t old_nt_hash[16], new_nt_hash[16];
1519 uint8_t old_lm_hash[16], new_lm_hash[16];
1521 status = test_OpenUser_byname(p, mem_ctx, handle, "testuser", &user_handle);
1522 if (!NT_STATUS_IS_OK(status)) {
1526 printf("Testing ChangePasswordUser for user 'testuser'\n");
1528 printf("old password: %s\n", oldpass);
1529 printf("new password: %s\n", newpass);
1531 E_md4hash(oldpass, old_nt_hash);
1532 E_md4hash(newpass, new_nt_hash);
1533 E_deshash(oldpass, old_lm_hash);
1534 E_deshash(newpass, new_lm_hash);
1536 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1537 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1538 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1539 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1540 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1541 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1543 r.in.handle = &user_handle;
1544 r.in.lm_present = 1;
1545 r.in.old_lm_crypted = &hash1;
1546 r.in.new_lm_crypted = &hash2;
1547 r.in.nt_present = 1;
1548 r.in.old_nt_crypted = &hash3;
1549 r.in.new_nt_crypted = &hash4;
1550 r.in.cross1_present = 1;
1551 r.in.nt_cross = &hash5;
1552 r.in.cross2_present = 1;
1553 r.in.lm_cross = &hash6;
1555 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1556 if (!NT_STATUS_IS_OK(status)) {
1557 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1561 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1569 static bool test_ChangePasswordUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1570 const char *acct_name,
1571 struct policy_handle *handle, char **password)
1574 struct samr_ChangePasswordUser r;
1576 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1577 struct policy_handle user_handle;
1579 uint8_t old_nt_hash[16], new_nt_hash[16];
1580 uint8_t old_lm_hash[16], new_lm_hash[16];
1581 bool changed = true;
1584 struct samr_GetUserPwInfo pwp;
1585 struct samr_PwInfo info;
1586 int policy_min_pw_len = 0;
1588 status = test_OpenUser_byname(p, tctx, handle, acct_name, &user_handle);
1589 if (!NT_STATUS_IS_OK(status)) {
1592 pwp.in.user_handle = &user_handle;
1593 pwp.out.info = &info;
1595 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1596 if (NT_STATUS_IS_OK(status)) {
1597 policy_min_pw_len = pwp.out.info->min_password_length;
1599 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1601 torture_comment(tctx, "Testing ChangePasswordUser\n");
1603 torture_assert(tctx, *password != NULL,
1604 "Failing ChangePasswordUser as old password was NULL. Previous test failed?");
1606 oldpass = *password;
1608 E_md4hash(oldpass, old_nt_hash);
1609 E_md4hash(newpass, new_nt_hash);
1610 E_deshash(oldpass, old_lm_hash);
1611 E_deshash(newpass, new_lm_hash);
1613 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1614 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1615 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1616 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1617 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1618 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1620 r.in.user_handle = &user_handle;
1621 r.in.lm_present = 1;
1622 /* Break the LM hash */
1624 r.in.old_lm_crypted = &hash1;
1625 r.in.new_lm_crypted = &hash2;
1626 r.in.nt_present = 1;
1627 r.in.old_nt_crypted = &hash3;
1628 r.in.new_nt_crypted = &hash4;
1629 r.in.cross1_present = 1;
1630 r.in.nt_cross = &hash5;
1631 r.in.cross2_present = 1;
1632 r.in.lm_cross = &hash6;
1634 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1635 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1636 "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash");
1638 /* Unbreak the LM hash */
1641 r.in.user_handle = &user_handle;
1642 r.in.lm_present = 1;
1643 r.in.old_lm_crypted = &hash1;
1644 r.in.new_lm_crypted = &hash2;
1645 /* Break the NT hash */
1647 r.in.nt_present = 1;
1648 r.in.old_nt_crypted = &hash3;
1649 r.in.new_nt_crypted = &hash4;
1650 r.in.cross1_present = 1;
1651 r.in.nt_cross = &hash5;
1652 r.in.cross2_present = 1;
1653 r.in.lm_cross = &hash6;
1655 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1656 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1657 "expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash");
1659 /* Unbreak the NT hash */
1662 r.in.user_handle = &user_handle;
1663 r.in.lm_present = 1;
1664 r.in.old_lm_crypted = &hash1;
1665 r.in.new_lm_crypted = &hash2;
1666 r.in.nt_present = 1;
1667 r.in.old_nt_crypted = &hash3;
1668 r.in.new_nt_crypted = &hash4;
1669 r.in.cross1_present = 1;
1670 r.in.nt_cross = &hash5;
1671 r.in.cross2_present = 1;
1672 /* Break the LM cross */
1674 r.in.lm_cross = &hash6;
1676 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1677 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1678 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status));
1682 /* Unbreak the LM cross */
1685 r.in.user_handle = &user_handle;
1686 r.in.lm_present = 1;
1687 r.in.old_lm_crypted = &hash1;
1688 r.in.new_lm_crypted = &hash2;
1689 r.in.nt_present = 1;
1690 r.in.old_nt_crypted = &hash3;
1691 r.in.new_nt_crypted = &hash4;
1692 r.in.cross1_present = 1;
1693 /* Break the NT cross */
1695 r.in.nt_cross = &hash5;
1696 r.in.cross2_present = 1;
1697 r.in.lm_cross = &hash6;
1699 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1700 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1701 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status));
1705 /* Unbreak the NT cross */
1709 /* Reset the hashes to not broken values */
1710 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1711 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1712 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1713 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1714 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1715 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1717 r.in.user_handle = &user_handle;
1718 r.in.lm_present = 1;
1719 r.in.old_lm_crypted = &hash1;
1720 r.in.new_lm_crypted = &hash2;
1721 r.in.nt_present = 1;
1722 r.in.old_nt_crypted = &hash3;
1723 r.in.new_nt_crypted = &hash4;
1724 r.in.cross1_present = 1;
1725 r.in.nt_cross = &hash5;
1726 r.in.cross2_present = 0;
1727 r.in.lm_cross = NULL;
1729 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1730 if (NT_STATUS_IS_OK(status)) {
1732 *password = newpass;
1733 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1734 printf("ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(status));
1739 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1741 E_md4hash(oldpass, old_nt_hash);
1742 E_md4hash(newpass, new_nt_hash);
1743 E_deshash(oldpass, old_lm_hash);
1744 E_deshash(newpass, new_lm_hash);
1747 /* Reset the hashes to not broken values */
1748 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1749 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1750 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1751 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1752 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1753 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1755 r.in.user_handle = &user_handle;
1756 r.in.lm_present = 1;
1757 r.in.old_lm_crypted = &hash1;
1758 r.in.new_lm_crypted = &hash2;
1759 r.in.nt_present = 1;
1760 r.in.old_nt_crypted = &hash3;
1761 r.in.new_nt_crypted = &hash4;
1762 r.in.cross1_present = 0;
1763 r.in.nt_cross = NULL;
1764 r.in.cross2_present = 1;
1765 r.in.lm_cross = &hash6;
1767 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1768 if (NT_STATUS_IS_OK(status)) {
1770 *password = newpass;
1771 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1772 printf("ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status));
1777 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1779 E_md4hash(oldpass, old_nt_hash);
1780 E_md4hash(newpass, new_nt_hash);
1781 E_deshash(oldpass, old_lm_hash);
1782 E_deshash(newpass, new_lm_hash);
1785 /* Reset the hashes to not broken values */
1786 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1787 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1788 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1789 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1790 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1791 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1793 r.in.user_handle = &user_handle;
1794 r.in.lm_present = 1;
1795 r.in.old_lm_crypted = &hash1;
1796 r.in.new_lm_crypted = &hash2;
1797 r.in.nt_present = 1;
1798 r.in.old_nt_crypted = &hash3;
1799 r.in.new_nt_crypted = &hash4;
1800 r.in.cross1_present = 1;
1801 r.in.nt_cross = &hash5;
1802 r.in.cross2_present = 1;
1803 r.in.lm_cross = &hash6;
1805 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1806 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1807 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1808 } else if (!NT_STATUS_IS_OK(status)) {
1809 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1813 *password = newpass;
1816 r.in.user_handle = &user_handle;
1817 r.in.lm_present = 1;
1818 r.in.old_lm_crypted = &hash1;
1819 r.in.new_lm_crypted = &hash2;
1820 r.in.nt_present = 1;
1821 r.in.old_nt_crypted = &hash3;
1822 r.in.new_nt_crypted = &hash4;
1823 r.in.cross1_present = 1;
1824 r.in.nt_cross = &hash5;
1825 r.in.cross2_present = 1;
1826 r.in.lm_cross = &hash6;
1829 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1830 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1831 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1832 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1833 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status));
1839 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
1847 static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
1848 const char *acct_name,
1849 struct policy_handle *handle, char **password)
1852 struct samr_OemChangePasswordUser2 r;
1854 struct samr_Password lm_verifier;
1855 struct samr_CryptPassword lm_pass;
1856 struct lsa_AsciiString server, account, account_bad;
1859 uint8_t old_lm_hash[16], new_lm_hash[16];
1861 struct samr_GetDomPwInfo dom_pw_info;
1862 struct samr_PwInfo info;
1863 int policy_min_pw_len = 0;
1865 struct lsa_String domain_name;
1867 domain_name.string = "";
1868 dom_pw_info.in.domain_name = &domain_name;
1869 dom_pw_info.out.info = &info;
1871 torture_comment(tctx, "Testing OemChangePasswordUser2\n");
1873 torture_assert(tctx, *password != NULL,
1874 "Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?");
1876 oldpass = *password;
1878 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
1879 if (NT_STATUS_IS_OK(status)) {
1880 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
1883 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1885 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1886 account.string = acct_name;
1888 E_deshash(oldpass, old_lm_hash);
1889 E_deshash(newpass, new_lm_hash);
1891 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1892 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1893 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1895 r.in.server = &server;
1896 r.in.account = &account;
1897 r.in.password = &lm_pass;
1898 r.in.hash = &lm_verifier;
1900 /* Break the verification */
1901 lm_verifier.hash[0]++;
1903 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1905 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1906 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1907 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1912 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1913 /* Break the old password */
1915 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1916 /* unbreak it for the next operation */
1918 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1920 r.in.server = &server;
1921 r.in.account = &account;
1922 r.in.password = &lm_pass;
1923 r.in.hash = &lm_verifier;
1925 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1927 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1928 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1929 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1934 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1935 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1937 r.in.server = &server;
1938 r.in.account = &account;
1939 r.in.password = &lm_pass;
1942 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1944 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1945 && !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1946 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
1951 /* This shouldn't be a valid name */
1952 account_bad.string = TEST_ACCOUNT_NAME "XX";
1953 r.in.account = &account_bad;
1955 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1957 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1958 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
1963 /* This shouldn't be a valid name */
1964 account_bad.string = TEST_ACCOUNT_NAME "XX";
1965 r.in.account = &account_bad;
1966 r.in.password = &lm_pass;
1967 r.in.hash = &lm_verifier;
1969 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1971 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1972 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1977 /* This shouldn't be a valid name */
1978 account_bad.string = TEST_ACCOUNT_NAME "XX";
1979 r.in.account = &account_bad;
1980 r.in.password = NULL;
1981 r.in.hash = &lm_verifier;
1983 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1985 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1986 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
1991 E_deshash(oldpass, old_lm_hash);
1992 E_deshash(newpass, new_lm_hash);
1994 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1995 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1996 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1998 r.in.server = &server;
1999 r.in.account = &account;
2000 r.in.password = &lm_pass;
2001 r.in.hash = &lm_verifier;
2003 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
2004 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2005 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
2006 } else if (!NT_STATUS_IS_OK(status)) {
2007 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
2010 *password = newpass;
2017 static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
2018 const char *acct_name,
2020 char *newpass, bool allow_password_restriction)
2023 struct samr_ChangePasswordUser2 r;
2025 struct lsa_String server, account;
2026 struct samr_CryptPassword nt_pass, lm_pass;
2027 struct samr_Password nt_verifier, lm_verifier;
2029 uint8_t old_nt_hash[16], new_nt_hash[16];
2030 uint8_t old_lm_hash[16], new_lm_hash[16];
2032 struct samr_GetDomPwInfo dom_pw_info;
2033 struct samr_PwInfo info;
2035 struct lsa_String domain_name;
2037 domain_name.string = "";
2038 dom_pw_info.in.domain_name = &domain_name;
2039 dom_pw_info.out.info = &info;
2041 torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name);
2043 torture_assert(tctx, *password != NULL,
2044 "Failing ChangePasswordUser2 as old password was NULL. Previous test failed?");
2045 oldpass = *password;
2048 int policy_min_pw_len = 0;
2049 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
2050 if (NT_STATUS_IS_OK(status)) {
2051 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
2054 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2057 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2058 init_lsa_String(&account, acct_name);
2060 E_md4hash(oldpass, old_nt_hash);
2061 E_md4hash(newpass, new_nt_hash);
2063 E_deshash(oldpass, old_lm_hash);
2064 E_deshash(newpass, new_lm_hash);
2066 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
2067 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2068 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2070 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2071 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2072 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2074 r.in.server = &server;
2075 r.in.account = &account;
2076 r.in.nt_password = &nt_pass;
2077 r.in.nt_verifier = &nt_verifier;
2079 r.in.lm_password = &lm_pass;
2080 r.in.lm_verifier = &lm_verifier;
2082 status = dcerpc_samr_ChangePasswordUser2(p, tctx, &r);
2083 if (allow_password_restriction && NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2084 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
2085 } else if (!NT_STATUS_IS_OK(status)) {
2086 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
2089 *password = newpass;
2096 bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tctx,
2097 const char *account_string,
2098 int policy_min_pw_len,
2100 const char *newpass,
2101 NTTIME last_password_change,
2102 bool handle_reject_reason)
2105 struct samr_ChangePasswordUser3 r;
2107 struct lsa_String server, account, account_bad;
2108 struct samr_CryptPassword nt_pass, lm_pass;
2109 struct samr_Password nt_verifier, lm_verifier;
2111 uint8_t old_nt_hash[16], new_nt_hash[16];
2112 uint8_t old_lm_hash[16], new_lm_hash[16];
2114 struct samr_DomInfo1 *dominfo = NULL;
2115 struct samr_ChangeReject *reject = NULL;
2117 torture_comment(tctx, "Testing ChangePasswordUser3\n");
2119 if (newpass == NULL) {
2121 if (policy_min_pw_len == 0) {
2122 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2124 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len);
2126 } while (check_password_quality(newpass) == false);
2128 torture_comment(tctx, "Using password '%s'\n", newpass);
2131 torture_assert(tctx, *password != NULL,
2132 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2134 oldpass = *password;
2135 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2136 init_lsa_String(&account, account_string);
2138 E_md4hash(oldpass, old_nt_hash);
2139 E_md4hash(newpass, new_nt_hash);
2141 E_deshash(oldpass, old_lm_hash);
2142 E_deshash(newpass, new_lm_hash);
2144 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2145 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2146 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2148 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2149 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2150 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2152 /* Break the verification */
2153 nt_verifier.hash[0]++;
2155 r.in.server = &server;
2156 r.in.account = &account;
2157 r.in.nt_password = &nt_pass;
2158 r.in.nt_verifier = &nt_verifier;
2160 r.in.lm_password = &lm_pass;
2161 r.in.lm_verifier = &lm_verifier;
2162 r.in.password3 = NULL;
2163 r.out.dominfo = &dominfo;
2164 r.out.reject = &reject;
2166 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2167 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
2168 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
2169 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
2174 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2175 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2176 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2178 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2179 /* Break the NT hash */
2181 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2182 /* Unbreak it again */
2184 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2186 r.in.server = &server;
2187 r.in.account = &account;
2188 r.in.nt_password = &nt_pass;
2189 r.in.nt_verifier = &nt_verifier;
2191 r.in.lm_password = &lm_pass;
2192 r.in.lm_verifier = &lm_verifier;
2193 r.in.password3 = NULL;
2194 r.out.dominfo = &dominfo;
2195 r.out.reject = &reject;
2197 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2198 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
2199 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
2200 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
2205 /* This shouldn't be a valid name */
2206 init_lsa_String(&account_bad, talloc_asprintf(tctx, "%sXX", account_string));
2208 r.in.account = &account_bad;
2209 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2210 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
2211 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
2216 E_md4hash(oldpass, old_nt_hash);
2217 E_md4hash(newpass, new_nt_hash);
2219 E_deshash(oldpass, old_lm_hash);
2220 E_deshash(newpass, new_lm_hash);
2222 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2223 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2224 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2226 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2227 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2228 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2230 r.in.server = &server;
2231 r.in.account = &account;
2232 r.in.nt_password = &nt_pass;
2233 r.in.nt_verifier = &nt_verifier;
2235 r.in.lm_password = &lm_pass;
2236 r.in.lm_verifier = &lm_verifier;
2237 r.in.password3 = NULL;
2238 r.out.dominfo = &dominfo;
2239 r.out.reject = &reject;
2241 unix_to_nt_time(&t, time(NULL));
2243 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2245 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
2248 && handle_reject_reason
2249 && (!null_nttime(last_password_change) || !dominfo->min_password_age)) {
2250 if (dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
2252 if (reject && (reject->reason != SAMR_REJECT_OTHER)) {
2253 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2254 SAMR_REJECT_OTHER, reject->reason);
2259 /* We tested the order of precendence which is as follows:
2268 if ((dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
2269 (last_password_change + dominfo->min_password_age > t)) {
2271 if (reject->reason != SAMR_REJECT_OTHER) {
2272 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2273 SAMR_REJECT_OTHER, reject->reason);
2277 } else if ((dominfo->min_password_length > 0) &&
2278 (strlen(newpass) < dominfo->min_password_length)) {
2280 if (reject->reason != SAMR_REJECT_TOO_SHORT) {
2281 printf("expected SAMR_REJECT_TOO_SHORT (%d), got %d\n",
2282 SAMR_REJECT_TOO_SHORT, reject->reason);
2286 } else if ((dominfo->password_history_length > 0) &&
2287 strequal(oldpass, newpass)) {
2289 if (reject->reason != SAMR_REJECT_IN_HISTORY) {
2290 printf("expected SAMR_REJECT_IN_HISTORY (%d), got %d\n",
2291 SAMR_REJECT_IN_HISTORY, reject->reason);
2294 } else if (dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
2296 if (reject->reason != SAMR_REJECT_COMPLEXITY) {
2297 printf("expected SAMR_REJECT_COMPLEXITY (%d), got %d\n",
2298 SAMR_REJECT_COMPLEXITY, reject->reason);
2304 if (reject->reason == SAMR_REJECT_TOO_SHORT) {
2305 /* retry with adjusted size */
2306 return test_ChangePasswordUser3(p, tctx, account_string,
2307 dominfo->min_password_length,
2308 password, NULL, 0, false);
2312 } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2313 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2314 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2315 SAMR_REJECT_OTHER, reject->reason);
2318 /* Perhaps the server has a 'min password age' set? */
2321 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3");
2322 *password = talloc_strdup(tctx, newpass);
2328 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_context *tctx,
2329 const char *account_string,
2330 struct policy_handle *handle,
2334 struct samr_ChangePasswordUser3 r;
2335 struct samr_SetUserInfo s;
2336 union samr_UserInfo u;
2337 DATA_BLOB session_key;
2338 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
2339 uint8_t confounder[16];
2340 struct MD5Context ctx;
2343 struct lsa_String server, account;
2344 struct samr_CryptPassword nt_pass;
2345 struct samr_Password nt_verifier;
2346 DATA_BLOB new_random_pass;
2349 uint8_t old_nt_hash[16], new_nt_hash[16];
2351 struct samr_DomInfo1 *dominfo = NULL;
2352 struct samr_ChangeReject *reject = NULL;
2354 new_random_pass = samr_very_rand_pass(tctx, 128);
2356 torture_assert(tctx, *password != NULL,
2357 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2359 oldpass = *password;
2360 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2361 init_lsa_String(&account, account_string);
2363 s.in.user_handle = handle;
2369 u.info25.info.fields_present = SAMR_FIELD_NT_PASSWORD_PRESENT;
2371 set_pw_in_buffer(u.info25.password.data, &new_random_pass);
2373 status = dcerpc_fetch_session_key(p, &session_key);
2374 if (!NT_STATUS_IS_OK(status)) {
2375 printf("SetUserInfo level %u - no session key - %s\n",
2376 s.in.level, nt_errstr(status));
2380 generate_random_buffer((uint8_t *)confounder, 16);
2383 MD5Update(&ctx, confounder, 16);
2384 MD5Update(&ctx, session_key.data, session_key.length);
2385 MD5Final(confounded_session_key.data, &ctx);
2387 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
2388 memcpy(&u.info25.password.data[516], confounder, 16);
2390 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
2392 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
2393 if (!NT_STATUS_IS_OK(status)) {
2394 printf("SetUserInfo level %u failed - %s\n",
2395 s.in.level, nt_errstr(status));
2399 torture_comment(tctx, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
2401 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2403 new_random_pass = samr_very_rand_pass(tctx, 128);
2405 mdfour(new_nt_hash, new_random_pass.data, new_random_pass.length);
2407 set_pw_in_buffer(nt_pass.data, &new_random_pass);
2408 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2409 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2411 r.in.server = &server;
2412 r.in.account = &account;
2413 r.in.nt_password = &nt_pass;
2414 r.in.nt_verifier = &nt_verifier;
2416 r.in.lm_password = NULL;
2417 r.in.lm_verifier = NULL;
2418 r.in.password3 = NULL;
2419 r.out.dominfo = &dominfo;
2420 r.out.reject = &reject;
2422 unix_to_nt_time(&t, time(NULL));
2424 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2426 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2427 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2428 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2429 SAMR_REJECT_OTHER, reject->reason);
2432 /* Perhaps the server has a 'min password age' set? */
2434 } else if (!NT_STATUS_IS_OK(status)) {
2435 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
2439 newpass = samr_rand_pass(tctx, 128);
2441 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2443 E_md4hash(newpass, new_nt_hash);
2445 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2446 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2447 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2449 r.in.server = &server;
2450 r.in.account = &account;
2451 r.in.nt_password = &nt_pass;
2452 r.in.nt_verifier = &nt_verifier;
2454 r.in.lm_password = NULL;
2455 r.in.lm_verifier = NULL;
2456 r.in.password3 = NULL;
2457 r.out.dominfo = &dominfo;
2458 r.out.reject = &reject;
2460 unix_to_nt_time(&t, time(NULL));
2462 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2464 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2465 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2466 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2467 SAMR_REJECT_OTHER, reject->reason);
2470 /* Perhaps the server has a 'min password age' set? */
2473 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3 (on second random password)");
2474 *password = talloc_strdup(tctx, newpass);
2481 static bool test_GetMembersInAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2482 struct policy_handle *alias_handle)
2484 struct samr_GetMembersInAlias r;
2485 struct lsa_SidArray sids;
2488 torture_comment(tctx, "Testing GetMembersInAlias\n");
2490 r.in.alias_handle = alias_handle;
2493 status = dcerpc_samr_GetMembersInAlias(p, tctx, &r);
2494 torture_assert_ntstatus_ok(tctx, status, "GetMembersInAlias");
2499 static bool test_AddMemberToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2500 struct policy_handle *alias_handle,
2501 const struct dom_sid *domain_sid)
2503 struct samr_AddAliasMember r;
2504 struct samr_DeleteAliasMember d;
2506 struct dom_sid *sid;
2508 sid = dom_sid_add_rid(tctx, domain_sid, 512);
2510 torture_comment(tctx, "testing AddAliasMember\n");
2511 r.in.alias_handle = alias_handle;
2514 status = dcerpc_samr_AddAliasMember(p, tctx, &r);
2515 torture_assert_ntstatus_ok(tctx, status, "AddAliasMember");
2517 d.in.alias_handle = alias_handle;
2520 status = dcerpc_samr_DeleteAliasMember(p, tctx, &d);
2521 torture_assert_ntstatus_ok(tctx, status, "DelAliasMember");
2526 static bool test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2527 struct policy_handle *alias_handle)
2529 struct samr_AddMultipleMembersToAlias a;
2530 struct samr_RemoveMultipleMembersFromAlias r;
2532 struct lsa_SidArray sids;
2534 torture_comment(tctx, "testing AddMultipleMembersToAlias\n");
2535 a.in.alias_handle = alias_handle;
2539 sids.sids = talloc_array(tctx, struct lsa_SidPtr, 3);
2541 sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2542 sids.sids[1].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-2");
2543 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-3");
2545 status = dcerpc_samr_AddMultipleMembersToAlias(p, tctx, &a);
2546 torture_assert_ntstatus_ok(tctx, status, "AddMultipleMembersToAlias");
2549 torture_comment(tctx, "testing RemoveMultipleMembersFromAlias\n");
2550 r.in.alias_handle = alias_handle;
2553 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2554 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2556 /* strange! removing twice doesn't give any error */
2557 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2558 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2560 /* but removing an alias that isn't there does */
2561 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-4");
2563 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2564 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, "RemoveMultipleMembersFromAlias");
2569 static bool test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2570 struct policy_handle *user_handle)
2572 struct samr_TestPrivateFunctionsUser r;
2575 torture_comment(tctx, "Testing TestPrivateFunctionsUser\n");
2577 r.in.user_handle = user_handle;
2579 status = dcerpc_samr_TestPrivateFunctionsUser(p, tctx, &r);
2580 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsUser");
2585 static bool test_QueryUserInfo_pwdlastset(struct dcerpc_pipe *p,
2586 struct torture_context *tctx,
2587 struct policy_handle *handle,
2592 uint16_t levels[] = { /* 3, */ 5, 21 };
2594 NTTIME pwdlastset3 = 0;
2595 NTTIME pwdlastset5 = 0;
2596 NTTIME pwdlastset21 = 0;
2598 torture_comment(tctx, "Testing QueryUserInfo%s level 5 and 21 call ",
2599 use_info2 ? "2":"");
2601 for (i=0; i<ARRAY_SIZE(levels); i++) {
2603 struct samr_QueryUserInfo r;
2604 struct samr_QueryUserInfo2 r2;
2605 union samr_UserInfo *info;
2608 r2.in.user_handle = handle;
2609 r2.in.level = levels[i];
2610 r2.out.info = &info;
2611 status = dcerpc_samr_QueryUserInfo2(p, tctx, &r2);
2614 r.in.user_handle = handle;
2615 r.in.level = levels[i];
2617 status = dcerpc_samr_QueryUserInfo(p, tctx, &r);
2620 if (!NT_STATUS_IS_OK(status) &&
2621 !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
2622 printf("QueryUserInfo%s level %u failed - %s\n",
2623 use_info2 ? "2":"", levels[i], nt_errstr(status));
2627 switch (levels[i]) {
2629 pwdlastset3 = info->info3.last_password_change;
2632 pwdlastset5 = info->info5.last_password_change;
2635 pwdlastset21 = info->info21.last_password_change;
2641 /* torture_assert_int_equal(tctx, pwdlastset3, pwdlastset5,
2642 "pwdlastset mixup"); */
2643 torture_assert_int_equal(tctx, pwdlastset5, pwdlastset21,
2644 "pwdlastset mixup");
2646 *pwdlastset = pwdlastset21;
2648 torture_comment(tctx, "(pwdlastset: %lld)\n", *pwdlastset);
2653 static bool test_SamLogon_Creds(struct dcerpc_pipe *p, struct torture_context *tctx,
2654 struct cli_credentials *machine_credentials,
2655 struct cli_credentials *test_credentials,
2656 struct netlogon_creds_CredentialState *creds,
2657 NTSTATUS expected_result)
2660 struct netr_LogonSamLogon r;
2661 struct netr_Authenticator auth, auth2;
2662 union netr_LogonLevel logon;
2663 union netr_Validation validation;
2664 uint8_t authoritative;
2665 struct netr_NetworkInfo ninfo;
2666 DATA_BLOB names_blob, chal, lm_resp, nt_resp;
2667 int flags = CLI_CRED_NTLM_AUTH;
2669 if (lp_client_lanman_auth(tctx->lp_ctx)) {
2670 flags |= CLI_CRED_LANMAN_AUTH;
2673 if (lp_client_ntlmv2_auth(tctx->lp_ctx)) {
2674 flags |= CLI_CRED_NTLMv2_AUTH;
2677 cli_credentials_get_ntlm_username_domain(test_credentials, tctx,
2678 &ninfo.identity_info.account_name.string,
2679 &ninfo.identity_info.domain_name.string);
2681 generate_random_buffer(ninfo.challenge,
2682 sizeof(ninfo.challenge));
2683 chal = data_blob_const(ninfo.challenge,
2684 sizeof(ninfo.challenge));
2686 names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(machine_credentials),
2687 cli_credentials_get_domain(machine_credentials));
2689 status = cli_credentials_get_ntlm_response(test_credentials, tctx,
2695 torture_assert_ntstatus_ok(tctx, status, "cli_credentials_get_ntlm_response failed");
2697 ninfo.lm.data = lm_resp.data;
2698 ninfo.lm.length = lm_resp.length;
2700 ninfo.nt.data = nt_resp.data;
2701 ninfo.nt.length = nt_resp.length;
2703 ninfo.identity_info.parameter_control =
2704 MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT |
2705 MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;
2706 ninfo.identity_info.logon_id_low = 0;
2707 ninfo.identity_info.logon_id_high = 0;
2708 ninfo.identity_info.workstation.string = cli_credentials_get_workstation(machine_credentials);
2710 logon.network = &ninfo;
2712 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2713 r.in.computer_name = cli_credentials_get_workstation(machine_credentials);
2714 r.in.credential = &auth;
2715 r.in.return_authenticator = &auth2;
2716 r.in.logon_level = 2;
2717 r.in.logon = &logon;
2718 r.out.validation = &validation;
2719 r.out.authoritative = &authoritative;
2721 d_printf("Testing LogonSamLogon with name %s\n", ninfo.identity_info.account_name.string);
2724 netlogon_creds_client_authenticator(creds, &auth);
2726 r.in.validation_level = 2;
2728 status = dcerpc_netr_LogonSamLogon(p, tctx, &r);
2729 if (!NT_STATUS_IS_OK(status)) {
2730 torture_assert_ntstatus_equal(tctx, status, expected_result, "LogonSamLogon failed");
2733 torture_assert_ntstatus_ok(tctx, status, "LogonSamLogon failed");
2736 torture_assert(tctx, netlogon_creds_client_check(creds, &r.out.return_authenticator->cred),
2737 "Credential chaining failed");
2742 static bool test_SamLogon(struct torture_context *tctx,
2743 struct dcerpc_pipe *p,
2744 struct cli_credentials *machine_credentials,
2745 struct cli_credentials *test_credentials,
2746 NTSTATUS expected_result)
2748 struct netlogon_creds_CredentialState *creds;
2750 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
2754 return test_SamLogon_Creds(p, tctx, machine_credentials, test_credentials,
2755 creds, expected_result);
2758 static bool test_SamLogon_with_creds(struct torture_context *tctx,
2759 struct dcerpc_pipe *p,
2760 struct cli_credentials *machine_creds,
2761 const char *acct_name,
2763 NTSTATUS expected_samlogon_result)
2766 struct cli_credentials *test_credentials;
2768 test_credentials = cli_credentials_init(tctx);
2770 cli_credentials_set_workstation(test_credentials,
2771 TEST_ACCOUNT_NAME_PWD, CRED_SPECIFIED);
2772 cli_credentials_set_domain(test_credentials,
2773 lp_workgroup(tctx->lp_ctx), CRED_SPECIFIED);
2774 cli_credentials_set_username(test_credentials,
2775 acct_name, CRED_SPECIFIED);
2776 cli_credentials_set_password(test_credentials,
2777 password, CRED_SPECIFIED);
2778 cli_credentials_set_secure_channel_type(test_credentials, SEC_CHAN_BDC);
2780 printf("testing samlogon as %s@%s password: %s\n",
2781 acct_name, TEST_ACCOUNT_NAME_PWD, password);
2783 if (!test_SamLogon(tctx, p, machine_creds, test_credentials,
2784 expected_samlogon_result)) {
2785 torture_warning(tctx, "new password did not work\n");
2792 static bool test_SetPassword_level(struct dcerpc_pipe *p,
2793 struct dcerpc_pipe *np,
2794 struct torture_context *tctx,
2795 struct policy_handle *handle,
2797 uint32_t fields_present,
2798 uint8_t password_expired,
2799 bool *matched_expected_error,
2801 const char *acct_name,
2803 struct cli_credentials *machine_creds,
2804 bool use_queryinfo2,
2806 NTSTATUS expected_samlogon_result)
2808 const char *fields = NULL;
2815 fields = talloc_asprintf(tctx, "(fields_present: 0x%08x)",
2822 torture_comment(tctx, "Testing SetUserInfo%s level %d call "
2823 "(password_expired: %d) %s\n",
2824 use_setinfo2 ? "2":"", level, password_expired,
2825 fields ? fields : "");
2827 if (!test_SetUserPass_level_ex(p, tctx, handle, level,
2832 matched_expected_error)) {
2836 if (!test_QueryUserInfo_pwdlastset(p, tctx, handle,
2842 if (*matched_expected_error == true) {
2846 if (!test_SamLogon_with_creds(tctx, np,
2850 expected_samlogon_result)) {
2857 static bool test_SetPassword_pwdlastset(struct dcerpc_pipe *p,
2858 struct torture_context *tctx,
2859 uint32_t acct_flags,
2860 const char *acct_name,
2861 struct policy_handle *handle,
2863 struct cli_credentials *machine_credentials)
2865 int s = 0, q = 0, f = 0, l = 0, z = 0;
2868 bool set_levels[] = { false, true };
2869 bool query_levels[] = { false, true };
2870 uint32_t levels[] = { 18, 21, 23, 24, 25, 26 };
2871 uint32_t nonzeros[] = { 1, 24 };
2872 uint32_t fields_present[] = {
2874 SAMR_FIELD_EXPIRED_FLAG,
2875 SAMR_FIELD_LAST_PWD_CHANGE,
2876 SAMR_FIELD_EXPIRED_FLAG | SAMR_FIELD_LAST_PWD_CHANGE,
2878 SAMR_FIELD_NT_PASSWORD_PRESENT,
2879 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
2880 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
2881 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
2882 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
2883 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
2884 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE | SAMR_FIELD_EXPIRED_FLAG
2887 struct dcerpc_pipe *np = NULL;
2889 if (torture_setting_bool(tctx, "samba3", false)) {
2891 printf("Samba3 has second granularity, setting delay to: %d\n",
2895 status = torture_rpc_connection(tctx, &np, &ndr_table_netlogon);
2896 if (!NT_STATUS_IS_OK(status)) {
2900 /* set to 1 to enable testing for all possible opcode
2901 (SetUserInfo, SetUserInfo2, QueryUserInfo, QueryUserInfo2)
2904 #define TEST_SET_LEVELS 1
2905 #define TEST_QUERY_LEVELS 1
2907 for (l=0; l<ARRAY_SIZE(levels); l++) {
2908 for (z=0; z<ARRAY_SIZE(nonzeros); z++) {
2909 for (f=0; f<ARRAY_SIZE(fields_present); f++) {
2910 #ifdef TEST_SET_LEVELS
2911 for (s=0; s<ARRAY_SIZE(set_levels); s++) {
2913 #ifdef TEST_QUERY_LEVELS
2914 for (q=0; q<ARRAY_SIZE(query_levels); q++) {
2916 NTTIME pwdlastset_old = 0;
2917 NTTIME pwdlastset_new = 0;
2918 bool matched_expected_error = false;
2919 NTSTATUS expected_samlogon_result = NT_STATUS_ACCOUNT_DISABLED;
2921 torture_comment(tctx, "------------------------------\n"
2922 "Testing pwdLastSet attribute for flags: 0x%08x "
2923 "(s: %d (l: %d), q: %d)\n",
2924 acct_flags, s, levels[l], q);
2926 switch (levels[l]) {
2930 if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
2931 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT))) {
2932 expected_samlogon_result = NT_STATUS_WRONG_PASSWORD;
2940 /* set a password and force password change (pwdlastset 0) by
2941 * setting the password expired flag to a non-0 value */
2943 if (!test_SetPassword_level(p, np, tctx, handle,
2947 &matched_expected_error,
2951 machine_credentials,
2954 expected_samlogon_result)) {
2958 if (matched_expected_error == true) {
2959 /* skipping on expected failure */
2963 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
2964 * set without the SAMR_FIELD_EXPIRED_FLAG */
2966 switch (levels[l]) {
2970 if ((pwdlastset_new != 0) &&
2971 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
2972 torture_comment(tctx, "not considering a non-0 "
2973 "pwdLastSet as a an error as the "
2974 "SAMR_FIELD_EXPIRED_FLAG has not "
2979 if (pwdlastset_new != 0) {
2980 torture_warning(tctx, "pwdLastSet test failed: "
2981 "expected pwdLastSet 0 but got %lld\n",
2988 switch (levels[l]) {
2992 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
2993 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
2994 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
2995 (pwdlastset_old >= pwdlastset_new)) {
2996 torture_warning(tctx, "pwdlastset not increasing\n");
3001 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3002 (pwdlastset_old >= pwdlastset_new)) {
3003 torture_warning(tctx, "pwdlastset not increasing\n");
3013 /* set a password, pwdlastset needs to get updated (increased
3014 * value), password_expired value used here is 0 */
3016 if (!test_SetPassword_level(p, np, tctx, handle,
3020 &matched_expected_error,
3024 machine_credentials,
3027 expected_samlogon_result)) {
3031 /* when a password has been changed, pwdlastset must not be 0 afterwards
3032 * and must be larger then the old value */
3034 switch (levels[l]) {
3039 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3040 * password has been changed, old and new pwdlastset
3041 * need to be the same value */
3043 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3044 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3045 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3047 torture_assert_int_equal(tctx, pwdlastset_old,
3048 pwdlastset_new, "pwdlastset must be equal");
3052 if (pwdlastset_old >= pwdlastset_new) {
3053 torture_warning(tctx, "pwdLastSet test failed: "
3054 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
3055 pwdlastset_old, pwdlastset_new);
3058 if (pwdlastset_new == 0) {
3059 torture_warning(tctx, "pwdLastSet test failed: "
3060 "expected non-0 pwdlastset, got: %lld\n",
3066 switch (levels[l]) {
3070 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3071 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3072 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3073 (pwdlastset_old >= pwdlastset_new)) {
3074 torture_warning(tctx, "pwdlastset not increasing\n");
3079 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3080 (pwdlastset_old >= pwdlastset_new)) {
3081 torture_warning(tctx, "pwdlastset not increasing\n");
3087 pwdlastset_old = pwdlastset_new;
3093 /* set a password, pwdlastset needs to get updated (increased
3094 * value), password_expired value used here is 0 */
3096 if (!test_SetPassword_level(p, np, tctx, handle,
3100 &matched_expected_error,
3104 machine_credentials,
3107 expected_samlogon_result)) {
3111 /* when a password has been changed, pwdlastset must not be 0 afterwards
3112 * and must be larger then the old value */
3114 switch (levels[l]) {
3119 /* if no password has been changed, old and new pwdlastset
3120 * need to be the same value */
3122 if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3123 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3125 torture_assert_int_equal(tctx, pwdlastset_old,
3126 pwdlastset_new, "pwdlastset must be equal");
3130 if (pwdlastset_old >= pwdlastset_new) {
3131 torture_warning(tctx, "pwdLastSet test failed: "
3132 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
3133 pwdlastset_old, pwdlastset_new);
3136 if (pwdlastset_new == 0) {
3137 torture_warning(tctx, "pwdLastSet test failed: "
3138 "expected non-0 pwdlastset, got: %lld\n",
3146 /* set a password and force password change (pwdlastset 0) by
3147 * setting the password expired flag to a non-0 value */
3149 if (!test_SetPassword_level(p, np, tctx, handle,
3153 &matched_expected_error,
3157 machine_credentials,
3160 expected_samlogon_result)) {
3164 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3165 * set without the SAMR_FIELD_EXPIRED_FLAG */
3167 switch (levels[l]) {
3171 if ((pwdlastset_new != 0) &&
3172 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
3173 torture_comment(tctx, "not considering a non-0 "
3174 "pwdLastSet as a an error as the "
3175 "SAMR_FIELD_EXPIRED_FLAG has not "
3180 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3181 * password has been changed, old and new pwdlastset
3182 * need to be the same value */
3184 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3185 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3186 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3188 torture_assert_int_equal(tctx, pwdlastset_old,
3189 pwdlastset_new, "pwdlastset must be equal");
3194 if (pwdlastset_old == pwdlastset_new) {
3195 torture_warning(tctx, "pwdLastSet test failed: "
3196 "expected last pwdlastset (%lld) != new pwdlastset (%lld)\n",
3197 pwdlastset_old, pwdlastset_new);
3201 if (pwdlastset_new != 0) {
3202 torture_warning(tctx, "pwdLastSet test failed: "
3203 "expected pwdLastSet 0, got %lld\n",
3210 switch (levels[l]) {
3214 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3215 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3216 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3217 (pwdlastset_old >= pwdlastset_new)) {
3218 torture_warning(tctx, "pwdlastset not increasing\n");
3223 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3224 (pwdlastset_old >= pwdlastset_new)) {
3225 torture_warning(tctx, "pwdlastset not increasing\n");
3231 /* if the level we are testing does not have a fields_present
3232 * field, skip all fields present tests by setting f to to
3234 switch (levels[l]) {
3238 f = ARRAY_SIZE(fields_present);
3242 #ifdef TEST_QUERY_LEVELS
3245 #ifdef TEST_SET_LEVELS
3248 } /* fields present */
3252 #undef TEST_SET_LEVELS
3253 #undef TEST_QUERY_LEVELS
3258 static bool test_user_ops(struct dcerpc_pipe *p,
3259 struct torture_context *tctx,
3260 struct policy_handle *user_handle,
3261 struct policy_handle *domain_handle,
3262 uint32_t base_acct_flags,
3263 const char *base_acct_name, enum torture_samr_choice which_ops,
3264 struct cli_credentials *machine_credentials)
3266 char *password = NULL;
3267 struct samr_QueryUserInfo q;
3268 union samr_UserInfo *info;
3274 const uint32_t password_fields[] = {
3275 SAMR_FIELD_NT_PASSWORD_PRESENT,
3276 SAMR_FIELD_LM_PASSWORD_PRESENT,
3277 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
3281 status = test_LookupName(p, tctx, domain_handle, base_acct_name, &rid);
3282 if (!NT_STATUS_IS_OK(status)) {
3286 switch (which_ops) {
3287 case TORTURE_SAMR_USER_ATTRIBUTES:
3288 if (!test_QuerySecurity(p, tctx, user_handle)) {
3292 if (!test_QueryUserInfo(p, tctx, user_handle)) {
3296 if (!test_QueryUserInfo2(p, tctx, user_handle)) {
3300 if (!test_SetUserInfo(p, tctx, user_handle, base_acct_flags,
3305 if (!test_GetUserPwInfo(p, tctx, user_handle)) {
3309 if (!test_TestPrivateFunctionsUser(p, tctx, user_handle)) {
3313 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
3317 case TORTURE_SAMR_PASSWORDS:
3318 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
3319 char simple_pass[9];
3320 char *v = generate_random_str(tctx, 1);
3322 ZERO_STRUCT(simple_pass);
3323 memset(simple_pass, *v, sizeof(simple_pass) - 1);
3325 printf("Testing machine account password policy rules\n");
3327 /* Workstation trust accounts don't seem to need to honour password quality policy */
3328 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
3332 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
3336 /* reset again, to allow another 'user' password change */
3337 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
3341 /* Try a 'short' password */
3342 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
3346 /* Try a compleatly random password */
3347 if (!test_ChangePasswordRandomBytes(p, tctx, base_acct_name, user_handle, &password)) {
3352 for (i = 0; password_fields[i]; i++) {
3353 if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
3357 /* check it was set right */
3358 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3363 for (i = 0; password_fields[i]; i++) {
3364 if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
3368 /* check it was set right */
3369 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3374 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
3378 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
3382 if (torture_setting_bool(tctx, "samba4", false)) {
3383 printf("skipping Set Password level 18 and 21 against Samba4\n");
3386 if (!test_SetUserPass_18(p, tctx, user_handle, &password)) {
3390 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3394 for (i = 0; password_fields[i]; i++) {
3396 if (password_fields[i] == SAMR_FIELD_LM_PASSWORD_PRESENT) {
3397 /* we need to skip as that would break
3398 * the ChangePasswordUser3 verify */
3402 if (!test_SetUserPass_21(p, tctx, user_handle, password_fields[i], &password)) {
3406 /* check it was set right */
3407 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3413 q.in.user_handle = user_handle;
3417 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
3418 if (!NT_STATUS_IS_OK(status)) {
3419 printf("QueryUserInfo level %u failed - %s\n",
3420 q.in.level, nt_errstr(status));
3423 uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
3424 if ((info->info5.acct_flags) != expected_flags) {
3425 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
3426 info->info5.acct_flags,
3429 if (!torture_setting_bool(tctx, "samba3", false)) {
3433 if (info->info5.rid != rid) {
3434 printf("QuerUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
3435 info->info5.rid, rid);
3442 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
3444 /* test last password change timestamp behaviour */
3445 if (!test_SetPassword_pwdlastset(p, tctx, base_acct_flags,
3447 user_handle, &password,
3448 machine_credentials)) {
3453 torture_comment(tctx, "pwdLastSet test succeeded\n");
3455 torture_warning(tctx, "pwdLastSet test failed\n");
3460 case TORTURE_SAMR_OTHER:
3461 /* We just need the account to exist */
3467 static bool test_alias_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
3468 struct policy_handle *alias_handle,
3469 const struct dom_sid *domain_sid)
3473 if (!test_QuerySecurity(p, tctx, alias_handle)) {
3477 if (!test_QueryAliasInfo(p, tctx, alias_handle)) {
3481 if (!test_SetAliasInfo(p, tctx, alias_handle)) {
3485 if (!test_AddMemberToAlias(p, tctx, alias_handle, domain_sid)) {
3489 if (torture_setting_bool(tctx, "samba4", false)) {
3490 printf("skipping MultipleMembers Alias tests against Samba4\n");
3494 if (!test_AddMultipleMembersToAlias(p, tctx, alias_handle)) {
3502 static bool test_DeleteUser(struct dcerpc_pipe *p, struct torture_context *tctx,
3503 struct policy_handle *user_handle)
3505 struct samr_DeleteUser d;
3507 torture_comment(tctx, "Testing DeleteUser\n");
3509 d.in.user_handle = user_handle;
3510 d.out.user_handle = user_handle;
3512 status = dcerpc_samr_DeleteUser(p, tctx, &d);
3513 torture_assert_ntstatus_ok(tctx, status, "DeleteUser");
3518 bool test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3519 struct policy_handle *handle, const char *name)
3522 struct samr_DeleteUser d;
3523 struct policy_handle user_handle;
3526 status = test_LookupName(p, mem_ctx, handle, name, &rid);
3527 if (!NT_STATUS_IS_OK(status)) {
3531 status = test_OpenUser_byname(p, mem_ctx, handle, name, &user_handle);
3532 if (!NT_STATUS_IS_OK(status)) {
3536 d.in.user_handle = &user_handle;
3537 d.out.user_handle = &user_handle;
3538 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
3539 if (!NT_STATUS_IS_OK(status)) {
3546 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
3551 static bool test_DeleteGroup_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3552 struct policy_handle *handle, const char *name)
3555 struct samr_OpenGroup r;
3556 struct samr_DeleteDomainGroup d;
3557 struct policy_handle group_handle;
3560 status = test_LookupName(p, mem_ctx, handle, name, &rid);
3561 if (!NT_STATUS_IS_OK(status)) {
3565 r.in.domain_handle = handle;
3566 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3568 r.out.group_handle = &group_handle;
3569 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
3570 if (!NT_STATUS_IS_OK(status)) {
3574 d.in.group_handle = &group_handle;
3575 d.out.group_handle = &group_handle;
3576 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
3577 if (!NT_STATUS_IS_OK(status)) {
3584 printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
3589 static bool test_DeleteAlias_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3590 struct policy_handle *domain_handle, const char *name)
3593 struct samr_OpenAlias r;
3594 struct samr_DeleteDomAlias d;
3595 struct policy_handle alias_handle;
3598 printf("testing DeleteAlias_byname\n");
3600 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
3601 if (!NT_STATUS_IS_OK(status)) {
3605 r.in.domain_handle = domain_handle;
3606 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3608 r.out.alias_handle = &alias_handle;
3609 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
3610 if (!NT_STATUS_IS_OK(status)) {
3614 d.in.alias_handle = &alias_handle;
3615 d.out.alias_handle = &alias_handle;
3616 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
3617 if (!NT_STATUS_IS_OK(status)) {
3624 printf("DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
3628 static bool test_DeleteAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3629 struct policy_handle *alias_handle)
3631 struct samr_DeleteDomAlias d;
3634 printf("Testing DeleteAlias\n");
3636 d.in.alias_handle = alias_handle;
3637 d.out.alias_handle = alias_handle;
3639 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
3640 if (!NT_STATUS_IS_OK(status)) {
3641 printf("DeleteAlias failed - %s\n", nt_errstr(status));
3648 static bool test_CreateAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
3649 struct policy_handle *domain_handle,
3650 struct policy_handle *alias_handle,
3651 const struct dom_sid *domain_sid)
3654 struct samr_CreateDomAlias r;
3655 struct lsa_String name;
3659 init_lsa_String(&name, TEST_ALIASNAME);
3660 r.in.domain_handle = domain_handle;
3661 r.in.alias_name = &name;
3662 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3663 r.out.alias_handle = alias_handle;
3666 printf("Testing CreateAlias (%s)\n", r.in.alias_name->string);
3668 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
3670 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
3671 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
3672 printf("Server correctly refused create of '%s'\n", r.in.alias_name->string);
3675 printf("Server should have refused create of '%s', got %s instead\n", r.in.alias_name->string,
3681 if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
3682 if (!test_DeleteAlias_byname(p, tctx, domain_handle, r.in.alias_name->string)) {
3685 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
3688 if (!NT_STATUS_IS_OK(status)) {
3689 printf("CreateAlias failed - %s\n", nt_errstr(status));
3693 if (!test_alias_ops(p, tctx, alias_handle, domain_sid)) {
3700 static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3701 const char *acct_name,
3702 struct policy_handle *domain_handle, char **password)
3710 if (!test_ChangePasswordUser(p, mem_ctx, acct_name, domain_handle, password)) {
3714 if (!test_ChangePasswordUser2(p, mem_ctx, acct_name, password, 0, true)) {
3718 if (!test_OemChangePasswordUser2(p, mem_ctx, acct_name, domain_handle, password)) {
3722 /* test what happens when setting the old password again */
3723 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, *password, 0, true)) {
3728 char simple_pass[9];
3729 char *v = generate_random_str(mem_ctx, 1);
3731 ZERO_STRUCT(simple_pass);
3732 memset(simple_pass, *v, sizeof(simple_pass) - 1);
3734 /* test what happens when picking a simple password */
3735 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, simple_pass, 0, true)) {
3740 /* set samr_SetDomainInfo level 1 with min_length 5 */
3742 struct samr_QueryDomainInfo r;
3743 union samr_DomainInfo *info = NULL;
3744 struct samr_SetDomainInfo s;
3745 uint16_t len_old, len;
3746 uint32_t pwd_prop_old;
3747 int64_t min_pwd_age_old;
3752 r.in.domain_handle = domain_handle;
3756 printf("testing samr_QueryDomainInfo level 1\n");
3757 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
3758 if (!NT_STATUS_IS_OK(status)) {
3762 s.in.domain_handle = domain_handle;
3766 /* remember the old min length, so we can reset it */
3767 len_old = s.in.info->info1.min_password_length;
3768 s.in.info->info1.min_password_length = len;
3769 pwd_prop_old = s.in.info->info1.password_properties;
3770 /* turn off password complexity checks for this test */
3771 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
3773 min_pwd_age_old = s.in.info->info1.min_password_age;
3774 s.in.info->info1.min_password_age = 0;
3776 printf("testing samr_SetDomainInfo level 1\n");
3777 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
3778 if (!NT_STATUS_IS_OK(status)) {
3782 printf("calling test_ChangePasswordUser3 with too short password\n");
3784 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, len - 1, password, NULL, 0, true)) {
3788 s.in.info->info1.min_password_length = len_old;
3789 s.in.info->info1.password_properties = pwd_prop_old;
3790 s.in.info->info1.min_password_age = min_pwd_age_old;
3792 printf("testing samr_SetDomainInfo level 1\n");
3793 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
3794 if (!NT_STATUS_IS_OK(status)) {
3802 struct samr_OpenUser r;
3803 struct samr_QueryUserInfo q;
3804 union samr_UserInfo *info;
3805 struct samr_LookupNames n;
3806 struct policy_handle user_handle;
3807 struct samr_Ids rids, types;
3809 n.in.domain_handle = domain_handle;
3811 n.in.names = talloc_array(mem_ctx, struct lsa_String, 1);
3812 n.in.names[0].string = acct_name;
3814 n.out.types = &types;
3816 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
3817 if (!NT_STATUS_IS_OK(status)) {
3818 printf("LookupNames failed - %s\n", nt_errstr(status));
3822 r.in.domain_handle = domain_handle;
3823 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3824 r.in.rid = n.out.rids->ids[0];
3825 r.out.user_handle = &user_handle;
3827 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3828 if (!NT_STATUS_IS_OK(status)) {
3829 printf("OpenUser(%u) failed - %s\n", n.out.rids->ids[0], nt_errstr(status));
3833 q.in.user_handle = &user_handle;
3837 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
3838 if (!NT_STATUS_IS_OK(status)) {
3839 printf("QueryUserInfo failed - %s\n", nt_errstr(status));
3843 printf("calling test_ChangePasswordUser3 with too early password change\n");
3845 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL,
3846 info->info5.last_password_change, true)) {
3851 /* we change passwords twice - this has the effect of verifying
3852 they were changed correctly for the final call */
3853 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, true)) {
3857 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, true)) {
3864 static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
3865 struct policy_handle *domain_handle,
3866 struct policy_handle *user_handle_out,
3867 struct dom_sid *domain_sid,
3868 enum torture_samr_choice which_ops,
3869 struct cli_credentials *machine_credentials)
3872 TALLOC_CTX *user_ctx;
3875 struct samr_CreateUser r;
3876 struct samr_QueryUserInfo q;
3877 union samr_UserInfo *info;
3878 struct samr_DeleteUser d;
3881 /* This call creates a 'normal' account - check that it really does */
3882 const uint32_t acct_flags = ACB_NORMAL;
3883 struct lsa_String name;
3886 struct policy_handle user_handle;
3887 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
3888 init_lsa_String(&name, TEST_ACCOUNT_NAME);
3890 r.in.domain_handle = domain_handle;
3891 r.in.account_name = &name;
3892 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3893 r.out.user_handle = &user_handle;
3896 printf("Testing CreateUser(%s)\n", r.in.account_name->string);
3898 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
3900 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
3901 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
3902 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
3905 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
3911 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
3912 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
3913 talloc_free(user_ctx);
3916 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
3918 if (!NT_STATUS_IS_OK(status)) {
3919 talloc_free(user_ctx);
3920 printf("CreateUser failed - %s\n", nt_errstr(status));
3923 q.in.user_handle = &user_handle;
3927 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
3928 if (!NT_STATUS_IS_OK(status)) {
3929 printf("QueryUserInfo level %u failed - %s\n",
3930 q.in.level, nt_errstr(status));
3933 if ((info->info16.acct_flags & acct_flags) != acct_flags) {
3934 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
3935 info->info16.acct_flags,
3941 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
3942 acct_flags, name.string, which_ops,
3943 machine_credentials)) {
3947 if (user_handle_out) {
3948 *user_handle_out = user_handle;
3950 printf("Testing DeleteUser (createuser test)\n");
3952 d.in.user_handle = &user_handle;
3953 d.out.user_handle = &user_handle;
3955 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
3956 if (!NT_STATUS_IS_OK(status)) {
3957 printf("DeleteUser failed - %s\n", nt_errstr(status));
3964 talloc_free(user_ctx);
3970 static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
3971 struct policy_handle *domain_handle,
3972 struct dom_sid *domain_sid,
3973 enum torture_samr_choice which_ops,
3974 struct cli_credentials *machine_credentials)
3977 struct samr_CreateUser2 r;
3978 struct samr_QueryUserInfo q;
3979 union samr_UserInfo *info;
3980 struct samr_DeleteUser d;
3981 struct policy_handle user_handle;
3983 struct lsa_String name;
3988 uint32_t acct_flags;
3989 const char *account_name;
3991 } account_types[] = {
3992 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
3993 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
3994 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
3995 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
3996 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
3997 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
3998 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
3999 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
4000 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
4001 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
4002 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
4003 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
4004 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
4005 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
4006 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
4009 for (i = 0; account_types[i].account_name; i++) {
4010 TALLOC_CTX *user_ctx;
4011 uint32_t acct_flags = account_types[i].acct_flags;
4012 uint32_t access_granted;
4013 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
4014 init_lsa_String(&name, account_types[i].account_name);
4016 r.in.domain_handle = domain_handle;
4017 r.in.account_name = &name;
4018 r.in.acct_flags = acct_flags;
4019 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4020 r.out.user_handle = &user_handle;
4021 r.out.access_granted = &access_granted;
4024 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
4026 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
4028 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
4029 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
4030 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
4033 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
4040 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
4041 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
4042 talloc_free(user_ctx);
4046 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
4049 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
4050 printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
4051 nt_errstr(status), nt_errstr(account_types[i].nt_status));
4055 if (NT_STATUS_IS_OK(status)) {
4056 q.in.user_handle = &user_handle;
4060 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
4061 if (!NT_STATUS_IS_OK(status)) {
4062 printf("QueryUserInfo level %u failed - %s\n",
4063 q.in.level, nt_errstr(status));
4066 uint32_t expected_flags = (acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
4067 if (acct_flags == ACB_NORMAL) {
4068 expected_flags |= ACB_PW_EXPIRED;
4070 if ((info->info5.acct_flags) != expected_flags) {
4071 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
4072 info->info5.acct_flags,
4076 switch (acct_flags) {
4078 if (info->info5.primary_gid != DOMAIN_RID_DCS) {
4079 printf("QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n",
4080 DOMAIN_RID_DCS, info->info5.primary_gid);
4085 if (info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
4086 printf("QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
4087 DOMAIN_RID_DOMAIN_MEMBERS, info->info5.primary_gid);
4092 if (info->info5.primary_gid != DOMAIN_RID_USERS) {
4093 printf("QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n",
4094 DOMAIN_RID_USERS, info->info5.primary_gid);
4101 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
4102 acct_flags, name.string, which_ops,
4103 machine_credentials)) {
4107 printf("Testing DeleteUser (createuser2 test)\n");
4109 d.in.user_handle = &user_handle;
4110 d.out.user_handle = &user_handle;
4112 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
4113 if (!NT_STATUS_IS_OK(status)) {
4114 printf("DeleteUser failed - %s\n", nt_errstr(status));
4118 talloc_free(user_ctx);
4124 static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4125 struct policy_handle *handle)
4128 struct samr_QueryAliasInfo r;
4129 union samr_AliasInfo *info;
4130 uint16_t levels[] = {1, 2, 3};
4134 for (i=0;i<ARRAY_SIZE(levels);i++) {
4135 printf("Testing QueryAliasInfo level %u\n", levels[i]);
4137 r.in.alias_handle = handle;
4138 r.in.level = levels[i];
4141 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
4142 if (!NT_STATUS_IS_OK(status)) {
4143 printf("QueryAliasInfo level %u failed - %s\n",
4144 levels[i], nt_errstr(status));
4152 static bool test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4153 struct policy_handle *handle)
4156 struct samr_QueryGroupInfo r;
4157 union samr_GroupInfo *info;
4158 uint16_t levels[] = {1, 2, 3, 4, 5};
4162 for (i=0;i<ARRAY_SIZE(levels);i++) {
4163 printf("Testing QueryGroupInfo level %u\n", levels[i]);
4165 r.in.group_handle = handle;
4166 r.in.level = levels[i];
4169 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
4170 if (!NT_STATUS_IS_OK(status)) {
4171 printf("QueryGroupInfo level %u failed - %s\n",
4172 levels[i], nt_errstr(status));
4180 static bool test_QueryGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4181 struct policy_handle *handle)
4184 struct samr_QueryGroupMember r;
4185 struct samr_RidTypeArray *rids = NULL;
4188 printf("Testing QueryGroupMember\n");
4190 r.in.group_handle = handle;
4193 status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &r);
4194 if (!NT_STATUS_IS_OK(status)) {
4195 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
4203 static bool test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4204 struct policy_handle *handle)
4207 struct samr_QueryGroupInfo r;
4208 union samr_GroupInfo *info;
4209 struct samr_SetGroupInfo s;
4210 uint16_t levels[] = {1, 2, 3, 4};
4211 uint16_t set_ok[] = {0, 1, 1, 1};
4215 for (i=0;i<ARRAY_SIZE(levels);i++) {
4216 printf("Testing QueryGroupInfo level %u\n", levels[i]);
4218 r.in.group_handle = handle;
4219 r.in.level = levels[i];
4222 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
4223 if (!NT_STATUS_IS_OK(status)) {
4224 printf("QueryGroupInfo level %u failed - %s\n",
4225 levels[i], nt_errstr(status));
4229 printf("Testing SetGroupInfo level %u\n", levels[i]);
4231 s.in.group_handle = handle;
4232 s.in.level = levels[i];
4233 s.in.info = *r.out.info;
4236 /* disabled this, as it changes the name only from the point of view of samr,
4237 but leaves the name from the point of view of w2k3 internals (and ldap). This means
4238 the name is still reserved, so creating the old name fails, but deleting by the old name
4240 if (s.in.level == 2) {
4241 init_lsa_String(&s.in.info->string, "NewName");
4245 if (s.in.level == 4) {
4246 init_lsa_String(&s.in.info->description, "test description");
4249 status = dcerpc_samr_SetGroupInfo(p, mem_ctx, &s);
4251 if (!NT_STATUS_IS_OK(status)) {
4252 printf("SetGroupInfo level %u failed - %s\n",
4253 r.in.level, nt_errstr(status));
4258 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
4259 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
4260 r.in.level, nt_errstr(status));
4270 static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4271 struct policy_handle *handle)
4274 struct samr_QueryUserInfo r;
4275 union samr_UserInfo *info;
4276 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
4277 11, 12, 13, 14, 16, 17, 20, 21};
4281 for (i=0;i<ARRAY_SIZE(levels);i++) {
4282 printf("Testing QueryUserInfo level %u\n", levels[i]);
4284 r.in.user_handle = handle;
4285 r.in.level = levels[i];
4288 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
4289 if (!NT_STATUS_IS_OK(status)) {
4290 printf("QueryUserInfo level %u failed - %s\n",
4291 levels[i], nt_errstr(status));
4299 static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4300 struct policy_handle *handle)
4303 struct samr_QueryUserInfo2 r;
4304 union samr_UserInfo *info;
4305 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
4306 11, 12, 13, 14, 16, 17, 20, 21};
4310 for (i=0;i<ARRAY_SIZE(levels);i++) {
4311 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
4313 r.in.user_handle = handle;
4314 r.in.level = levels[i];
4317 status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r);
4318 if (!NT_STATUS_IS_OK(status)) {
4319 printf("QueryUserInfo2 level %u failed - %s\n",
4320 levels[i], nt_errstr(status));
4328 static bool test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4329 struct policy_handle *handle, uint32_t rid)
4332 struct samr_OpenUser r;
4333 struct policy_handle user_handle;
4336 printf("Testing OpenUser(%u)\n", rid);
4338 r.in.domain_handle = handle;
4339 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4341 r.out.user_handle = &user_handle;
4343 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
4344 if (!NT_STATUS_IS_OK(status)) {
4345 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
4349 if (!test_QuerySecurity(p, mem_ctx, &user_handle)) {
4353 if (!test_QueryUserInfo(p, mem_ctx, &user_handle)) {
4357 if (!test_QueryUserInfo2(p, mem_ctx, &user_handle)) {
4361 if (!test_GetUserPwInfo(p, mem_ctx, &user_handle)) {
4365 if (!test_GetGroupsForUser(p,mem_ctx, &user_handle)) {
4369 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
4376 static bool test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4377 struct policy_handle *handle, uint32_t rid)
4380 struct samr_OpenGroup r;
4381 struct policy_handle group_handle;
4384 printf("Testing OpenGroup(%u)\n", rid);
4386 r.in.domain_handle = handle;
4387 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4389 r.out.group_handle = &group_handle;
4391 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
4392 if (!NT_STATUS_IS_OK(status)) {
4393 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
4397 if (!test_QuerySecurity(p, mem_ctx, &group_handle)) {
4401 if (!test_QueryGroupInfo(p, mem_ctx, &group_handle)) {
4405 if (!test_QueryGroupMember(p, mem_ctx, &group_handle)) {
4409 if (!test_samr_handle_Close(p, mem_ctx, &group_handle)) {
4416 static bool test_OpenAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
4417 struct policy_handle *handle, uint32_t rid)
4420 struct samr_OpenAlias r;
4421 struct policy_handle alias_handle;
4424 torture_comment(tctx, "Testing OpenAlias(%u)\n", rid);
4426 r.in.domain_handle = handle;
4427 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4429 r.out.alias_handle = &alias_handle;
4431 status = dcerpc_samr_OpenAlias(p, tctx, &r);
4432 if (!NT_STATUS_IS_OK(status)) {
4433 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
4437 if (!test_QuerySecurity(p, tctx, &alias_handle)) {
4441 if (!test_QueryAliasInfo(p, tctx, &alias_handle)) {
4445 if (!test_GetMembersInAlias(p, tctx, &alias_handle)) {
4449 if (!test_samr_handle_Close(p, tctx, &alias_handle)) {
4456 static bool check_mask(struct dcerpc_pipe *p, struct torture_context *tctx,
4457 struct policy_handle *handle, uint32_t rid,
4458 uint32_t acct_flag_mask)
4461 struct samr_OpenUser r;
4462 struct samr_QueryUserInfo q;
4463 union samr_UserInfo *info;
4464 struct policy_handle user_handle;
4467 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
4469 r.in.domain_handle = handle;
4470 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4472 r.out.user_handle = &user_handle;
4474 status = dcerpc_samr_OpenUser(p, tctx, &r);
4475 if (!NT_STATUS_IS_OK(status)) {
4476 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
4480 q.in.user_handle = &user_handle;
4484 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
4485 if (!NT_STATUS_IS_OK(status)) {
4486 printf("QueryUserInfo level 16 failed - %s\n",
4490 if ((acct_flag_mask & info->info16.acct_flags) == 0) {
4491 printf("Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
4492 acct_flag_mask, info->info16.acct_flags, rid);
4497 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
4504 static bool test_EnumDomainUsers(struct dcerpc_pipe *p, struct torture_context *tctx,
4505 struct policy_handle *handle)
4507 NTSTATUS status = STATUS_MORE_ENTRIES;
4508 struct samr_EnumDomainUsers r;
4509 uint32_t mask, resume_handle=0;
4512 struct samr_LookupNames n;
4513 struct samr_LookupRids lr ;
4514 struct lsa_Strings names;
4515 struct samr_Ids rids, types;
4516 struct samr_SamArray *sam = NULL;
4517 uint32_t num_entries = 0;
4519 uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
4520 ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
4521 ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
4524 printf("Testing EnumDomainUsers\n");
4526 for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
4527 r.in.domain_handle = handle;
4528 r.in.resume_handle = &resume_handle;
4529 r.in.acct_flags = mask = masks[mask_idx];
4530 r.in.max_size = (uint32_t)-1;
4531 r.out.resume_handle = &resume_handle;
4532 r.out.num_entries = &num_entries;
4535 status = dcerpc_samr_EnumDomainUsers(p, tctx, &r);
4536 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
4537 !NT_STATUS_IS_OK(status)) {
4538 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
4542 torture_assert(tctx, sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
4544 if (sam->count == 0) {
4548 for (i=0;i<sam->count;i++) {
4550 if (!check_mask(p, tctx, handle, sam->entries[i].idx, mask)) {
4553 } else if (!test_OpenUser(p, tctx, handle, sam->entries[i].idx)) {
4559 printf("Testing LookupNames\n");
4560 n.in.domain_handle = handle;
4561 n.in.num_names = sam->count;
4562 n.in.names = talloc_array(tctx, struct lsa_String, sam->count);
4564 n.out.types = &types;
4565 for (i=0;i<sam->count;i++) {
4566 n.in.names[i].string = sam->entries[i].name.string;
4568 status = dcerpc_samr_LookupNames(p, tctx, &n);
4569 if (!NT_STATUS_IS_OK(status)) {
4570 printf("LookupNames failed - %s\n", nt_errstr(status));
4575 printf("Testing LookupRids\n");
4576 lr.in.domain_handle = handle;
4577 lr.in.num_rids = sam->count;
4578 lr.in.rids = talloc_array(tctx, uint32_t, sam->count);
4579 lr.out.names = &names;
4580 lr.out.types = &types;
4581 for (i=0;i<sam->count;i++) {
4582 lr.in.rids[i] = sam->entries[i].idx;
4584 status = dcerpc_samr_LookupRids(p, tctx, &lr);
4585 torture_assert_ntstatus_ok(tctx, status, "LookupRids");
4591 try blasting the server with a bunch of sync requests
4593 static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, struct torture_context *tctx,
4594 struct policy_handle *handle)
4597 struct samr_EnumDomainUsers r;
4598 uint32_t resume_handle=0;
4600 #define ASYNC_COUNT 100
4601 struct rpc_request *req[ASYNC_COUNT];
4603 if (!torture_setting_bool(tctx, "dangerous", false)) {
4604 torture_skip(tctx, "samr async test disabled - enable dangerous tests to use\n");
4607 torture_comment(tctx, "Testing EnumDomainUsers_async\n");
4609 r.in.domain_handle = handle;
4610 r.in.resume_handle = &resume_handle;
4611 r.in.acct_flags = 0;
4612 r.in.max_size = (uint32_t)-1;
4613 r.out.resume_handle = &resume_handle;
4615 for (i=0;i<ASYNC_COUNT;i++) {
4616 req[i] = dcerpc_samr_EnumDomainUsers_send(p, tctx, &r);
4619 for (i=0;i<ASYNC_COUNT;i++) {
4620 status = dcerpc_ndr_request_recv(req[i]);
4621 if (!NT_STATUS_IS_OK(status)) {
4622 printf("EnumDomainUsers[%d] failed - %s\n",
4623 i, nt_errstr(status));
4628 torture_comment(tctx, "%d async requests OK\n", i);
4633 static bool test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4634 struct policy_handle *handle)
4637 struct samr_EnumDomainGroups r;
4638 uint32_t resume_handle=0;
4639 struct samr_SamArray *sam = NULL;
4640 uint32_t num_entries = 0;
4644 printf("Testing EnumDomainGroups\n");
4646 r.in.domain_handle = handle;
4647 r.in.resume_handle = &resume_handle;
4648 r.in.max_size = (uint32_t)-1;
4649 r.out.resume_handle = &resume_handle;
4650 r.out.num_entries = &num_entries;
4653 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
4654 if (!NT_STATUS_IS_OK(status)) {
4655 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
4663 for (i=0;i<sam->count;i++) {
4664 if (!test_OpenGroup(p, mem_ctx, handle, sam->entries[i].idx)) {
4672 static bool test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4673 struct policy_handle *handle)
4676 struct samr_EnumDomainAliases r;
4677 uint32_t resume_handle=0;
4678 struct samr_SamArray *sam = NULL;
4679 uint32_t num_entries = 0;
4683 printf("Testing EnumDomainAliases\n");
4685 r.in.domain_handle = handle;
4686 r.in.resume_handle = &resume_handle;
4687 r.in.max_size = (uint32_t)-1;
4689 r.out.num_entries = &num_entries;
4690 r.out.resume_handle = &resume_handle;
4692 status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
4693 if (!NT_STATUS_IS_OK(status)) {
4694 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
4702 for (i=0;i<sam->count;i++) {
4703 if (!test_OpenAlias(p, mem_ctx, handle, sam->entries[i].idx)) {
4711 static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4712 struct policy_handle *handle)
4715 struct samr_GetDisplayEnumerationIndex r;
4717 uint16_t levels[] = {1, 2, 3, 4, 5};
4718 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
4719 struct lsa_String name;
4723 for (i=0;i<ARRAY_SIZE(levels);i++) {
4724 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
4726 init_lsa_String(&name, TEST_ACCOUNT_NAME);
4728 r.in.domain_handle = handle;
4729 r.in.level = levels[i];
4733 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
4736 !NT_STATUS_IS_OK(status) &&
4737 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
4738 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
4739 levels[i], nt_errstr(status));
4743 init_lsa_String(&name, "zzzzzzzz");
4745 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
4747 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
4748 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
4749 levels[i], nt_errstr(status));
4757 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4758 struct policy_handle *handle)
4761 struct samr_GetDisplayEnumerationIndex2 r;
4763 uint16_t levels[] = {1, 2, 3, 4, 5};
4764 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
4765 struct lsa_String name;
4769 for (i=0;i<ARRAY_SIZE(levels);i++) {
4770 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
4772 init_lsa_String(&name, TEST_ACCOUNT_NAME);
4774 r.in.domain_handle = handle;
4775 r.in.level = levels[i];
4779 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
4781 !NT_STATUS_IS_OK(status) &&
4782 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
4783 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
4784 levels[i], nt_errstr(status));
4788 init_lsa_String(&name, "zzzzzzzz");
4790 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
4791 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
4792 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
4793 levels[i], nt_errstr(status));
4801 #define STRING_EQUAL_QUERY(s1, s2, user) \
4802 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
4803 /* odd, but valid */ \
4804 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
4805 printf("%s mismatch for %s: %s != %s (%s)\n", \
4806 #s1, user.string, s1.string, s2.string, __location__); \
4809 #define INT_EQUAL_QUERY(s1, s2, user) \
4811 printf("%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
4812 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
4816 static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4817 struct samr_QueryDisplayInfo *querydisplayinfo,
4818 bool *seen_testuser)
4820 struct samr_OpenUser r;
4821 struct samr_QueryUserInfo q;
4822 union samr_UserInfo *info;
4823 struct policy_handle user_handle;
4826 r.in.domain_handle = querydisplayinfo->in.domain_handle;
4827 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4828 for (i = 0; ; i++) {
4829 switch (querydisplayinfo->in.level) {
4831 if (i >= querydisplayinfo->out.info->info1.count) {
4834 r.in.rid = querydisplayinfo->out.info->info1.entries[i].rid;
4837 if (i >= querydisplayinfo->out.info->info2.count) {
4840 r.in.rid = querydisplayinfo->out.info->info2.entries[i].rid;
4846 /* Not interested in validating just the account name */
4850 r.out.user_handle = &user_handle;
4852 switch (querydisplayinfo->in.level) {
4855 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
4856 if (!NT_STATUS_IS_OK(status)) {
4857 printf("OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(status));
4862 q.in.user_handle = &user_handle;
4865 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
4866 if (!NT_STATUS_IS_OK(status)) {
4867 printf("QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(status));
4871 switch (querydisplayinfo->in.level) {
4873 if (seen_testuser && strcmp(info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
4874 *seen_testuser = true;
4876 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].full_name,
4877 info->info21.full_name, info->info21.account_name);
4878 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].account_name,
4879 info->info21.account_name, info->info21.account_name);
4880 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].description,
4881 info->info21.description, info->info21.account_name);
4882 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].rid,
4883 info->info21.rid, info->info21.account_name);
4884 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].acct_flags,
4885 info->info21.acct_flags, info->info21.account_name);
4889 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].account_name,
4890 info->info21.account_name, info->info21.account_name);
4891 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].description,
4892 info->info21.description, info->info21.account_name);
4893 INT_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].rid,
4894 info->info21.rid, info->info21.account_name);
4895 INT_EQUAL_QUERY((querydisplayinfo->out.info->info2.entries[i].acct_flags & ~ACB_NORMAL),
4896 info->info21.acct_flags, info->info21.account_name);
4898 if (!(querydisplayinfo->out.info->info2.entries[i].acct_flags & ACB_NORMAL)) {
4899 printf("Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
4900 info->info21.account_name.string);
4903 if (!(info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
4904 printf("Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
4905 info->info21.account_name.string,
4906 querydisplayinfo->out.info->info2.entries[i].acct_flags,
4907 info->info21.acct_flags);
4914 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
4921 static bool test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4922 struct policy_handle *handle)
4925 struct samr_QueryDisplayInfo r;
4926 struct samr_QueryDomainInfo dom_info;
4927 union samr_DomainInfo *info = NULL;
4929 uint16_t levels[] = {1, 2, 3, 4, 5};
4931 bool seen_testuser = false;
4932 uint32_t total_size;
4933 uint32_t returned_size;
4934 union samr_DispInfo disp_info;
4937 for (i=0;i<ARRAY_SIZE(levels);i++) {
4938 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
4941 status = STATUS_MORE_ENTRIES;
4942 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
4943 r.in.domain_handle = handle;
4944 r.in.level = levels[i];
4945 r.in.max_entries = 2;
4946 r.in.buf_size = (uint32_t)-1;
4947 r.out.total_size = &total_size;
4948 r.out.returned_size = &returned_size;
4949 r.out.info = &disp_info;
4951 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
4952 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(status)) {
4953 printf("QueryDisplayInfo level %u failed - %s\n",
4954 levels[i], nt_errstr(status));
4957 switch (r.in.level) {
4959 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, &seen_testuser)) {
4962 r.in.start_idx += r.out.info->info1.count;
4965 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, NULL)) {
4968 r.in.start_idx += r.out.info->info2.count;
4971 r.in.start_idx += r.out.info->info3.count;
4974 r.in.start_idx += r.out.info->info4.count;
4977 r.in.start_idx += r.out.info->info5.count;
4981 dom_info.in.domain_handle = handle;
4982 dom_info.in.level = 2;
4983 dom_info.out.info = &info;
4985 /* Check number of users returned is correct */
4986 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &dom_info);
4987 if (!NT_STATUS_IS_OK(status)) {
4988 printf("QueryDomainInfo level %u failed - %s\n",
4989 r.in.level, nt_errstr(status));
4993 switch (r.in.level) {
4996 if (info->general.num_users < r.in.start_idx) {
4997 printf("QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
4998 r.in.start_idx, info->general.num_groups,
4999 info->general.domain_name.string);
5002 if (!seen_testuser) {
5003 struct policy_handle user_handle;
5004 if (NT_STATUS_IS_OK(test_OpenUser_byname(p, mem_ctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
5005 printf("Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
5006 info->general.domain_name.string);
5008 test_samr_handle_Close(p, mem_ctx, &user_handle);
5014 if (info->general.num_groups != r.in.start_idx) {
5015 printf("QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
5016 r.in.start_idx, info->general.num_groups,
5017 info->general.domain_name.string);
5029 static bool test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
5030 struct policy_handle *handle)
5033 struct samr_QueryDisplayInfo2 r;
5035 uint16_t levels[] = {1, 2, 3, 4, 5};
5037 uint32_t total_size;
5038 uint32_t returned_size;
5039 union samr_DispInfo info;
5041 for (i=0;i<ARRAY_SIZE(levels);i++) {
5042 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
5044 r.in.domain_handle = handle;
5045 r.in.level = levels[i];
5047 r.in.max_entries = 1000;
5048 r.in.buf_size = (uint32_t)-1;
5049 r.out.total_size = &total_size;
5050 r.out.returned_size = &returned_size;
5053 status = dcerpc_samr_QueryDisplayInfo2(p, mem_ctx, &r);
5054 if (!NT_STATUS_IS_OK(status)) {
5055 printf("QueryDisplayInfo2 level %u failed - %s\n",
5056 levels[i], nt_errstr(status));
5064 static bool test_QueryDisplayInfo3(struct dcerpc_pipe *p, struct torture_context *tctx,
5065 struct policy_handle *handle)
5068 struct samr_QueryDisplayInfo3 r;
5070 uint16_t levels[] = {1, 2, 3, 4, 5};
5072 uint32_t total_size;
5073 uint32_t returned_size;
5074 union samr_DispInfo info;
5076 for (i=0;i<ARRAY_SIZE(levels);i++) {
5077 torture_comment(tctx, "Testing QueryDisplayInfo3 level %u\n", levels[i]);
5079 r.in.domain_handle = handle;
5080 r.in.level = levels[i];
5082 r.in.max_entries = 1000;
5083 r.in.buf_size = (uint32_t)-1;
5084 r.out.total_size = &total_size;
5085 r.out.returned_size = &returned_size;
5088 status = dcerpc_samr_QueryDisplayInfo3(p, tctx, &r);
5089 if (!NT_STATUS_IS_OK(status)) {
5090 printf("QueryDisplayInfo3 level %u failed - %s\n",
5091 levels[i], nt_errstr(status));
5100 static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
5101 struct policy_handle *handle)
5104 struct samr_QueryDisplayInfo r;
5106 uint32_t total_size;
5107 uint32_t returned_size;
5108 union samr_DispInfo info;
5110 printf("Testing QueryDisplayInfo continuation\n");
5112 r.in.domain_handle = handle;
5115 r.in.max_entries = 1;
5116 r.in.buf_size = (uint32_t)-1;
5117 r.out.total_size = &total_size;
5118 r.out.returned_size = &returned_size;
5122 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
5123 if (NT_STATUS_IS_OK(status) && *r.out.returned_size != 0) {
5124 if (r.out.info->info1.entries[0].idx != r.in.start_idx + 1) {
5125 printf("expected idx %d but got %d\n",
5127 r.out.info->info1.entries[0].idx);
5131 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
5132 !NT_STATUS_IS_OK(status)) {
5133 printf("QueryDisplayInfo level %u failed - %s\n",
5134 r.in.level, nt_errstr(status));
5139 } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
5140 NT_STATUS_IS_OK(status)) &&
5141 *r.out.returned_size != 0);
5146 static bool test_QueryDomainInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
5147 struct policy_handle *handle)
5150 struct samr_QueryDomainInfo r;
5151 union samr_DomainInfo *info = NULL;
5152 struct samr_SetDomainInfo s;
5153 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
5154 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
5157 const char *domain_comment = talloc_asprintf(tctx,
5158 "Tortured by Samba4 RPC-SAMR: %s",
5159 timestring(tctx, time(NULL)));
5161 s.in.domain_handle = handle;
5163 s.in.info = talloc(tctx, union samr_DomainInfo);
5165 s.in.info->oem.oem_information.string = domain_comment;
5166 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
5167 if (!NT_STATUS_IS_OK(status)) {
5168 printf("SetDomainInfo level %u (set comment) failed - %s\n",
5169 s.in.level, nt_errstr(status));
5173 for (i=0;i<ARRAY_SIZE(levels);i++) {
5174 torture_comment(tctx, "Testing QueryDomainInfo level %u\n", levels[i]);
5176 r.in.domain_handle = handle;
5177 r.in.level = levels[i];
5180 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
5181 if (!NT_STATUS_IS_OK(status)) {
5182 printf("QueryDomainInfo level %u failed - %s\n",
5183 r.in.level, nt_errstr(status));
5188 switch (levels[i]) {
5190 if (strcmp(info->general.oem_information.string, domain_comment) != 0) {
5191 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
5192 levels[i], info->general.oem_information.string, domain_comment);
5195 if (!info->general.primary.string) {
5196 printf("QueryDomainInfo level %u returned no PDC name\n",
5199 } else if (info->general.role == SAMR_ROLE_DOMAIN_PDC) {
5200 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), info->general.primary.string) != 0) {
5201 printf("QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
5202 levels[i], info->general.primary.string, dcerpc_server_name(p));
5207 if (strcmp(info->oem.oem_information.string, domain_comment) != 0) {
5208 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
5209 levels[i], info->oem.oem_information.string, domain_comment);
5214 if (!info->info6.primary.string) {
5215 printf("QueryDomainInfo level %u returned no PDC name\n",
5221 if (strcmp(info->general2.general.oem_information.string, domain_comment) != 0) {
5222 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
5223 levels[i], info->general2.general.oem_information.string, domain_comment);
5229 torture_comment(tctx, "Testing SetDomainInfo level %u\n", levels[i]);
5231 s.in.domain_handle = handle;
5232 s.in.level = levels[i];
5235 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
5237 if (!NT_STATUS_IS_OK(status)) {
5238 printf("SetDomainInfo level %u failed - %s\n",
5239 r.in.level, nt_errstr(status));
5244 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
5245 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
5246 r.in.level, nt_errstr(status));
5252 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
5253 if (!NT_STATUS_IS_OK(status)) {
5254 printf("QueryDomainInfo level %u failed - %s\n",
5255 r.in.level, nt_errstr(status));
5265 static bool test_QueryDomainInfo2(struct dcerpc_pipe *p, struct torture_context *tctx,
5266 struct policy_handle *handle)
5269 struct samr_QueryDomainInfo2 r;
5270 union samr_DomainInfo *info = NULL;
5271 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
5275 for (i=0;i<ARRAY_SIZE(levels);i++) {
5276 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
5278 r.in.domain_handle = handle;
5279 r.in.level = levels[i];
5282 status = dcerpc_samr_QueryDomainInfo2(p, tctx, &r);
5283 if (!NT_STATUS_IS_OK(status)) {
5284 printf("QueryDomainInfo2 level %u failed - %s\n",
5285 r.in.level, nt_errstr(status));
5294 /* Test whether querydispinfo level 5 and enumdomgroups return the same
5295 set of group names. */
5296 static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx,
5297 struct policy_handle *handle)
5299 struct samr_EnumDomainGroups q1;
5300 struct samr_QueryDisplayInfo q2;
5302 uint32_t resume_handle=0;
5303 struct samr_SamArray *sam = NULL;
5304 uint32_t num_entries = 0;
5307 uint32_t total_size;
5308 uint32_t returned_size;
5309 union samr_DispInfo info;
5312 const char **names = NULL;
5314 torture_comment(tctx, "Testing coherency of querydispinfo vs enumdomgroups\n");
5316 q1.in.domain_handle = handle;
5317 q1.in.resume_handle = &resume_handle;
5319 q1.out.resume_handle = &resume_handle;
5320 q1.out.num_entries = &num_entries;
5323 status = STATUS_MORE_ENTRIES;
5324 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
5325 status = dcerpc_samr_EnumDomainGroups(p, tctx, &q1);
5327 if (!NT_STATUS_IS_OK(status) &&
5328 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
5331 for (i=0; i<*q1.out.num_entries; i++) {
5332 add_string_to_array(tctx,
5333 sam->entries[i].name.string,
5334 &names, &num_names);
5338 torture_assert_ntstatus_ok(tctx, status, "EnumDomainGroups");
5340 torture_assert(tctx, sam, "EnumDomainGroups failed to return sam");
5342 q2.in.domain_handle = handle;
5344 q2.in.start_idx = 0;
5345 q2.in.max_entries = 5;
5346 q2.in.buf_size = (uint32_t)-1;
5347 q2.out.total_size = &total_size;
5348 q2.out.returned_size = &returned_size;
5349 q2.out.info = &info;
5351 status = STATUS_MORE_ENTRIES;
5352 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
5353 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &q2);
5355 if (!NT_STATUS_IS_OK(status) &&
5356 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
5359 for (i=0; i<q2.out.info->info5.count; i++) {
5361 const char *name = q2.out.info->info5.entries[i].account_name.string;
5363 for (j=0; j<num_names; j++) {
5364 if (names[j] == NULL)
5366 if (strequal(names[j], name)) {
5374 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
5379 q2.in.start_idx += q2.out.info->info5.count;
5382 if (!NT_STATUS_IS_OK(status)) {
5383 printf("QueryDisplayInfo level 5 failed - %s\n",
5388 for (i=0; i<num_names; i++) {
5389 if (names[i] != NULL) {
5390 printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
5399 static bool test_DeleteDomainGroup(struct dcerpc_pipe *p, struct torture_context *tctx,
5400 struct policy_handle *group_handle)
5402 struct samr_DeleteDomainGroup d;
5405 torture_comment(tctx, "Testing DeleteDomainGroup\n");
5407 d.in.group_handle = group_handle;
5408 d.out.group_handle = group_handle;
5410 status = dcerpc_samr_DeleteDomainGroup(p, tctx, &d);
5411 torture_assert_ntstatus_ok(tctx, status, "DeleteDomainGroup");
5416 static bool test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
5417 struct policy_handle *domain_handle)
5419 struct samr_TestPrivateFunctionsDomain r;
5423 torture_comment(tctx, "Testing TestPrivateFunctionsDomain\n");
5425 r.in.domain_handle = domain_handle;
5427 status = dcerpc_samr_TestPrivateFunctionsDomain(p, tctx, &r);
5428 torture_assert_ntstatus_equal(tctx, NT_STATUS_NOT_IMPLEMENTED, status, "TestPrivateFunctionsDomain");
5433 static bool test_RidToSid(struct dcerpc_pipe *p, struct torture_context *tctx,
5434 struct dom_sid *domain_sid,
5435 struct policy_handle *domain_handle)
5437 struct samr_RidToSid r;
5440 struct dom_sid *calc_sid, *out_sid;
5441 int rids[] = { 0, 42, 512, 10200 };
5444 for (i=0;i<ARRAY_SIZE(rids);i++) {
5445 torture_comment(tctx, "Testing RidToSid\n");
5447 calc_sid = dom_sid_dup(tctx, domain_sid);
5448 r.in.domain_handle = domain_handle;
5450 r.out.sid = &out_sid;
5452 status = dcerpc_samr_RidToSid(p, tctx, &r);
5453 if (!NT_STATUS_IS_OK(status)) {
5454 printf("RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
5457 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
5459 if (!dom_sid_equal(calc_sid, out_sid)) {
5460 printf("RidToSid for %d failed - got %s, expected %s\n", rids[i],
5461 dom_sid_string(tctx, out_sid),
5462 dom_sid_string(tctx, calc_sid));
5471 static bool test_GetBootKeyInformation(struct dcerpc_pipe *p, struct torture_context *tctx,
5472 struct policy_handle *domain_handle)
5474 struct samr_GetBootKeyInformation r;
5477 uint32_t unknown = 0;
5479 torture_comment(tctx, "Testing GetBootKeyInformation\n");
5481 r.in.domain_handle = domain_handle;
5482 r.out.unknown = &unknown;
5484 status = dcerpc_samr_GetBootKeyInformation(p, tctx, &r);
5485 if (!NT_STATUS_IS_OK(status)) {
5486 /* w2k3 seems to fail this sometimes and pass it sometimes */
5487 torture_comment(tctx, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
5493 static bool test_AddGroupMember(struct dcerpc_pipe *p, struct torture_context *tctx,
5494 struct policy_handle *domain_handle,
5495 struct policy_handle *group_handle)
5498 struct samr_AddGroupMember r;
5499 struct samr_DeleteGroupMember d;
5500 struct samr_QueryGroupMember q;
5501 struct samr_RidTypeArray *rids = NULL;
5502 struct samr_SetMemberAttributesOfGroup s;
5505 status = test_LookupName(p, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
5506 torture_assert_ntstatus_ok(tctx, status, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME);
5508 r.in.group_handle = group_handle;
5510 r.in.flags = 0; /* ??? */
5512 torture_comment(tctx, "Testing AddGroupMember and DeleteGroupMember\n");
5514 d.in.group_handle = group_handle;
5517 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
5518 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_NOT_IN_GROUP, status, "DeleteGroupMember");
5520 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5521 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
5523 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5524 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_IN_GROUP, status, "AddGroupMember");
5526 if (torture_setting_bool(tctx, "samba4", false)) {
5527 torture_comment(tctx, "skipping SetMemberAttributesOfGroup test against Samba4\n");
5529 /* this one is quite strange. I am using random inputs in the
5530 hope of triggering an error that might give us a clue */
5532 s.in.group_handle = group_handle;
5533 s.in.unknown1 = random();
5534 s.in.unknown2 = random();
5536 status = dcerpc_samr_SetMemberAttributesOfGroup(p, tctx, &s);
5537 torture_assert_ntstatus_ok(tctx, status, "SetMemberAttributesOfGroup");
5540 q.in.group_handle = group_handle;
5543 status = dcerpc_samr_QueryGroupMember(p, tctx, &q);
5544 torture_assert_ntstatus_ok(tctx, status, "QueryGroupMember");
5546 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
5547 torture_assert_ntstatus_ok(tctx, status, "DeleteGroupMember");
5549 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5550 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
5556 static bool test_CreateDomainGroup(struct dcerpc_pipe *p,
5557 struct torture_context *tctx,
5558 struct policy_handle *domain_handle,
5559 struct policy_handle *group_handle,
5560 struct dom_sid *domain_sid)
5563 struct samr_CreateDomainGroup r;
5565 struct lsa_String name;
5568 init_lsa_String(&name, TEST_GROUPNAME);
5570 r.in.domain_handle = domain_handle;
5572 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5573 r.out.group_handle = group_handle;
5576 printf("Testing CreateDomainGroup(%s)\n", r.in.name->string);
5578 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
5580 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5581 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5582 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.name->string);
5585 printf("Server should have refused create of '%s', got %s instead\n", r.in.name->string,
5591 if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS)) {
5592 if (!test_DeleteGroup_byname(p, tctx, domain_handle, r.in.name->string)) {
5593 printf("CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
5597 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
5599 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
5600 if (!test_DeleteUser_byname(p, tctx, domain_handle, r.in.name->string)) {
5602 printf("CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
5606 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
5608 torture_assert_ntstatus_ok(tctx, status, "CreateDomainGroup");
5610 if (!test_AddGroupMember(p, tctx, domain_handle, group_handle)) {
5611 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
5615 if (!test_SetGroupInfo(p, tctx, group_handle)) {
5624 its not totally clear what this does. It seems to accept any sid you like.
5626 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p,
5627 struct torture_context *tctx,
5628 struct policy_handle *domain_handle)
5631 struct samr_RemoveMemberFromForeignDomain r;
5633 r.in.domain_handle = domain_handle;
5634 r.in.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-12-34-56-78");
5636 status = dcerpc_samr_RemoveMemberFromForeignDomain(p, tctx, &r);
5637 torture_assert_ntstatus_ok(tctx, status, "RemoveMemberFromForeignDomain");
5644 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
5645 struct policy_handle *handle);
5647 static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
5648 struct policy_handle *handle, struct dom_sid *sid,
5649 enum torture_samr_choice which_ops,
5650 struct cli_credentials *machine_credentials)
5653 struct samr_OpenDomain r;
5654 struct policy_handle domain_handle;
5655 struct policy_handle alias_handle;
5656 struct policy_handle user_handle;
5657 struct policy_handle group_handle;
5660 ZERO_STRUCT(alias_handle);
5661 ZERO_STRUCT(user_handle);
5662 ZERO_STRUCT(group_handle);
5663 ZERO_STRUCT(domain_handle);
5665 torture_comment(tctx, "Testing OpenDomain of %s\n", dom_sid_string(tctx, sid));
5667 r.in.connect_handle = handle;
5668 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5670 r.out.domain_handle = &domain_handle;
5672 status = dcerpc_samr_OpenDomain(p, tctx, &r);
5673 torture_assert_ntstatus_ok(tctx, status, "OpenDomain");
5675 /* run the domain tests with the main handle closed - this tests
5676 the servers reference counting */
5677 ret &= test_samr_handle_Close(p, tctx, handle);
5679 switch (which_ops) {
5680 case TORTURE_SAMR_USER_ATTRIBUTES:
5681 case TORTURE_SAMR_PASSWORDS:
5682 if (!torture_setting_bool(tctx, "samba3", false)) {
5683 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops, NULL);
5685 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops, NULL);
5686 /* This test needs 'complex' users to validate */
5687 ret &= test_QueryDisplayInfo(p, tctx, &domain_handle);
5689 printf("Testing PASSWORDS or ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
5692 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
5693 if (!torture_setting_bool(tctx, "samba3", false)) {
5694 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops, machine_credentials);
5696 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops, machine_credentials);
5698 printf("Testing PASSWORDS PWDLASTSET on domain %s failed!\n", dom_sid_string(tctx, sid));
5701 case TORTURE_SAMR_OTHER:
5702 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops, NULL);
5704 printf("Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid));
5706 ret &= test_QuerySecurity(p, tctx, &domain_handle);
5707 ret &= test_RemoveMemberFromForeignDomain(p, tctx, &domain_handle);
5708 ret &= test_CreateAlias(p, tctx, &domain_handle, &alias_handle, sid);
5709 ret &= test_CreateDomainGroup(p, tctx, &domain_handle, &group_handle, sid);
5710 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
5711 ret &= test_QueryDomainInfo2(p, tctx, &domain_handle);
5712 ret &= test_EnumDomainUsers(p, tctx, &domain_handle);
5713 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
5714 ret &= test_EnumDomainGroups(p, tctx, &domain_handle);
5715 ret &= test_EnumDomainAliases(p, tctx, &domain_handle);
5716 ret &= test_QueryDisplayInfo2(p, tctx, &domain_handle);
5717 ret &= test_QueryDisplayInfo3(p, tctx, &domain_handle);
5718 ret &= test_QueryDisplayInfo_continue(p, tctx, &domain_handle);
5720 if (torture_setting_bool(tctx, "samba4", false)) {
5721 torture_comment(tctx, "skipping GetDisplayEnumerationIndex test against Samba4\n");
5723 ret &= test_GetDisplayEnumerationIndex(p, tctx, &domain_handle);
5724 ret &= test_GetDisplayEnumerationIndex2(p, tctx, &domain_handle);
5726 ret &= test_GroupList(p, tctx, &domain_handle);
5727 ret &= test_TestPrivateFunctionsDomain(p, tctx, &domain_handle);
5728 ret &= test_RidToSid(p, tctx, sid, &domain_handle);
5729 ret &= test_GetBootKeyInformation(p, tctx, &domain_handle);
5731 torture_comment(tctx, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx, sid));
5736 if (!policy_handle_empty(&user_handle) &&
5737 !test_DeleteUser(p, tctx, &user_handle)) {
5741 if (!policy_handle_empty(&alias_handle) &&
5742 !test_DeleteAlias(p, tctx, &alias_handle)) {
5746 if (!policy_handle_empty(&group_handle) &&
5747 !test_DeleteDomainGroup(p, tctx, &group_handle)) {
5751 ret &= test_samr_handle_Close(p, tctx, &domain_handle);
5753 /* reconnect the main handle */
5754 ret &= test_Connect(p, tctx, handle);
5757 printf("Testing domain %s failed!\n", dom_sid_string(tctx, sid));
5763 static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
5764 struct policy_handle *handle, const char *domain,
5765 enum torture_samr_choice which_ops,
5766 struct cli_credentials *machine_credentials)
5769 struct samr_LookupDomain r;
5770 struct dom_sid2 *sid = NULL;
5771 struct lsa_String n1;
5772 struct lsa_String n2;
5775 torture_comment(tctx, "Testing LookupDomain(%s)\n", domain);
5777 /* check for correct error codes */
5778 r.in.connect_handle = handle;
5779 r.in.domain_name = &n2;
5783 status = dcerpc_samr_LookupDomain(p, tctx, &r);
5784 torture_assert_ntstatus_equal(tctx, NT_STATUS_INVALID_PARAMETER, status, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
5786 init_lsa_String(&n2, "xxNODOMAINxx");
5788 status = dcerpc_samr_LookupDomain(p, tctx, &r);
5789 torture_assert_ntstatus_equal(tctx, NT_STATUS_NO_SUCH_DOMAIN, status, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
5791 r.in.connect_handle = handle;
5793 init_lsa_String(&n1, domain);
5794 r.in.domain_name = &n1;
5796 status = dcerpc_samr_LookupDomain(p, tctx, &r);
5797 torture_assert_ntstatus_ok(tctx, status, "LookupDomain");
5799 if (!test_GetDomPwInfo(p, tctx, &n1)) {
5803 if (!test_OpenDomain(p, tctx, handle, *r.out.sid, which_ops,
5804 machine_credentials)) {
5812 static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
5813 struct policy_handle *handle, enum torture_samr_choice which_ops,
5814 struct cli_credentials *machine_credentials)
5817 struct samr_EnumDomains r;
5818 uint32_t resume_handle = 0;
5819 uint32_t num_entries = 0;
5820 struct samr_SamArray *sam = NULL;
5824 r.in.connect_handle = handle;
5825 r.in.resume_handle = &resume_handle;
5826 r.in.buf_size = (uint32_t)-1;
5827 r.out.resume_handle = &resume_handle;
5828 r.out.num_entries = &num_entries;
5831 status = dcerpc_samr_EnumDomains(p, tctx, &r);
5832 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
5838 for (i=0;i<sam->count;i++) {
5839 if (!test_LookupDomain(p, tctx, handle,
5840 sam->entries[i].name.string, which_ops,
5841 machine_credentials)) {
5846 status = dcerpc_samr_EnumDomains(p, tctx, &r);
5847 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
5853 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
5854 struct policy_handle *handle)
5857 struct samr_Connect r;
5858 struct samr_Connect2 r2;
5859 struct samr_Connect3 r3;
5860 struct samr_Connect4 r4;
5861 struct samr_Connect5 r5;
5862 union samr_ConnectInfo info;
5863 struct policy_handle h;
5864 uint32_t level_out = 0;
5865 bool ret = true, got_handle = false;
5867 torture_comment(tctx, "testing samr_Connect\n");
5869 r.in.system_name = 0;
5870 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5871 r.out.connect_handle = &h;
5873 status = dcerpc_samr_Connect(p, tctx, &r);
5874 if (!NT_STATUS_IS_OK(status)) {
5875 torture_comment(tctx, "Connect failed - %s\n", nt_errstr(status));
5882 torture_comment(tctx, "testing samr_Connect2\n");
5884 r2.in.system_name = NULL;
5885 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5886 r2.out.connect_handle = &h;
5888 status = dcerpc_samr_Connect2(p, tctx, &r2);
5889 if (!NT_STATUS_IS_OK(status)) {
5890 torture_comment(tctx, "Connect2 failed - %s\n", nt_errstr(status));
5894 test_samr_handle_Close(p, tctx, handle);
5900 torture_comment(tctx, "testing samr_Connect3\n");
5902 r3.in.system_name = NULL;
5904 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5905 r3.out.connect_handle = &h;
5907 status = dcerpc_samr_Connect3(p, tctx, &r3);
5908 if (!NT_STATUS_IS_OK(status)) {
5909 printf("Connect3 failed - %s\n", nt_errstr(status));
5913 test_samr_handle_Close(p, tctx, handle);
5919 torture_comment(tctx, "testing samr_Connect4\n");
5921 r4.in.system_name = "";
5922 r4.in.client_version = 0;
5923 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5924 r4.out.connect_handle = &h;
5926 status = dcerpc_samr_Connect4(p, tctx, &r4);
5927 if (!NT_STATUS_IS_OK(status)) {
5928 printf("Connect4 failed - %s\n", nt_errstr(status));
5932 test_samr_handle_Close(p, tctx, handle);
5938 torture_comment(tctx, "testing samr_Connect5\n");
5940 info.info1.client_version = 0;
5941 info.info1.unknown2 = 0;
5943 r5.in.system_name = "";
5944 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5946 r5.out.level_out = &level_out;
5947 r5.in.info_in = &info;
5948 r5.out.info_out = &info;
5949 r5.out.connect_handle = &h;
5951 status = dcerpc_samr_Connect5(p, tctx, &r5);
5952 if (!NT_STATUS_IS_OK(status)) {
5953 printf("Connect5 failed - %s\n", nt_errstr(status));
5957 test_samr_handle_Close(p, tctx, handle);
5967 bool torture_rpc_samr(struct torture_context *torture)
5970 struct dcerpc_pipe *p;
5972 struct policy_handle handle;
5974 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
5975 if (!NT_STATUS_IS_OK(status)) {
5979 ret &= test_Connect(p, torture, &handle);
5981 ret &= test_QuerySecurity(p, torture, &handle);
5983 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_OTHER, NULL);
5985 ret &= test_SetDsrmPassword(p, torture, &handle);
5987 ret &= test_Shutdown(p, torture, &handle);
5989 ret &= test_samr_handle_Close(p, torture, &handle);
5995 bool torture_rpc_samr_users(struct torture_context *torture)
5998 struct dcerpc_pipe *p;
6000 struct policy_handle handle;
6002 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6003 if (!NT_STATUS_IS_OK(status)) {
6007 ret &= test_Connect(p, torture, &handle);
6009 ret &= test_QuerySecurity(p, torture, &handle);
6011 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_USER_ATTRIBUTES, NULL);
6013 ret &= test_SetDsrmPassword(p, torture, &handle);
6015 ret &= test_Shutdown(p, torture, &handle);
6017 ret &= test_samr_handle_Close(p, torture, &handle);
6023 bool torture_rpc_samr_passwords(struct torture_context *torture)
6026 struct dcerpc_pipe *p;
6028 struct policy_handle handle;
6030 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6031 if (!NT_STATUS_IS_OK(status)) {
6035 ret &= test_Connect(p, torture, &handle);
6037 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_PASSWORDS, NULL);
6039 ret &= test_samr_handle_Close(p, torture, &handle);
6044 static bool torture_rpc_samr_pwdlastset(struct torture_context *torture,
6045 struct dcerpc_pipe *p2,
6046 struct cli_credentials *machine_credentials)
6049 struct dcerpc_pipe *p;
6051 struct policy_handle handle;
6053 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6054 if (!NT_STATUS_IS_OK(status)) {
6058 ret &= test_Connect(p, torture, &handle);
6060 ret &= test_EnumDomains(p, torture, &handle,
6061 TORTURE_SAMR_PASSWORDS_PWDLASTSET,
6062 machine_credentials);
6064 ret &= test_samr_handle_Close(p, torture, &handle);
6069 struct torture_suite *torture_rpc_samr_passwords_pwdlastset(TALLOC_CTX *mem_ctx)
6071 struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-PASSWORDS-PWDLASTSET");
6072 struct torture_rpc_tcase *tcase;
6074 tcase = torture_suite_add_machine_rpc_iface_tcase(suite, "samr",
6076 TEST_ACCOUNT_NAME_PWD);
6078 torture_rpc_tcase_add_test_creds(tcase, "pwdLastSet",
6079 torture_rpc_samr_pwdlastset);