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;
193 if (!torture_setting_bool(tctx, "samba3", false)) {
194 if (base_acct_flags == ACB_NORMAL) {
195 /* When created, accounts are expired by default */
196 user_extra_flags = ACB_PW_EXPIRED;
200 s.in.user_handle = handle;
203 s2.in.user_handle = handle;
206 q.in.user_handle = handle;
210 #define TESTCALL(call, r) \
211 status = dcerpc_samr_ ##call(p, tctx, &r); \
212 if (!NT_STATUS_IS_OK(status)) { \
213 torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
214 r.in.level, nt_errstr(status), __location__); \
219 #define STRING_EQUAL(s1, s2, field) \
220 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
221 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
222 #field, s2, __location__); \
227 #define MEM_EQUAL(s1, s2, length, field) \
228 if ((s1 && !s2) || (s2 && !s1) || memcmp(s1, s2, length)) { \
229 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
230 #field, (const char *)s2, __location__); \
235 #define INT_EQUAL(i1, i2, field) \
237 torture_comment(tctx, "Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \
238 #field, (unsigned long long)i2, (unsigned long long)i1, __location__); \
243 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
244 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
246 TESTCALL(QueryUserInfo, q) \
248 s2.in.level = lvl1; \
251 ZERO_STRUCT(u.info21); \
252 u.info21.fields_present = fpval; \
254 init_lsa_String(&u.info ## lvl1.field1, value); \
255 TESTCALL(SetUserInfo, s) \
256 TESTCALL(SetUserInfo2, s2) \
257 init_lsa_String(&u.info ## lvl1.field1, ""); \
258 TESTCALL(QueryUserInfo, q); \
260 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
262 TESTCALL(QueryUserInfo, q) \
264 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
267 #define TEST_USERINFO_BINARYSTRING(lvl1, field1, lvl2, field2, value, fpval) do { \
268 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
270 TESTCALL(QueryUserInfo, q) \
272 s2.in.level = lvl1; \
275 ZERO_STRUCT(u.info21); \
276 u.info21.fields_present = fpval; \
278 init_lsa_BinaryString(&u.info ## lvl1.field1, value, strlen(value)); \
279 TESTCALL(SetUserInfo, s) \
280 TESTCALL(SetUserInfo2, s2) \
281 init_lsa_BinaryString(&u.info ## lvl1.field1, "", 1); \
282 TESTCALL(QueryUserInfo, q); \
284 MEM_EQUAL(u.info ## lvl1.field1.array, value, strlen(value), field1); \
286 TESTCALL(QueryUserInfo, q) \
288 MEM_EQUAL(u.info ## lvl2.field2.array, value, strlen(value), field2); \
291 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
292 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
294 TESTCALL(QueryUserInfo, q) \
296 s2.in.level = lvl1; \
299 uint8_t *bits = u.info21.logon_hours.bits; \
300 ZERO_STRUCT(u.info21); \
301 if (fpval == SAMR_FIELD_LOGON_HOURS) { \
302 u.info21.logon_hours.units_per_week = 168; \
303 u.info21.logon_hours.bits = bits; \
305 u.info21.fields_present = fpval; \
307 u.info ## lvl1.field1 = value; \
308 TESTCALL(SetUserInfo, s) \
309 TESTCALL(SetUserInfo2, s2) \
310 u.info ## lvl1.field1 = 0; \
311 TESTCALL(QueryUserInfo, q); \
313 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
315 TESTCALL(QueryUserInfo, q) \
317 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
320 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
321 TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
325 do { TESTCALL(QueryUserInfo, q0) } while (0);
327 /* Samba 3 cannot store comment fields atm. - gd */
328 if (!torture_setting_bool(tctx, "samba3", false)) {
329 TEST_USERINFO_STRING(2, comment, 1, comment, "xx2-1 comment", 0);
330 TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
331 TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment",
335 test_account_name = talloc_asprintf(tctx, "%sxx7-1", base_account_name);
336 TEST_USERINFO_STRING(7, account_name, 1, account_name, base_account_name, 0);
337 test_account_name = talloc_asprintf(tctx, "%sxx7-3", base_account_name);
338 TEST_USERINFO_STRING(7, account_name, 3, account_name, base_account_name, 0);
339 test_account_name = talloc_asprintf(tctx, "%sxx7-5", base_account_name);
340 TEST_USERINFO_STRING(7, account_name, 5, account_name, base_account_name, 0);
341 test_account_name = talloc_asprintf(tctx, "%sxx7-6", base_account_name);
342 TEST_USERINFO_STRING(7, account_name, 6, account_name, base_account_name, 0);
343 test_account_name = talloc_asprintf(tctx, "%sxx7-7", base_account_name);
344 TEST_USERINFO_STRING(7, account_name, 7, account_name, base_account_name, 0);
345 test_account_name = talloc_asprintf(tctx, "%sxx7-21", base_account_name);
346 TEST_USERINFO_STRING(7, account_name, 21, account_name, base_account_name, 0);
347 test_account_name = base_account_name;
348 TEST_USERINFO_STRING(21, account_name, 21, account_name, base_account_name,
349 SAMR_FIELD_ACCOUNT_NAME);
351 TEST_USERINFO_STRING(6, full_name, 1, full_name, "xx6-1 full_name", 0);
352 TEST_USERINFO_STRING(6, full_name, 3, full_name, "xx6-3 full_name", 0);
353 TEST_USERINFO_STRING(6, full_name, 5, full_name, "xx6-5 full_name", 0);
354 TEST_USERINFO_STRING(6, full_name, 6, full_name, "xx6-6 full_name", 0);
355 TEST_USERINFO_STRING(6, full_name, 8, full_name, "xx6-8 full_name", 0);
356 TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
357 TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
358 TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name",
359 SAMR_FIELD_FULL_NAME);
361 TEST_USERINFO_STRING(6, full_name, 1, full_name, "", 0);
362 TEST_USERINFO_STRING(6, full_name, 3, full_name, "", 0);
363 TEST_USERINFO_STRING(6, full_name, 5, full_name, "", 0);
364 TEST_USERINFO_STRING(6, full_name, 6, full_name, "", 0);
365 TEST_USERINFO_STRING(6, full_name, 8, full_name, "", 0);
366 TEST_USERINFO_STRING(6, full_name, 21, full_name, "", 0);
367 TEST_USERINFO_STRING(8, full_name, 21, full_name, "", 0);
368 TEST_USERINFO_STRING(21, full_name, 21, full_name, "",
369 SAMR_FIELD_FULL_NAME);
371 TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
372 TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
373 TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
374 TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script",
375 SAMR_FIELD_LOGON_SCRIPT);
377 TEST_USERINFO_STRING(12, profile_path, 3, profile_path, "xx12-3 profile_path", 0);
378 TEST_USERINFO_STRING(12, profile_path, 5, profile_path, "xx12-5 profile_path", 0);
379 TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
380 TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path",
381 SAMR_FIELD_PROFILE_PATH);
383 TEST_USERINFO_STRING(10, home_directory, 3, home_directory, "xx10-3 home_directory", 0);
384 TEST_USERINFO_STRING(10, home_directory, 5, home_directory, "xx10-5 home_directory", 0);
385 TEST_USERINFO_STRING(10, home_directory, 21, home_directory, "xx10-21 home_directory", 0);
386 TEST_USERINFO_STRING(21, home_directory, 21, home_directory, "xx21-21 home_directory",
387 SAMR_FIELD_HOME_DIRECTORY);
388 TEST_USERINFO_STRING(21, home_directory, 10, home_directory, "xx21-10 home_directory",
389 SAMR_FIELD_HOME_DIRECTORY);
391 TEST_USERINFO_STRING(10, home_drive, 3, home_drive, "xx10-3 home_drive", 0);
392 TEST_USERINFO_STRING(10, home_drive, 5, home_drive, "xx10-5 home_drive", 0);
393 TEST_USERINFO_STRING(10, home_drive, 21, home_drive, "xx10-21 home_drive", 0);
394 TEST_USERINFO_STRING(21, home_drive, 21, home_drive, "xx21-21 home_drive",
395 SAMR_FIELD_HOME_DRIVE);
396 TEST_USERINFO_STRING(21, home_drive, 10, home_drive, "xx21-10 home_drive",
397 SAMR_FIELD_HOME_DRIVE);
399 TEST_USERINFO_STRING(13, description, 1, description, "xx13-1 description", 0);
400 TEST_USERINFO_STRING(13, description, 5, description, "xx13-5 description", 0);
401 TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
402 TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description",
403 SAMR_FIELD_DESCRIPTION);
405 TEST_USERINFO_STRING(14, workstations, 3, workstations, "14workstation3", 0);
406 TEST_USERINFO_STRING(14, workstations, 5, workstations, "14workstation4", 0);
407 TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
408 TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21",
409 SAMR_FIELD_WORKSTATIONS);
410 TEST_USERINFO_STRING(21, workstations, 3, workstations, "21workstation3",
411 SAMR_FIELD_WORKSTATIONS);
412 TEST_USERINFO_STRING(21, workstations, 5, workstations, "21workstation5",
413 SAMR_FIELD_WORKSTATIONS);
414 TEST_USERINFO_STRING(21, workstations, 14, workstations, "21workstation14",
415 SAMR_FIELD_WORKSTATIONS);
417 TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
418 TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "xx21-21 parameters",
419 SAMR_FIELD_PARAMETERS);
420 TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "xx21-20 parameters",
421 SAMR_FIELD_PARAMETERS);
422 /* also empty user parameters are allowed */
423 TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "", 0);
424 TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "",
425 SAMR_FIELD_PARAMETERS);
426 TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "",
427 SAMR_FIELD_PARAMETERS);
429 /* Samba 3 cannot store country_code and copy_page atm. - gd */
430 if (!torture_setting_bool(tctx, "samba3", false)) {
431 TEST_USERINFO_INT(2, country_code, 2, country_code, __LINE__, 0);
432 TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
433 TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__,
434 SAMR_FIELD_COUNTRY_CODE);
435 TEST_USERINFO_INT(21, country_code, 2, country_code, __LINE__,
436 SAMR_FIELD_COUNTRY_CODE);
438 TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
439 TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__,
440 SAMR_FIELD_CODE_PAGE);
441 TEST_USERINFO_INT(21, code_page, 2, code_page, __LINE__,
442 SAMR_FIELD_CODE_PAGE);
445 if (!torture_setting_bool(tctx, "samba3", false)) {
446 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, __LINE__, 0);
447 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, __LINE__, 0);
448 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, __LINE__,
449 SAMR_FIELD_ACCT_EXPIRY);
450 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, __LINE__,
451 SAMR_FIELD_ACCT_EXPIRY);
452 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, __LINE__,
453 SAMR_FIELD_ACCT_EXPIRY);
455 /* Samba 3 can only store seconds / time_t in passdb - gd */
457 unix_to_nt_time(&nt, time(NULL) + __LINE__);
458 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, nt, 0);
459 unix_to_nt_time(&nt, time(NULL) + __LINE__);
460 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, nt, 0);
461 unix_to_nt_time(&nt, time(NULL) + __LINE__);
462 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
463 unix_to_nt_time(&nt, time(NULL) + __LINE__);
464 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
465 unix_to_nt_time(&nt, time(NULL) + __LINE__);
466 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
469 TEST_USERINFO_INT(4, logon_hours.bits[3], 3, logon_hours.bits[3], 1, 0);
470 TEST_USERINFO_INT(4, logon_hours.bits[3], 5, logon_hours.bits[3], 2, 0);
471 TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
472 TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4,
473 SAMR_FIELD_LOGON_HOURS);
475 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
476 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
477 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
479 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
480 (base_acct_flags | ACB_DISABLED),
481 (base_acct_flags | ACB_DISABLED | user_extra_flags),
484 /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
485 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
486 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
487 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
489 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
490 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
491 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
495 /* The 'autolock' flag doesn't stick - check this */
496 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
497 (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK),
498 (base_acct_flags | ACB_DISABLED | user_extra_flags),
501 /* Removing the 'disabled' flag doesn't stick - check this */
502 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
504 (base_acct_flags | ACB_DISABLED | user_extra_flags),
508 /* Samba3 cannot store these atm */
509 if (!torture_setting_bool(tctx, "samba3", false)) {
510 /* The 'store plaintext' flag does stick */
511 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
512 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED),
513 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags),
515 /* The 'use DES' flag does stick */
516 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
517 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY),
518 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags),
520 /* The 'don't require kerberos pre-authentication flag does stick */
521 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
522 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH),
523 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags),
525 /* The 'no kerberos PAC required' flag sticks */
526 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
527 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD),
528 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags),
531 TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags,
532 (base_acct_flags | ACB_DISABLED),
533 (base_acct_flags | ACB_DISABLED | user_extra_flags),
534 SAMR_FIELD_ACCT_FLAGS);
537 /* these fail with win2003 - it appears you can't set the primary gid?
538 the set succeeds, but the gid isn't changed. Very weird! */
539 TEST_USERINFO_INT(9, primary_gid, 1, primary_gid, 513);
540 TEST_USERINFO_INT(9, primary_gid, 3, primary_gid, 513);
541 TEST_USERINFO_INT(9, primary_gid, 5, primary_gid, 513);
542 TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
549 generate a random password for password change tests
551 static char *samr_rand_pass_silent(TALLOC_CTX *mem_ctx, int min_len)
553 size_t len = MAX(8, min_len) + (random() % 6);
554 char *s = generate_random_str(mem_ctx, len);
558 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
560 char *s = samr_rand_pass_silent(mem_ctx, min_len);
561 printf("Generated password '%s'\n", s);
567 generate a random password for password change tests
569 static DATA_BLOB samr_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
572 DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
573 generate_random_buffer(password.data, password.length);
575 for (i=0; i < len; i++) {
576 if (((uint16_t *)password.data)[i] == 0) {
577 ((uint16_t *)password.data)[i] = 1;
585 generate a random password for password change tests (fixed length)
587 static char *samr_rand_pass_fixed_len(TALLOC_CTX *mem_ctx, int len)
589 char *s = generate_random_str(mem_ctx, len);
590 printf("Generated password '%s'\n", s);
594 static bool test_SetUserPass(struct dcerpc_pipe *p, struct torture_context *tctx,
595 struct policy_handle *handle, char **password)
598 struct samr_SetUserInfo s;
599 union samr_UserInfo u;
601 DATA_BLOB session_key;
603 struct samr_GetUserPwInfo pwp;
604 struct samr_PwInfo info;
605 int policy_min_pw_len = 0;
606 pwp.in.user_handle = handle;
607 pwp.out.info = &info;
609 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
610 if (NT_STATUS_IS_OK(status)) {
611 policy_min_pw_len = pwp.out.info->min_password_length;
613 newpass = samr_rand_pass(tctx, policy_min_pw_len);
615 s.in.user_handle = handle;
619 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
620 u.info24.password_expired = 0;
622 status = dcerpc_fetch_session_key(p, &session_key);
623 if (!NT_STATUS_IS_OK(status)) {
624 printf("SetUserInfo level %u - no session key - %s\n",
625 s.in.level, nt_errstr(status));
629 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
631 torture_comment(tctx, "Testing SetUserInfo level 24 (set password)\n");
633 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
634 if (!NT_STATUS_IS_OK(status)) {
635 printf("SetUserInfo level %u failed - %s\n",
636 s.in.level, nt_errstr(status));
646 static bool test_SetUserPass_23(struct dcerpc_pipe *p, struct torture_context *tctx,
647 struct policy_handle *handle, uint32_t fields_present,
651 struct samr_SetUserInfo s;
652 union samr_UserInfo u;
654 DATA_BLOB session_key;
656 struct samr_GetUserPwInfo pwp;
657 struct samr_PwInfo info;
658 int policy_min_pw_len = 0;
659 pwp.in.user_handle = handle;
660 pwp.out.info = &info;
662 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
663 if (NT_STATUS_IS_OK(status)) {
664 policy_min_pw_len = pwp.out.info->min_password_length;
666 newpass = samr_rand_pass(tctx, policy_min_pw_len);
668 s.in.user_handle = handle;
674 u.info23.info.fields_present = fields_present;
676 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
678 status = dcerpc_fetch_session_key(p, &session_key);
679 if (!NT_STATUS_IS_OK(status)) {
680 printf("SetUserInfo level %u - no session key - %s\n",
681 s.in.level, nt_errstr(status));
685 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
687 torture_comment(tctx, "Testing SetUserInfo level 23 (set password)\n");
689 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
690 if (!NT_STATUS_IS_OK(status)) {
691 printf("SetUserInfo level %u failed - %s\n",
692 s.in.level, nt_errstr(status));
698 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
700 status = dcerpc_fetch_session_key(p, &session_key);
701 if (!NT_STATUS_IS_OK(status)) {
702 printf("SetUserInfo level %u - no session key - %s\n",
703 s.in.level, nt_errstr(status));
707 /* This should break the key nicely */
708 session_key.length--;
709 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
711 torture_comment(tctx, "Testing SetUserInfo level 23 (set password) with wrong password\n");
713 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
714 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
715 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
716 s.in.level, nt_errstr(status));
724 static bool test_SetUserPassEx(struct dcerpc_pipe *p, struct torture_context *tctx,
725 struct policy_handle *handle, bool makeshort,
729 struct samr_SetUserInfo s;
730 union samr_UserInfo u;
732 DATA_BLOB session_key;
733 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
734 uint8_t confounder[16];
736 struct MD5Context ctx;
737 struct samr_GetUserPwInfo pwp;
738 struct samr_PwInfo info;
739 int policy_min_pw_len = 0;
740 pwp.in.user_handle = handle;
741 pwp.out.info = &info;
743 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
744 if (NT_STATUS_IS_OK(status)) {
745 policy_min_pw_len = pwp.out.info->min_password_length;
747 if (makeshort && policy_min_pw_len) {
748 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len - 1);
750 newpass = samr_rand_pass(tctx, policy_min_pw_len);
753 s.in.user_handle = handle;
757 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
758 u.info26.password_expired = 0;
760 status = dcerpc_fetch_session_key(p, &session_key);
761 if (!NT_STATUS_IS_OK(status)) {
762 printf("SetUserInfo level %u - no session key - %s\n",
763 s.in.level, nt_errstr(status));
767 generate_random_buffer((uint8_t *)confounder, 16);
770 MD5Update(&ctx, confounder, 16);
771 MD5Update(&ctx, session_key.data, session_key.length);
772 MD5Final(confounded_session_key.data, &ctx);
774 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
775 memcpy(&u.info26.password.data[516], confounder, 16);
777 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex)\n");
779 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
780 if (!NT_STATUS_IS_OK(status)) {
781 printf("SetUserInfo level %u failed - %s\n",
782 s.in.level, nt_errstr(status));
788 /* This should break the key nicely */
789 confounded_session_key.data[0]++;
791 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
792 memcpy(&u.info26.password.data[516], confounder, 16);
794 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
796 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
797 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
798 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
799 s.in.level, nt_errstr(status));
808 static bool test_SetUserPass_25(struct dcerpc_pipe *p, struct torture_context *tctx,
809 struct policy_handle *handle, uint32_t fields_present,
813 struct samr_SetUserInfo s;
814 union samr_UserInfo u;
816 DATA_BLOB session_key;
817 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
818 struct MD5Context ctx;
819 uint8_t confounder[16];
821 struct samr_GetUserPwInfo pwp;
822 struct samr_PwInfo info;
823 int policy_min_pw_len = 0;
824 pwp.in.user_handle = handle;
825 pwp.out.info = &info;
827 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
828 if (NT_STATUS_IS_OK(status)) {
829 policy_min_pw_len = pwp.out.info->min_password_length;
831 newpass = samr_rand_pass(tctx, policy_min_pw_len);
833 s.in.user_handle = handle;
839 u.info25.info.fields_present = fields_present;
841 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
843 status = dcerpc_fetch_session_key(p, &session_key);
844 if (!NT_STATUS_IS_OK(status)) {
845 printf("SetUserInfo level %u - no session key - %s\n",
846 s.in.level, nt_errstr(status));
850 generate_random_buffer((uint8_t *)confounder, 16);
853 MD5Update(&ctx, confounder, 16);
854 MD5Update(&ctx, session_key.data, session_key.length);
855 MD5Final(confounded_session_key.data, &ctx);
857 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
858 memcpy(&u.info25.password.data[516], confounder, 16);
860 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex)\n");
862 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
863 if (!NT_STATUS_IS_OK(status)) {
864 printf("SetUserInfo level %u failed - %s\n",
865 s.in.level, nt_errstr(status));
871 /* This should break the key nicely */
872 confounded_session_key.data[0]++;
874 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
875 memcpy(&u.info25.password.data[516], confounder, 16);
877 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
879 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
880 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
881 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
882 s.in.level, nt_errstr(status));
889 static bool test_SetUserPass_18(struct dcerpc_pipe *p, struct torture_context *tctx,
890 struct policy_handle *handle, char **password)
893 struct samr_SetUserInfo s;
894 union samr_UserInfo u;
896 DATA_BLOB session_key;
898 struct samr_GetUserPwInfo pwp;
899 struct samr_PwInfo info;
900 int policy_min_pw_len = 0;
901 uint8_t lm_hash[16], nt_hash[16];
903 pwp.in.user_handle = handle;
904 pwp.out.info = &info;
906 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
907 if (NT_STATUS_IS_OK(status)) {
908 policy_min_pw_len = pwp.out.info->min_password_length;
910 newpass = samr_rand_pass(tctx, policy_min_pw_len);
912 s.in.user_handle = handle;
918 u.info18.nt_pwd_active = true;
919 u.info18.lm_pwd_active = true;
921 E_md4hash(newpass, nt_hash);
922 E_deshash(newpass, lm_hash);
924 status = dcerpc_fetch_session_key(p, &session_key);
925 if (!NT_STATUS_IS_OK(status)) {
926 printf("SetUserInfo level %u - no session key - %s\n",
927 s.in.level, nt_errstr(status));
933 in = data_blob_const(nt_hash, 16);
934 out = data_blob_talloc_zero(tctx, 16);
935 sess_crypt_blob(&out, &in, &session_key, true);
936 memcpy(u.info18.nt_pwd.hash, out.data, out.length);
940 in = data_blob_const(lm_hash, 16);
941 out = data_blob_talloc_zero(tctx, 16);
942 sess_crypt_blob(&out, &in, &session_key, true);
943 memcpy(u.info18.lm_pwd.hash, out.data, out.length);
946 torture_comment(tctx, "Testing SetUserInfo level 18 (set password hash)\n");
948 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
949 if (!NT_STATUS_IS_OK(status)) {
950 printf("SetUserInfo level %u failed - %s\n",
951 s.in.level, nt_errstr(status));
960 static bool test_SetUserPass_21(struct dcerpc_pipe *p, struct torture_context *tctx,
961 struct policy_handle *handle, uint32_t fields_present,
965 struct samr_SetUserInfo s;
966 union samr_UserInfo u;
968 DATA_BLOB session_key;
970 struct samr_GetUserPwInfo pwp;
971 struct samr_PwInfo info;
972 int policy_min_pw_len = 0;
973 uint8_t lm_hash[16], nt_hash[16];
975 pwp.in.user_handle = handle;
976 pwp.out.info = &info;
978 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
979 if (NT_STATUS_IS_OK(status)) {
980 policy_min_pw_len = pwp.out.info->min_password_length;
982 newpass = samr_rand_pass(tctx, policy_min_pw_len);
984 s.in.user_handle = handle;
988 E_md4hash(newpass, nt_hash);
989 E_deshash(newpass, lm_hash);
993 u.info21.fields_present = fields_present;
995 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
996 u.info21.lm_owf_password.length = 16;
997 u.info21.lm_owf_password.size = 16;
998 u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
999 u.info21.lm_password_set = true;
1002 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1003 u.info21.nt_owf_password.length = 16;
1004 u.info21.nt_owf_password.size = 16;
1005 u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
1006 u.info21.nt_password_set = true;
1009 status = dcerpc_fetch_session_key(p, &session_key);
1010 if (!NT_STATUS_IS_OK(status)) {
1011 printf("SetUserInfo level %u - no session key - %s\n",
1012 s.in.level, nt_errstr(status));
1016 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1018 in = data_blob_const(u.info21.lm_owf_password.array,
1019 u.info21.lm_owf_password.length);
1020 out = data_blob_talloc_zero(tctx, 16);
1021 sess_crypt_blob(&out, &in, &session_key, true);
1022 u.info21.lm_owf_password.array = (uint16_t *)out.data;
1025 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1027 in = data_blob_const(u.info21.nt_owf_password.array,
1028 u.info21.nt_owf_password.length);
1029 out = data_blob_talloc_zero(tctx, 16);
1030 sess_crypt_blob(&out, &in, &session_key, true);
1031 u.info21.nt_owf_password.array = (uint16_t *)out.data;
1034 torture_comment(tctx, "Testing SetUserInfo level 21 (set password hash)\n");
1036 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1037 if (!NT_STATUS_IS_OK(status)) {
1038 printf("SetUserInfo level %u failed - %s\n",
1039 s.in.level, nt_errstr(status));
1042 *password = newpass;
1045 /* try invalid length */
1046 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1048 u.info21.nt_owf_password.length++;
1050 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1052 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1053 printf("SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1054 s.in.level, nt_errstr(status));
1059 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1061 u.info21.lm_owf_password.length++;
1063 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1065 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1066 printf("SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1067 s.in.level, nt_errstr(status));
1075 static bool test_SetUserPass_level_ex(struct dcerpc_pipe *p,
1076 struct torture_context *tctx,
1077 struct policy_handle *handle,
1079 uint32_t fields_present,
1080 char **password, uint8_t password_expired,
1082 bool *matched_expected_error)
1085 NTSTATUS expected_error = NT_STATUS_OK;
1086 struct samr_SetUserInfo s;
1087 struct samr_SetUserInfo2 s2;
1088 union samr_UserInfo u;
1090 DATA_BLOB session_key;
1091 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
1092 struct MD5Context ctx;
1093 uint8_t confounder[16];
1095 struct samr_GetUserPwInfo pwp;
1096 struct samr_PwInfo info;
1097 int policy_min_pw_len = 0;
1098 const char *comment = NULL;
1099 uint8_t lm_hash[16], nt_hash[16];
1101 pwp.in.user_handle = handle;
1102 pwp.out.info = &info;
1104 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1105 if (NT_STATUS_IS_OK(status)) {
1106 policy_min_pw_len = pwp.out.info->min_password_length;
1108 newpass = samr_rand_pass_silent(tctx, policy_min_pw_len);
1111 s2.in.user_handle = handle;
1113 s2.in.level = level;
1115 s.in.user_handle = handle;
1120 if (fields_present & SAMR_FIELD_COMMENT) {
1121 comment = talloc_asprintf(tctx, "comment: %ld\n", time(NULL));
1128 E_md4hash(newpass, nt_hash);
1129 E_deshash(newpass, lm_hash);
1131 u.info18.nt_pwd_active = true;
1132 u.info18.lm_pwd_active = true;
1133 u.info18.password_expired = password_expired;
1135 memcpy(u.info18.lm_pwd.hash, lm_hash, 16);
1136 memcpy(u.info18.nt_pwd.hash, nt_hash, 16);
1140 E_md4hash(newpass, nt_hash);
1141 E_deshash(newpass, lm_hash);
1143 u.info21.fields_present = fields_present;
1144 u.info21.password_expired = password_expired;
1145 u.info21.comment.string = comment;
1147 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1148 u.info21.lm_owf_password.length = 16;
1149 u.info21.lm_owf_password.size = 16;
1150 u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
1151 u.info21.lm_password_set = true;
1154 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1155 u.info21.nt_owf_password.length = 16;
1156 u.info21.nt_owf_password.size = 16;
1157 u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
1158 u.info21.nt_password_set = true;
1163 u.info23.info.fields_present = fields_present;
1164 u.info23.info.password_expired = password_expired;
1165 u.info23.info.comment.string = comment;
1167 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
1171 u.info24.password_expired = password_expired;
1173 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
1177 u.info25.info.fields_present = fields_present;
1178 u.info25.info.password_expired = password_expired;
1179 u.info25.info.comment.string = comment;
1181 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
1185 u.info26.password_expired = password_expired;
1187 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
1192 status = dcerpc_fetch_session_key(p, &session_key);
1193 if (!NT_STATUS_IS_OK(status)) {
1194 printf("SetUserInfo level %u - no session key - %s\n",
1195 s.in.level, nt_errstr(status));
1199 generate_random_buffer((uint8_t *)confounder, 16);
1202 MD5Update(&ctx, confounder, 16);
1203 MD5Update(&ctx, session_key.data, session_key.length);
1204 MD5Final(confounded_session_key.data, &ctx);
1210 in = data_blob_const(u.info18.nt_pwd.hash, 16);
1211 out = data_blob_talloc_zero(tctx, 16);
1212 sess_crypt_blob(&out, &in, &session_key, true);
1213 memcpy(u.info18.nt_pwd.hash, out.data, out.length);
1217 in = data_blob_const(u.info18.lm_pwd.hash, 16);
1218 out = data_blob_talloc_zero(tctx, 16);
1219 sess_crypt_blob(&out, &in, &session_key, true);
1220 memcpy(u.info18.lm_pwd.hash, out.data, out.length);
1225 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1227 in = data_blob_const(u.info21.lm_owf_password.array,
1228 u.info21.lm_owf_password.length);
1229 out = data_blob_talloc_zero(tctx, 16);
1230 sess_crypt_blob(&out, &in, &session_key, true);
1231 u.info21.lm_owf_password.array = (uint16_t *)out.data;
1233 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1235 in = data_blob_const(u.info21.nt_owf_password.array,
1236 u.info21.nt_owf_password.length);
1237 out = data_blob_talloc_zero(tctx, 16);
1238 sess_crypt_blob(&out, &in, &session_key, true);
1239 u.info21.nt_owf_password.array = (uint16_t *)out.data;
1243 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
1246 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
1249 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
1250 memcpy(&u.info25.password.data[516], confounder, 16);
1253 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
1254 memcpy(&u.info26.password.data[516], confounder, 16);
1259 status = dcerpc_samr_SetUserInfo2(p, tctx, &s2);
1261 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1264 if (!NT_STATUS_IS_OK(status)) {
1265 if (fields_present == 0) {
1266 expected_error = NT_STATUS_INVALID_PARAMETER;
1268 if (fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
1269 expected_error = NT_STATUS_ACCESS_DENIED;
1273 if (!NT_STATUS_IS_OK(expected_error)) {
1275 torture_assert_ntstatus_equal(tctx,
1277 expected_error, "SetUserInfo2 failed");
1279 torture_assert_ntstatus_equal(tctx,
1281 expected_error, "SetUserInfo failed");
1283 *matched_expected_error = true;
1287 if (!NT_STATUS_IS_OK(status)) {
1288 printf("SetUserInfo%s level %u failed - %s\n",
1289 use_setinfo2 ? "2":"", level, nt_errstr(status));
1292 *password = newpass;
1298 static bool test_SetAliasInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1299 struct policy_handle *handle)
1302 struct samr_SetAliasInfo r;
1303 struct samr_QueryAliasInfo q;
1304 union samr_AliasInfo *info;
1305 uint16_t levels[] = {2, 3};
1309 /* Ignoring switch level 1, as that includes the number of members for the alias
1310 * and setting this to a wrong value might have negative consequences
1313 for (i=0;i<ARRAY_SIZE(levels);i++) {
1314 torture_comment(tctx, "Testing SetAliasInfo level %u\n", levels[i]);
1316 r.in.alias_handle = handle;
1317 r.in.level = levels[i];
1318 r.in.info = talloc(tctx, union samr_AliasInfo);
1319 switch (r.in.level) {
1320 case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
1321 case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
1322 "Test Description, should test I18N as well"); break;
1323 case ALIASINFOALL: printf("ALIASINFOALL ignored\n"); break;
1326 status = dcerpc_samr_SetAliasInfo(p, tctx, &r);
1327 if (!NT_STATUS_IS_OK(status)) {
1328 printf("SetAliasInfo level %u failed - %s\n",
1329 levels[i], nt_errstr(status));
1333 q.in.alias_handle = handle;
1334 q.in.level = levels[i];
1337 status = dcerpc_samr_QueryAliasInfo(p, tctx, &q);
1338 if (!NT_STATUS_IS_OK(status)) {
1339 printf("QueryAliasInfo level %u failed - %s\n",
1340 levels[i], nt_errstr(status));
1348 static bool test_GetGroupsForUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1349 struct policy_handle *user_handle)
1351 struct samr_GetGroupsForUser r;
1352 struct samr_RidWithAttributeArray *rids = NULL;
1355 torture_comment(tctx, "testing GetGroupsForUser\n");
1357 r.in.user_handle = user_handle;
1360 status = dcerpc_samr_GetGroupsForUser(p, tctx, &r);
1361 torture_assert_ntstatus_ok(tctx, status, "GetGroupsForUser");
1367 static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1368 struct lsa_String *domain_name)
1371 struct samr_GetDomPwInfo r;
1372 struct samr_PwInfo info;
1374 r.in.domain_name = domain_name;
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 = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
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 = "\\\\__NONAME__";
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");
1394 r.in.domain_name->string = "\\\\Builtin";
1395 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1397 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1398 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1403 static bool test_GetUserPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1404 struct policy_handle *handle)
1407 struct samr_GetUserPwInfo r;
1408 struct samr_PwInfo info;
1410 torture_comment(tctx, "Testing GetUserPwInfo\n");
1412 r.in.user_handle = handle;
1415 status = dcerpc_samr_GetUserPwInfo(p, tctx, &r);
1416 torture_assert_ntstatus_ok(tctx, status, "GetUserPwInfo");
1421 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, struct torture_context *tctx,
1422 struct policy_handle *domain_handle, const char *name,
1426 struct samr_LookupNames n;
1427 struct lsa_String sname[2];
1428 struct samr_Ids rids, types;
1430 init_lsa_String(&sname[0], name);
1432 n.in.domain_handle = domain_handle;
1436 n.out.types = &types;
1437 status = dcerpc_samr_LookupNames(p, tctx, &n);
1438 if (NT_STATUS_IS_OK(status)) {
1439 *rid = n.out.rids->ids[0];
1444 init_lsa_String(&sname[1], "xxNONAMExx");
1446 status = dcerpc_samr_LookupNames(p, tctx, &n);
1447 if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
1448 printf("LookupNames[2] failed - %s\n", nt_errstr(status));
1449 if (NT_STATUS_IS_OK(status)) {
1450 return NT_STATUS_UNSUCCESSFUL;
1456 status = dcerpc_samr_LookupNames(p, tctx, &n);
1457 if (!NT_STATUS_IS_OK(status)) {
1458 printf("LookupNames[0] failed - %s\n", nt_errstr(status));
1462 init_lsa_String(&sname[0], "xxNONAMExx");
1464 status = dcerpc_samr_LookupNames(p, tctx, &n);
1465 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1466 printf("LookupNames[1 bad name] failed - %s\n", nt_errstr(status));
1467 if (NT_STATUS_IS_OK(status)) {
1468 return NT_STATUS_UNSUCCESSFUL;
1473 init_lsa_String(&sname[0], "xxNONAMExx");
1474 init_lsa_String(&sname[1], "xxNONAME2xx");
1476 status = dcerpc_samr_LookupNames(p, tctx, &n);
1477 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1478 printf("LookupNames[2 bad names] failed - %s\n", nt_errstr(status));
1479 if (NT_STATUS_IS_OK(status)) {
1480 return NT_STATUS_UNSUCCESSFUL;
1485 return NT_STATUS_OK;
1488 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1489 struct policy_handle *domain_handle,
1490 const char *name, struct policy_handle *user_handle)
1493 struct samr_OpenUser r;
1496 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
1497 if (!NT_STATUS_IS_OK(status)) {
1501 r.in.domain_handle = domain_handle;
1502 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1504 r.out.user_handle = user_handle;
1505 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
1506 if (!NT_STATUS_IS_OK(status)) {
1507 printf("OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(status));
1514 static bool test_ChangePasswordNT3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1515 struct policy_handle *handle)
1518 struct samr_ChangePasswordUser r;
1520 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1521 struct policy_handle user_handle;
1522 char *oldpass = "test";
1523 char *newpass = "test2";
1524 uint8_t old_nt_hash[16], new_nt_hash[16];
1525 uint8_t old_lm_hash[16], new_lm_hash[16];
1527 status = test_OpenUser_byname(p, mem_ctx, handle, "testuser", &user_handle);
1528 if (!NT_STATUS_IS_OK(status)) {
1532 printf("Testing ChangePasswordUser for user 'testuser'\n");
1534 printf("old password: %s\n", oldpass);
1535 printf("new password: %s\n", newpass);
1537 E_md4hash(oldpass, old_nt_hash);
1538 E_md4hash(newpass, new_nt_hash);
1539 E_deshash(oldpass, old_lm_hash);
1540 E_deshash(newpass, new_lm_hash);
1542 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1543 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1544 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1545 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1546 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1547 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1549 r.in.handle = &user_handle;
1550 r.in.lm_present = 1;
1551 r.in.old_lm_crypted = &hash1;
1552 r.in.new_lm_crypted = &hash2;
1553 r.in.nt_present = 1;
1554 r.in.old_nt_crypted = &hash3;
1555 r.in.new_nt_crypted = &hash4;
1556 r.in.cross1_present = 1;
1557 r.in.nt_cross = &hash5;
1558 r.in.cross2_present = 1;
1559 r.in.lm_cross = &hash6;
1561 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1562 if (!NT_STATUS_IS_OK(status)) {
1563 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1567 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1575 static bool test_ChangePasswordUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1576 const char *acct_name,
1577 struct policy_handle *handle, char **password)
1580 struct samr_ChangePasswordUser r;
1582 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1583 struct policy_handle user_handle;
1585 uint8_t old_nt_hash[16], new_nt_hash[16];
1586 uint8_t old_lm_hash[16], new_lm_hash[16];
1587 bool changed = true;
1590 struct samr_GetUserPwInfo pwp;
1591 struct samr_PwInfo info;
1592 int policy_min_pw_len = 0;
1594 status = test_OpenUser_byname(p, tctx, handle, acct_name, &user_handle);
1595 if (!NT_STATUS_IS_OK(status)) {
1598 pwp.in.user_handle = &user_handle;
1599 pwp.out.info = &info;
1601 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1602 if (NT_STATUS_IS_OK(status)) {
1603 policy_min_pw_len = pwp.out.info->min_password_length;
1605 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1607 torture_comment(tctx, "Testing ChangePasswordUser\n");
1609 torture_assert(tctx, *password != NULL,
1610 "Failing ChangePasswordUser as old password was NULL. Previous test failed?");
1612 oldpass = *password;
1614 E_md4hash(oldpass, old_nt_hash);
1615 E_md4hash(newpass, new_nt_hash);
1616 E_deshash(oldpass, old_lm_hash);
1617 E_deshash(newpass, new_lm_hash);
1619 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1620 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1621 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1622 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1623 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1624 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1626 r.in.user_handle = &user_handle;
1627 r.in.lm_present = 1;
1628 /* Break the LM hash */
1630 r.in.old_lm_crypted = &hash1;
1631 r.in.new_lm_crypted = &hash2;
1632 r.in.nt_present = 1;
1633 r.in.old_nt_crypted = &hash3;
1634 r.in.new_nt_crypted = &hash4;
1635 r.in.cross1_present = 1;
1636 r.in.nt_cross = &hash5;
1637 r.in.cross2_present = 1;
1638 r.in.lm_cross = &hash6;
1640 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1641 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1642 "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash");
1644 /* Unbreak the LM hash */
1647 r.in.user_handle = &user_handle;
1648 r.in.lm_present = 1;
1649 r.in.old_lm_crypted = &hash1;
1650 r.in.new_lm_crypted = &hash2;
1651 /* Break the NT hash */
1653 r.in.nt_present = 1;
1654 r.in.old_nt_crypted = &hash3;
1655 r.in.new_nt_crypted = &hash4;
1656 r.in.cross1_present = 1;
1657 r.in.nt_cross = &hash5;
1658 r.in.cross2_present = 1;
1659 r.in.lm_cross = &hash6;
1661 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1662 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1663 "expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash");
1665 /* Unbreak the NT hash */
1668 r.in.user_handle = &user_handle;
1669 r.in.lm_present = 1;
1670 r.in.old_lm_crypted = &hash1;
1671 r.in.new_lm_crypted = &hash2;
1672 r.in.nt_present = 1;
1673 r.in.old_nt_crypted = &hash3;
1674 r.in.new_nt_crypted = &hash4;
1675 r.in.cross1_present = 1;
1676 r.in.nt_cross = &hash5;
1677 r.in.cross2_present = 1;
1678 /* Break the LM cross */
1680 r.in.lm_cross = &hash6;
1682 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1683 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1684 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status));
1688 /* Unbreak the LM cross */
1691 r.in.user_handle = &user_handle;
1692 r.in.lm_present = 1;
1693 r.in.old_lm_crypted = &hash1;
1694 r.in.new_lm_crypted = &hash2;
1695 r.in.nt_present = 1;
1696 r.in.old_nt_crypted = &hash3;
1697 r.in.new_nt_crypted = &hash4;
1698 r.in.cross1_present = 1;
1699 /* Break the NT cross */
1701 r.in.nt_cross = &hash5;
1702 r.in.cross2_present = 1;
1703 r.in.lm_cross = &hash6;
1705 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1706 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1707 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status));
1711 /* Unbreak the NT cross */
1715 /* Reset the hashes to not broken values */
1716 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1717 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1718 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1719 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1720 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1721 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1723 r.in.user_handle = &user_handle;
1724 r.in.lm_present = 1;
1725 r.in.old_lm_crypted = &hash1;
1726 r.in.new_lm_crypted = &hash2;
1727 r.in.nt_present = 1;
1728 r.in.old_nt_crypted = &hash3;
1729 r.in.new_nt_crypted = &hash4;
1730 r.in.cross1_present = 1;
1731 r.in.nt_cross = &hash5;
1732 r.in.cross2_present = 0;
1733 r.in.lm_cross = NULL;
1735 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1736 if (NT_STATUS_IS_OK(status)) {
1738 *password = newpass;
1739 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1740 printf("ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(status));
1745 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1747 E_md4hash(oldpass, old_nt_hash);
1748 E_md4hash(newpass, new_nt_hash);
1749 E_deshash(oldpass, old_lm_hash);
1750 E_deshash(newpass, new_lm_hash);
1753 /* Reset the hashes to not broken values */
1754 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1755 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1756 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1757 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1758 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1759 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1761 r.in.user_handle = &user_handle;
1762 r.in.lm_present = 1;
1763 r.in.old_lm_crypted = &hash1;
1764 r.in.new_lm_crypted = &hash2;
1765 r.in.nt_present = 1;
1766 r.in.old_nt_crypted = &hash3;
1767 r.in.new_nt_crypted = &hash4;
1768 r.in.cross1_present = 0;
1769 r.in.nt_cross = NULL;
1770 r.in.cross2_present = 1;
1771 r.in.lm_cross = &hash6;
1773 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1774 if (NT_STATUS_IS_OK(status)) {
1776 *password = newpass;
1777 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1778 printf("ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status));
1783 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1785 E_md4hash(oldpass, old_nt_hash);
1786 E_md4hash(newpass, new_nt_hash);
1787 E_deshash(oldpass, old_lm_hash);
1788 E_deshash(newpass, new_lm_hash);
1791 /* Reset the hashes to not broken values */
1792 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1793 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1794 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1795 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1796 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1797 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1799 r.in.user_handle = &user_handle;
1800 r.in.lm_present = 1;
1801 r.in.old_lm_crypted = &hash1;
1802 r.in.new_lm_crypted = &hash2;
1803 r.in.nt_present = 1;
1804 r.in.old_nt_crypted = &hash3;
1805 r.in.new_nt_crypted = &hash4;
1806 r.in.cross1_present = 1;
1807 r.in.nt_cross = &hash5;
1808 r.in.cross2_present = 1;
1809 r.in.lm_cross = &hash6;
1811 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1812 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1813 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1814 } else if (!NT_STATUS_IS_OK(status)) {
1815 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1819 *password = newpass;
1822 r.in.user_handle = &user_handle;
1823 r.in.lm_present = 1;
1824 r.in.old_lm_crypted = &hash1;
1825 r.in.new_lm_crypted = &hash2;
1826 r.in.nt_present = 1;
1827 r.in.old_nt_crypted = &hash3;
1828 r.in.new_nt_crypted = &hash4;
1829 r.in.cross1_present = 1;
1830 r.in.nt_cross = &hash5;
1831 r.in.cross2_present = 1;
1832 r.in.lm_cross = &hash6;
1835 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1836 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1837 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1838 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1839 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status));
1845 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
1853 static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
1854 const char *acct_name,
1855 struct policy_handle *handle, char **password)
1858 struct samr_OemChangePasswordUser2 r;
1860 struct samr_Password lm_verifier;
1861 struct samr_CryptPassword lm_pass;
1862 struct lsa_AsciiString server, account, account_bad;
1865 uint8_t old_lm_hash[16], new_lm_hash[16];
1867 struct samr_GetDomPwInfo dom_pw_info;
1868 struct samr_PwInfo info;
1869 int policy_min_pw_len = 0;
1871 struct lsa_String domain_name;
1873 domain_name.string = "";
1874 dom_pw_info.in.domain_name = &domain_name;
1875 dom_pw_info.out.info = &info;
1877 torture_comment(tctx, "Testing OemChangePasswordUser2\n");
1879 torture_assert(tctx, *password != NULL,
1880 "Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?");
1882 oldpass = *password;
1884 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
1885 if (NT_STATUS_IS_OK(status)) {
1886 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
1889 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1891 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1892 account.string = acct_name;
1894 E_deshash(oldpass, old_lm_hash);
1895 E_deshash(newpass, new_lm_hash);
1897 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1898 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1899 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1901 r.in.server = &server;
1902 r.in.account = &account;
1903 r.in.password = &lm_pass;
1904 r.in.hash = &lm_verifier;
1906 /* Break the verification */
1907 lm_verifier.hash[0]++;
1909 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1911 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1912 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1913 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1918 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1919 /* Break the old password */
1921 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1922 /* unbreak it for the next operation */
1924 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1926 r.in.server = &server;
1927 r.in.account = &account;
1928 r.in.password = &lm_pass;
1929 r.in.hash = &lm_verifier;
1931 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1933 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1934 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1935 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1940 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1941 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1943 r.in.server = &server;
1944 r.in.account = &account;
1945 r.in.password = &lm_pass;
1948 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1950 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1951 && !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1952 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
1957 /* This shouldn't be a valid name */
1958 account_bad.string = TEST_ACCOUNT_NAME "XX";
1959 r.in.account = &account_bad;
1961 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1963 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1964 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
1969 /* This shouldn't be a valid name */
1970 account_bad.string = TEST_ACCOUNT_NAME "XX";
1971 r.in.account = &account_bad;
1972 r.in.password = &lm_pass;
1973 r.in.hash = &lm_verifier;
1975 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1977 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1978 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1983 /* This shouldn't be a valid name */
1984 account_bad.string = TEST_ACCOUNT_NAME "XX";
1985 r.in.account = &account_bad;
1986 r.in.password = NULL;
1987 r.in.hash = &lm_verifier;
1989 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1991 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1992 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
1997 E_deshash(oldpass, old_lm_hash);
1998 E_deshash(newpass, new_lm_hash);
2000 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
2001 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2002 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
2004 r.in.server = &server;
2005 r.in.account = &account;
2006 r.in.password = &lm_pass;
2007 r.in.hash = &lm_verifier;
2009 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
2010 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2011 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
2012 } else if (!NT_STATUS_IS_OK(status)) {
2013 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
2016 *password = newpass;
2023 static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
2024 const char *acct_name,
2026 char *newpass, bool allow_password_restriction)
2029 struct samr_ChangePasswordUser2 r;
2031 struct lsa_String server, account;
2032 struct samr_CryptPassword nt_pass, lm_pass;
2033 struct samr_Password nt_verifier, lm_verifier;
2035 uint8_t old_nt_hash[16], new_nt_hash[16];
2036 uint8_t old_lm_hash[16], new_lm_hash[16];
2038 struct samr_GetDomPwInfo dom_pw_info;
2039 struct samr_PwInfo info;
2041 struct lsa_String domain_name;
2043 domain_name.string = "";
2044 dom_pw_info.in.domain_name = &domain_name;
2045 dom_pw_info.out.info = &info;
2047 torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name);
2049 torture_assert(tctx, *password != NULL,
2050 "Failing ChangePasswordUser2 as old password was NULL. Previous test failed?");
2051 oldpass = *password;
2054 int policy_min_pw_len = 0;
2055 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
2056 if (NT_STATUS_IS_OK(status)) {
2057 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
2060 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2063 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2064 init_lsa_String(&account, acct_name);
2066 E_md4hash(oldpass, old_nt_hash);
2067 E_md4hash(newpass, new_nt_hash);
2069 E_deshash(oldpass, old_lm_hash);
2070 E_deshash(newpass, new_lm_hash);
2072 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
2073 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2074 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2076 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2077 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2078 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2080 r.in.server = &server;
2081 r.in.account = &account;
2082 r.in.nt_password = &nt_pass;
2083 r.in.nt_verifier = &nt_verifier;
2085 r.in.lm_password = &lm_pass;
2086 r.in.lm_verifier = &lm_verifier;
2088 status = dcerpc_samr_ChangePasswordUser2(p, tctx, &r);
2089 if (allow_password_restriction && NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2090 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
2091 } else if (!NT_STATUS_IS_OK(status)) {
2092 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
2095 *password = newpass;
2102 bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tctx,
2103 const char *account_string,
2104 int policy_min_pw_len,
2106 const char *newpass,
2107 NTTIME last_password_change,
2108 bool handle_reject_reason)
2111 struct samr_ChangePasswordUser3 r;
2113 struct lsa_String server, account, account_bad;
2114 struct samr_CryptPassword nt_pass, lm_pass;
2115 struct samr_Password nt_verifier, lm_verifier;
2117 uint8_t old_nt_hash[16], new_nt_hash[16];
2118 uint8_t old_lm_hash[16], new_lm_hash[16];
2120 struct samr_DomInfo1 *dominfo = NULL;
2121 struct samr_ChangeReject *reject = NULL;
2123 torture_comment(tctx, "Testing ChangePasswordUser3\n");
2125 if (newpass == NULL) {
2127 if (policy_min_pw_len == 0) {
2128 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2130 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len);
2132 } while (check_password_quality(newpass) == false);
2134 torture_comment(tctx, "Using password '%s'\n", newpass);
2137 torture_assert(tctx, *password != NULL,
2138 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2140 oldpass = *password;
2141 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2142 init_lsa_String(&account, account_string);
2144 E_md4hash(oldpass, old_nt_hash);
2145 E_md4hash(newpass, new_nt_hash);
2147 E_deshash(oldpass, old_lm_hash);
2148 E_deshash(newpass, new_lm_hash);
2150 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2151 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2152 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2154 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2155 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2156 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2158 /* Break the verification */
2159 nt_verifier.hash[0]++;
2161 r.in.server = &server;
2162 r.in.account = &account;
2163 r.in.nt_password = &nt_pass;
2164 r.in.nt_verifier = &nt_verifier;
2166 r.in.lm_password = &lm_pass;
2167 r.in.lm_verifier = &lm_verifier;
2168 r.in.password3 = NULL;
2169 r.out.dominfo = &dominfo;
2170 r.out.reject = &reject;
2172 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2173 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
2174 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
2175 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
2180 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2181 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2182 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2184 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2185 /* Break the NT hash */
2187 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2188 /* Unbreak it again */
2190 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2192 r.in.server = &server;
2193 r.in.account = &account;
2194 r.in.nt_password = &nt_pass;
2195 r.in.nt_verifier = &nt_verifier;
2197 r.in.lm_password = &lm_pass;
2198 r.in.lm_verifier = &lm_verifier;
2199 r.in.password3 = NULL;
2200 r.out.dominfo = &dominfo;
2201 r.out.reject = &reject;
2203 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2204 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
2205 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
2206 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
2211 /* This shouldn't be a valid name */
2212 init_lsa_String(&account_bad, talloc_asprintf(tctx, "%sXX", account_string));
2214 r.in.account = &account_bad;
2215 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2216 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
2217 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
2222 E_md4hash(oldpass, old_nt_hash);
2223 E_md4hash(newpass, new_nt_hash);
2225 E_deshash(oldpass, old_lm_hash);
2226 E_deshash(newpass, new_lm_hash);
2228 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2229 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2230 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2232 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2233 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2234 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2236 r.in.server = &server;
2237 r.in.account = &account;
2238 r.in.nt_password = &nt_pass;
2239 r.in.nt_verifier = &nt_verifier;
2241 r.in.lm_password = &lm_pass;
2242 r.in.lm_verifier = &lm_verifier;
2243 r.in.password3 = NULL;
2244 r.out.dominfo = &dominfo;
2245 r.out.reject = &reject;
2247 unix_to_nt_time(&t, time(NULL));
2249 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2251 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
2254 && handle_reject_reason
2255 && (!null_nttime(last_password_change) || !dominfo->min_password_age)) {
2256 if (dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
2258 if (reject && (reject->reason != SAMR_REJECT_OTHER)) {
2259 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2260 SAMR_REJECT_OTHER, reject->reason);
2265 /* We tested the order of precendence which is as follows:
2274 if ((dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
2275 (last_password_change + dominfo->min_password_age > t)) {
2277 if (reject->reason != SAMR_REJECT_OTHER) {
2278 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2279 SAMR_REJECT_OTHER, reject->reason);
2283 } else if ((dominfo->min_password_length > 0) &&
2284 (strlen(newpass) < dominfo->min_password_length)) {
2286 if (reject->reason != SAMR_REJECT_TOO_SHORT) {
2287 printf("expected SAMR_REJECT_TOO_SHORT (%d), got %d\n",
2288 SAMR_REJECT_TOO_SHORT, reject->reason);
2292 } else if ((dominfo->password_history_length > 0) &&
2293 strequal(oldpass, newpass)) {
2295 if (reject->reason != SAMR_REJECT_IN_HISTORY) {
2296 printf("expected SAMR_REJECT_IN_HISTORY (%d), got %d\n",
2297 SAMR_REJECT_IN_HISTORY, reject->reason);
2300 } else if (dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
2302 if (reject->reason != SAMR_REJECT_COMPLEXITY) {
2303 printf("expected SAMR_REJECT_COMPLEXITY (%d), got %d\n",
2304 SAMR_REJECT_COMPLEXITY, reject->reason);
2310 if (reject->reason == SAMR_REJECT_TOO_SHORT) {
2311 /* retry with adjusted size */
2312 return test_ChangePasswordUser3(p, tctx, account_string,
2313 dominfo->min_password_length,
2314 password, NULL, 0, false);
2318 } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2319 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2320 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2321 SAMR_REJECT_OTHER, reject->reason);
2324 /* Perhaps the server has a 'min password age' set? */
2327 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3");
2328 *password = talloc_strdup(tctx, newpass);
2334 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_context *tctx,
2335 const char *account_string,
2336 struct policy_handle *handle,
2340 struct samr_ChangePasswordUser3 r;
2341 struct samr_SetUserInfo s;
2342 union samr_UserInfo u;
2343 DATA_BLOB session_key;
2344 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
2345 uint8_t confounder[16];
2346 struct MD5Context ctx;
2349 struct lsa_String server, account;
2350 struct samr_CryptPassword nt_pass;
2351 struct samr_Password nt_verifier;
2352 DATA_BLOB new_random_pass;
2355 uint8_t old_nt_hash[16], new_nt_hash[16];
2357 struct samr_DomInfo1 *dominfo = NULL;
2358 struct samr_ChangeReject *reject = NULL;
2360 new_random_pass = samr_very_rand_pass(tctx, 128);
2362 torture_assert(tctx, *password != NULL,
2363 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2365 oldpass = *password;
2366 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2367 init_lsa_String(&account, account_string);
2369 s.in.user_handle = handle;
2375 u.info25.info.fields_present = SAMR_FIELD_NT_PASSWORD_PRESENT;
2377 set_pw_in_buffer(u.info25.password.data, &new_random_pass);
2379 status = dcerpc_fetch_session_key(p, &session_key);
2380 if (!NT_STATUS_IS_OK(status)) {
2381 printf("SetUserInfo level %u - no session key - %s\n",
2382 s.in.level, nt_errstr(status));
2386 generate_random_buffer((uint8_t *)confounder, 16);
2389 MD5Update(&ctx, confounder, 16);
2390 MD5Update(&ctx, session_key.data, session_key.length);
2391 MD5Final(confounded_session_key.data, &ctx);
2393 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
2394 memcpy(&u.info25.password.data[516], confounder, 16);
2396 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
2398 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
2399 if (!NT_STATUS_IS_OK(status)) {
2400 printf("SetUserInfo level %u failed - %s\n",
2401 s.in.level, nt_errstr(status));
2405 torture_comment(tctx, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
2407 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2409 new_random_pass = samr_very_rand_pass(tctx, 128);
2411 mdfour(new_nt_hash, new_random_pass.data, new_random_pass.length);
2413 set_pw_in_buffer(nt_pass.data, &new_random_pass);
2414 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2415 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2417 r.in.server = &server;
2418 r.in.account = &account;
2419 r.in.nt_password = &nt_pass;
2420 r.in.nt_verifier = &nt_verifier;
2422 r.in.lm_password = NULL;
2423 r.in.lm_verifier = NULL;
2424 r.in.password3 = NULL;
2425 r.out.dominfo = &dominfo;
2426 r.out.reject = &reject;
2428 unix_to_nt_time(&t, time(NULL));
2430 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2432 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2433 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2434 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2435 SAMR_REJECT_OTHER, reject->reason);
2438 /* Perhaps the server has a 'min password age' set? */
2440 } else if (!NT_STATUS_IS_OK(status)) {
2441 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
2445 newpass = samr_rand_pass(tctx, 128);
2447 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2449 E_md4hash(newpass, new_nt_hash);
2451 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2452 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2453 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2455 r.in.server = &server;
2456 r.in.account = &account;
2457 r.in.nt_password = &nt_pass;
2458 r.in.nt_verifier = &nt_verifier;
2460 r.in.lm_password = NULL;
2461 r.in.lm_verifier = NULL;
2462 r.in.password3 = NULL;
2463 r.out.dominfo = &dominfo;
2464 r.out.reject = &reject;
2466 unix_to_nt_time(&t, time(NULL));
2468 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2470 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2471 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2472 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2473 SAMR_REJECT_OTHER, reject->reason);
2476 /* Perhaps the server has a 'min password age' set? */
2479 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3 (on second random password)");
2480 *password = talloc_strdup(tctx, newpass);
2487 static bool test_GetMembersInAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2488 struct policy_handle *alias_handle)
2490 struct samr_GetMembersInAlias r;
2491 struct lsa_SidArray sids;
2494 torture_comment(tctx, "Testing GetMembersInAlias\n");
2496 r.in.alias_handle = alias_handle;
2499 status = dcerpc_samr_GetMembersInAlias(p, tctx, &r);
2500 torture_assert_ntstatus_ok(tctx, status, "GetMembersInAlias");
2505 static bool test_AddMemberToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2506 struct policy_handle *alias_handle,
2507 const struct dom_sid *domain_sid)
2509 struct samr_AddAliasMember r;
2510 struct samr_DeleteAliasMember d;
2512 struct dom_sid *sid;
2514 sid = dom_sid_add_rid(tctx, domain_sid, 512);
2516 torture_comment(tctx, "testing AddAliasMember\n");
2517 r.in.alias_handle = alias_handle;
2520 status = dcerpc_samr_AddAliasMember(p, tctx, &r);
2521 torture_assert_ntstatus_ok(tctx, status, "AddAliasMember");
2523 d.in.alias_handle = alias_handle;
2526 status = dcerpc_samr_DeleteAliasMember(p, tctx, &d);
2527 torture_assert_ntstatus_ok(tctx, status, "DelAliasMember");
2532 static bool test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2533 struct policy_handle *alias_handle)
2535 struct samr_AddMultipleMembersToAlias a;
2536 struct samr_RemoveMultipleMembersFromAlias r;
2538 struct lsa_SidArray sids;
2540 torture_comment(tctx, "testing AddMultipleMembersToAlias\n");
2541 a.in.alias_handle = alias_handle;
2545 sids.sids = talloc_array(tctx, struct lsa_SidPtr, 3);
2547 sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2548 sids.sids[1].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-2");
2549 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-3");
2551 status = dcerpc_samr_AddMultipleMembersToAlias(p, tctx, &a);
2552 torture_assert_ntstatus_ok(tctx, status, "AddMultipleMembersToAlias");
2555 torture_comment(tctx, "testing RemoveMultipleMembersFromAlias\n");
2556 r.in.alias_handle = alias_handle;
2559 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2560 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2562 /* strange! removing twice doesn't give any error */
2563 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2564 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2566 /* but removing an alias that isn't there does */
2567 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-4");
2569 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2570 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, "RemoveMultipleMembersFromAlias");
2575 static bool test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2576 struct policy_handle *user_handle)
2578 struct samr_TestPrivateFunctionsUser r;
2581 torture_comment(tctx, "Testing TestPrivateFunctionsUser\n");
2583 r.in.user_handle = user_handle;
2585 status = dcerpc_samr_TestPrivateFunctionsUser(p, tctx, &r);
2586 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsUser");
2591 static bool test_QueryUserInfo_pwdlastset(struct dcerpc_pipe *p,
2592 struct torture_context *tctx,
2593 struct policy_handle *handle,
2598 uint16_t levels[] = { /* 3, */ 5, 21 };
2600 NTTIME pwdlastset3 = 0;
2601 NTTIME pwdlastset5 = 0;
2602 NTTIME pwdlastset21 = 0;
2604 torture_comment(tctx, "Testing QueryUserInfo%s level 5 and 21 call ",
2605 use_info2 ? "2":"");
2607 for (i=0; i<ARRAY_SIZE(levels); i++) {
2609 struct samr_QueryUserInfo r;
2610 struct samr_QueryUserInfo2 r2;
2611 union samr_UserInfo *info;
2614 r2.in.user_handle = handle;
2615 r2.in.level = levels[i];
2616 r2.out.info = &info;
2617 status = dcerpc_samr_QueryUserInfo2(p, tctx, &r2);
2620 r.in.user_handle = handle;
2621 r.in.level = levels[i];
2623 status = dcerpc_samr_QueryUserInfo(p, tctx, &r);
2626 if (!NT_STATUS_IS_OK(status) &&
2627 !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
2628 printf("QueryUserInfo%s level %u failed - %s\n",
2629 use_info2 ? "2":"", levels[i], nt_errstr(status));
2633 switch (levels[i]) {
2635 pwdlastset3 = info->info3.last_password_change;
2638 pwdlastset5 = info->info5.last_password_change;
2641 pwdlastset21 = info->info21.last_password_change;
2647 /* torture_assert_int_equal(tctx, pwdlastset3, pwdlastset5,
2648 "pwdlastset mixup"); */
2649 torture_assert_int_equal(tctx, pwdlastset5, pwdlastset21,
2650 "pwdlastset mixup");
2652 *pwdlastset = pwdlastset21;
2654 torture_comment(tctx, "(pwdlastset: %lld)\n", *pwdlastset);
2659 static bool test_SamLogon_Creds(struct dcerpc_pipe *p, struct torture_context *tctx,
2660 struct cli_credentials *machine_credentials,
2661 struct cli_credentials *test_credentials,
2662 struct netlogon_creds_CredentialState *creds,
2663 NTSTATUS expected_result)
2666 struct netr_LogonSamLogon r;
2667 struct netr_Authenticator auth, auth2;
2668 union netr_LogonLevel logon;
2669 union netr_Validation validation;
2670 uint8_t authoritative;
2671 struct netr_NetworkInfo ninfo;
2672 DATA_BLOB names_blob, chal, lm_resp, nt_resp;
2673 int flags = CLI_CRED_NTLM_AUTH;
2675 if (lp_client_lanman_auth(tctx->lp_ctx)) {
2676 flags |= CLI_CRED_LANMAN_AUTH;
2679 if (lp_client_ntlmv2_auth(tctx->lp_ctx)) {
2680 flags |= CLI_CRED_NTLMv2_AUTH;
2683 cli_credentials_get_ntlm_username_domain(test_credentials, tctx,
2684 &ninfo.identity_info.account_name.string,
2685 &ninfo.identity_info.domain_name.string);
2687 generate_random_buffer(ninfo.challenge,
2688 sizeof(ninfo.challenge));
2689 chal = data_blob_const(ninfo.challenge,
2690 sizeof(ninfo.challenge));
2692 names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(machine_credentials),
2693 cli_credentials_get_domain(machine_credentials));
2695 status = cli_credentials_get_ntlm_response(test_credentials, tctx,
2701 torture_assert_ntstatus_ok(tctx, status, "cli_credentials_get_ntlm_response failed");
2703 ninfo.lm.data = lm_resp.data;
2704 ninfo.lm.length = lm_resp.length;
2706 ninfo.nt.data = nt_resp.data;
2707 ninfo.nt.length = nt_resp.length;
2709 ninfo.identity_info.parameter_control =
2710 MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT |
2711 MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;
2712 ninfo.identity_info.logon_id_low = 0;
2713 ninfo.identity_info.logon_id_high = 0;
2714 ninfo.identity_info.workstation.string = cli_credentials_get_workstation(machine_credentials);
2716 logon.network = &ninfo;
2718 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2719 r.in.computer_name = cli_credentials_get_workstation(machine_credentials);
2720 r.in.credential = &auth;
2721 r.in.return_authenticator = &auth2;
2722 r.in.logon_level = 2;
2723 r.in.logon = &logon;
2724 r.out.validation = &validation;
2725 r.out.authoritative = &authoritative;
2727 d_printf("Testing LogonSamLogon with name %s\n", ninfo.identity_info.account_name.string);
2730 netlogon_creds_client_authenticator(creds, &auth);
2732 r.in.validation_level = 2;
2734 status = dcerpc_netr_LogonSamLogon(p, tctx, &r);
2735 if (!NT_STATUS_IS_OK(status)) {
2736 torture_assert_ntstatus_equal(tctx, status, expected_result, "LogonSamLogon failed");
2739 torture_assert_ntstatus_ok(tctx, status, "LogonSamLogon failed");
2742 torture_assert(tctx, netlogon_creds_client_check(creds, &r.out.return_authenticator->cred),
2743 "Credential chaining failed");
2748 static bool test_SamLogon(struct torture_context *tctx,
2749 struct dcerpc_pipe *p,
2750 struct cli_credentials *machine_credentials,
2751 struct cli_credentials *test_credentials,
2752 NTSTATUS expected_result)
2754 struct netlogon_creds_CredentialState *creds;
2756 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
2760 return test_SamLogon_Creds(p, tctx, machine_credentials, test_credentials,
2761 creds, expected_result);
2764 static bool test_SamLogon_with_creds(struct torture_context *tctx,
2765 struct dcerpc_pipe *p,
2766 struct cli_credentials *machine_creds,
2767 const char *acct_name,
2769 NTSTATUS expected_samlogon_result)
2772 struct cli_credentials *test_credentials;
2774 test_credentials = cli_credentials_init(tctx);
2776 cli_credentials_set_workstation(test_credentials,
2777 TEST_ACCOUNT_NAME_PWD, CRED_SPECIFIED);
2778 cli_credentials_set_domain(test_credentials,
2779 lp_workgroup(tctx->lp_ctx), CRED_SPECIFIED);
2780 cli_credentials_set_username(test_credentials,
2781 acct_name, CRED_SPECIFIED);
2782 cli_credentials_set_password(test_credentials,
2783 password, CRED_SPECIFIED);
2784 cli_credentials_set_secure_channel_type(test_credentials, SEC_CHAN_BDC);
2786 printf("testing samlogon as %s@%s password: %s\n",
2787 acct_name, TEST_ACCOUNT_NAME_PWD, password);
2789 if (!test_SamLogon(tctx, p, machine_creds, test_credentials,
2790 expected_samlogon_result)) {
2791 torture_warning(tctx, "new password did not work\n");
2798 static bool test_SetPassword_level(struct dcerpc_pipe *p,
2799 struct dcerpc_pipe *np,
2800 struct torture_context *tctx,
2801 struct policy_handle *handle,
2803 uint32_t fields_present,
2804 uint8_t password_expired,
2805 bool *matched_expected_error,
2807 const char *acct_name,
2809 struct cli_credentials *machine_creds,
2810 bool use_queryinfo2,
2812 NTSTATUS expected_samlogon_result)
2814 const char *fields = NULL;
2821 fields = talloc_asprintf(tctx, "(fields_present: 0x%08x)",
2828 torture_comment(tctx, "Testing SetUserInfo%s level %d call "
2829 "(password_expired: %d) %s\n",
2830 use_setinfo2 ? "2":"", level, password_expired,
2831 fields ? fields : "");
2833 if (!test_SetUserPass_level_ex(p, tctx, handle, level,
2838 matched_expected_error)) {
2842 if (!test_QueryUserInfo_pwdlastset(p, tctx, handle,
2848 if (*matched_expected_error == true) {
2852 if (!test_SamLogon_with_creds(tctx, np,
2856 expected_samlogon_result)) {
2863 static bool test_SetPassword_pwdlastset(struct dcerpc_pipe *p,
2864 struct torture_context *tctx,
2865 uint32_t acct_flags,
2866 const char *acct_name,
2867 struct policy_handle *handle,
2869 struct cli_credentials *machine_credentials)
2871 int s = 0, q = 0, f = 0, l = 0, z = 0;
2874 bool set_levels[] = { false, true };
2875 bool query_levels[] = { false, true };
2876 uint32_t levels[] = { 18, 21, 23, 24, 25, 26 };
2877 uint32_t nonzeros[] = { 1, 24 };
2878 uint32_t fields_present[] = {
2880 SAMR_FIELD_EXPIRED_FLAG,
2881 SAMR_FIELD_LAST_PWD_CHANGE,
2882 SAMR_FIELD_EXPIRED_FLAG | SAMR_FIELD_LAST_PWD_CHANGE,
2884 SAMR_FIELD_NT_PASSWORD_PRESENT,
2885 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
2886 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
2887 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
2888 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
2889 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
2890 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE | SAMR_FIELD_EXPIRED_FLAG
2893 struct dcerpc_pipe *np = NULL;
2895 if (torture_setting_bool(tctx, "samba3", false)) {
2897 printf("Samba3 has second granularity, setting delay to: %d\n",
2901 status = torture_rpc_connection(tctx, &np, &ndr_table_netlogon);
2902 if (!NT_STATUS_IS_OK(status)) {
2906 /* set to 1 to enable testing for all possible opcode
2907 (SetUserInfo, SetUserInfo2, QueryUserInfo, QueryUserInfo2)
2910 #define TEST_SET_LEVELS 1
2911 #define TEST_QUERY_LEVELS 1
2913 for (l=0; l<ARRAY_SIZE(levels); l++) {
2914 for (z=0; z<ARRAY_SIZE(nonzeros); z++) {
2915 for (f=0; f<ARRAY_SIZE(fields_present); f++) {
2916 #ifdef TEST_SET_LEVELS
2917 for (s=0; s<ARRAY_SIZE(set_levels); s++) {
2919 #ifdef TEST_QUERY_LEVELS
2920 for (q=0; q<ARRAY_SIZE(query_levels); q++) {
2922 NTTIME pwdlastset_old = 0;
2923 NTTIME pwdlastset_new = 0;
2924 bool matched_expected_error = false;
2925 NTSTATUS expected_samlogon_result = NT_STATUS_ACCOUNT_DISABLED;
2927 torture_comment(tctx, "------------------------------\n"
2928 "Testing pwdLastSet attribute for flags: 0x%08x "
2929 "(s: %d (l: %d), q: %d)\n",
2930 acct_flags, s, levels[l], q);
2932 switch (levels[l]) {
2936 if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
2937 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT))) {
2938 expected_samlogon_result = NT_STATUS_WRONG_PASSWORD;
2946 /* set a password and force password change (pwdlastset 0) by
2947 * setting the password expired flag to a non-0 value */
2949 if (!test_SetPassword_level(p, np, tctx, handle,
2953 &matched_expected_error,
2957 machine_credentials,
2960 expected_samlogon_result)) {
2964 if (matched_expected_error == true) {
2965 /* skipping on expected failure */
2969 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
2970 * set without the SAMR_FIELD_EXPIRED_FLAG */
2972 switch (levels[l]) {
2976 if ((pwdlastset_new != 0) &&
2977 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
2978 torture_comment(tctx, "not considering a non-0 "
2979 "pwdLastSet as a an error as the "
2980 "SAMR_FIELD_EXPIRED_FLAG has not "
2985 if (pwdlastset_new != 0) {
2986 torture_warning(tctx, "pwdLastSet test failed: "
2987 "expected pwdLastSet 0 but got %lld\n",
2994 switch (levels[l]) {
2998 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
2999 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3000 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3001 (pwdlastset_old >= pwdlastset_new)) {
3002 torture_warning(tctx, "pwdlastset not increasing\n");
3007 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3008 (pwdlastset_old >= pwdlastset_new)) {
3009 torture_warning(tctx, "pwdlastset not increasing\n");
3019 /* set a password, pwdlastset needs to get updated (increased
3020 * value), password_expired value used here is 0 */
3022 if (!test_SetPassword_level(p, np, tctx, handle,
3026 &matched_expected_error,
3030 machine_credentials,
3033 expected_samlogon_result)) {
3037 /* when a password has been changed, pwdlastset must not be 0 afterwards
3038 * and must be larger then the old value */
3040 switch (levels[l]) {
3045 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3046 * password has been changed, old and new pwdlastset
3047 * need to be the same value */
3049 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3050 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3051 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3053 torture_assert_int_equal(tctx, pwdlastset_old,
3054 pwdlastset_new, "pwdlastset must be equal");
3058 if (pwdlastset_old >= pwdlastset_new) {
3059 torture_warning(tctx, "pwdLastSet test failed: "
3060 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
3061 pwdlastset_old, pwdlastset_new);
3064 if (pwdlastset_new == 0) {
3065 torture_warning(tctx, "pwdLastSet test failed: "
3066 "expected non-0 pwdlastset, got: %lld\n",
3072 switch (levels[l]) {
3076 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3077 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3078 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3079 (pwdlastset_old >= pwdlastset_new)) {
3080 torture_warning(tctx, "pwdlastset not increasing\n");
3085 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3086 (pwdlastset_old >= pwdlastset_new)) {
3087 torture_warning(tctx, "pwdlastset not increasing\n");
3093 pwdlastset_old = pwdlastset_new;
3099 /* set a password, pwdlastset needs to get updated (increased
3100 * value), password_expired value used here is 0 */
3102 if (!test_SetPassword_level(p, np, tctx, handle,
3106 &matched_expected_error,
3110 machine_credentials,
3113 expected_samlogon_result)) {
3117 /* when a password has been changed, pwdlastset must not be 0 afterwards
3118 * and must be larger then the old value */
3120 switch (levels[l]) {
3125 /* if no password has been changed, old and new pwdlastset
3126 * need to be the same value */
3128 if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3129 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3131 torture_assert_int_equal(tctx, pwdlastset_old,
3132 pwdlastset_new, "pwdlastset must be equal");
3136 if (pwdlastset_old >= pwdlastset_new) {
3137 torture_warning(tctx, "pwdLastSet test failed: "
3138 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
3139 pwdlastset_old, pwdlastset_new);
3142 if (pwdlastset_new == 0) {
3143 torture_warning(tctx, "pwdLastSet test failed: "
3144 "expected non-0 pwdlastset, got: %lld\n",
3152 /* set a password and force password change (pwdlastset 0) by
3153 * setting the password expired flag to a non-0 value */
3155 if (!test_SetPassword_level(p, np, tctx, handle,
3159 &matched_expected_error,
3163 machine_credentials,
3166 expected_samlogon_result)) {
3170 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3171 * set without the SAMR_FIELD_EXPIRED_FLAG */
3173 switch (levels[l]) {
3177 if ((pwdlastset_new != 0) &&
3178 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
3179 torture_comment(tctx, "not considering a non-0 "
3180 "pwdLastSet as a an error as the "
3181 "SAMR_FIELD_EXPIRED_FLAG has not "
3186 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3187 * password has been changed, old and new pwdlastset
3188 * need to be the same value */
3190 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3191 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3192 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3194 torture_assert_int_equal(tctx, pwdlastset_old,
3195 pwdlastset_new, "pwdlastset must be equal");
3200 if (pwdlastset_old == pwdlastset_new) {
3201 torture_warning(tctx, "pwdLastSet test failed: "
3202 "expected last pwdlastset (%lld) != new pwdlastset (%lld)\n",
3203 pwdlastset_old, pwdlastset_new);
3207 if (pwdlastset_new != 0) {
3208 torture_warning(tctx, "pwdLastSet test failed: "
3209 "expected pwdLastSet 0, got %lld\n",
3216 switch (levels[l]) {
3220 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3221 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3222 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3223 (pwdlastset_old >= pwdlastset_new)) {
3224 torture_warning(tctx, "pwdlastset not increasing\n");
3229 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3230 (pwdlastset_old >= pwdlastset_new)) {
3231 torture_warning(tctx, "pwdlastset not increasing\n");
3237 /* if the level we are testing does not have a fields_present
3238 * field, skip all fields present tests by setting f to to
3240 switch (levels[l]) {
3244 f = ARRAY_SIZE(fields_present);
3248 #ifdef TEST_QUERY_LEVELS
3251 #ifdef TEST_SET_LEVELS
3254 } /* fields present */
3258 #undef TEST_SET_LEVELS
3259 #undef TEST_QUERY_LEVELS
3264 static bool test_user_ops(struct dcerpc_pipe *p,
3265 struct torture_context *tctx,
3266 struct policy_handle *user_handle,
3267 struct policy_handle *domain_handle,
3268 uint32_t base_acct_flags,
3269 const char *base_acct_name, enum torture_samr_choice which_ops,
3270 struct cli_credentials *machine_credentials)
3272 char *password = NULL;
3273 struct samr_QueryUserInfo q;
3274 union samr_UserInfo *info;
3280 const uint32_t password_fields[] = {
3281 SAMR_FIELD_NT_PASSWORD_PRESENT,
3282 SAMR_FIELD_LM_PASSWORD_PRESENT,
3283 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
3287 status = test_LookupName(p, tctx, domain_handle, base_acct_name, &rid);
3288 if (!NT_STATUS_IS_OK(status)) {
3292 switch (which_ops) {
3293 case TORTURE_SAMR_USER_ATTRIBUTES:
3294 if (!test_QuerySecurity(p, tctx, user_handle)) {
3298 if (!test_QueryUserInfo(p, tctx, user_handle)) {
3302 if (!test_QueryUserInfo2(p, tctx, user_handle)) {
3306 if (!test_SetUserInfo(p, tctx, user_handle, base_acct_flags,
3311 if (!test_GetUserPwInfo(p, tctx, user_handle)) {
3315 if (!test_TestPrivateFunctionsUser(p, tctx, user_handle)) {
3319 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
3323 case TORTURE_SAMR_PASSWORDS:
3324 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
3325 char simple_pass[9];
3326 char *v = generate_random_str(tctx, 1);
3328 ZERO_STRUCT(simple_pass);
3329 memset(simple_pass, *v, sizeof(simple_pass) - 1);
3331 printf("Testing machine account password policy rules\n");
3333 /* Workstation trust accounts don't seem to need to honour password quality policy */
3334 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
3338 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
3342 /* reset again, to allow another 'user' password change */
3343 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
3347 /* Try a 'short' password */
3348 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
3352 /* Try a compleatly random password */
3353 if (!test_ChangePasswordRandomBytes(p, tctx, base_acct_name, user_handle, &password)) {
3358 for (i = 0; password_fields[i]; i++) {
3359 if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
3363 /* check it was set right */
3364 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3369 for (i = 0; password_fields[i]; i++) {
3370 if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
3374 /* check it was set right */
3375 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3380 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
3384 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
3388 if (torture_setting_bool(tctx, "samba4", false)) {
3389 printf("skipping Set Password level 18 and 21 against Samba4\n");
3392 if (!test_SetUserPass_18(p, tctx, user_handle, &password)) {
3396 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3400 for (i = 0; password_fields[i]; i++) {
3402 if (password_fields[i] == SAMR_FIELD_LM_PASSWORD_PRESENT) {
3403 /* we need to skip as that would break
3404 * the ChangePasswordUser3 verify */
3408 if (!test_SetUserPass_21(p, tctx, user_handle, password_fields[i], &password)) {
3412 /* check it was set right */
3413 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3419 q.in.user_handle = user_handle;
3423 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
3424 if (!NT_STATUS_IS_OK(status)) {
3425 printf("QueryUserInfo level %u failed - %s\n",
3426 q.in.level, nt_errstr(status));
3429 uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
3430 if ((info->info5.acct_flags) != expected_flags) {
3431 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
3432 info->info5.acct_flags,
3435 if (!torture_setting_bool(tctx, "samba3", false)) {
3439 if (info->info5.rid != rid) {
3440 printf("QuerUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
3441 info->info5.rid, rid);
3448 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
3450 /* test last password change timestamp behaviour */
3451 if (!test_SetPassword_pwdlastset(p, tctx, base_acct_flags,
3453 user_handle, &password,
3454 machine_credentials)) {
3459 torture_comment(tctx, "pwdLastSet test succeeded\n");
3461 torture_warning(tctx, "pwdLastSet test failed\n");
3466 case TORTURE_SAMR_OTHER:
3467 /* We just need the account to exist */
3473 static bool test_alias_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
3474 struct policy_handle *alias_handle,
3475 const struct dom_sid *domain_sid)
3479 if (!test_QuerySecurity(p, tctx, alias_handle)) {
3483 if (!test_QueryAliasInfo(p, tctx, alias_handle)) {
3487 if (!test_SetAliasInfo(p, tctx, alias_handle)) {
3491 if (!test_AddMemberToAlias(p, tctx, alias_handle, domain_sid)) {
3495 if (torture_setting_bool(tctx, "samba4", false)) {
3496 printf("skipping MultipleMembers Alias tests against Samba4\n");
3500 if (!test_AddMultipleMembersToAlias(p, tctx, alias_handle)) {
3508 static bool test_DeleteUser(struct dcerpc_pipe *p, struct torture_context *tctx,
3509 struct policy_handle *user_handle)
3511 struct samr_DeleteUser d;
3513 torture_comment(tctx, "Testing DeleteUser\n");
3515 d.in.user_handle = user_handle;
3516 d.out.user_handle = user_handle;
3518 status = dcerpc_samr_DeleteUser(p, tctx, &d);
3519 torture_assert_ntstatus_ok(tctx, status, "DeleteUser");
3524 bool test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3525 struct policy_handle *handle, const char *name)
3528 struct samr_DeleteUser d;
3529 struct policy_handle user_handle;
3532 status = test_LookupName(p, mem_ctx, handle, name, &rid);
3533 if (!NT_STATUS_IS_OK(status)) {
3537 status = test_OpenUser_byname(p, mem_ctx, handle, name, &user_handle);
3538 if (!NT_STATUS_IS_OK(status)) {
3542 d.in.user_handle = &user_handle;
3543 d.out.user_handle = &user_handle;
3544 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
3545 if (!NT_STATUS_IS_OK(status)) {
3552 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
3557 static bool test_DeleteGroup_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3558 struct policy_handle *handle, const char *name)
3561 struct samr_OpenGroup r;
3562 struct samr_DeleteDomainGroup d;
3563 struct policy_handle group_handle;
3566 status = test_LookupName(p, mem_ctx, handle, name, &rid);
3567 if (!NT_STATUS_IS_OK(status)) {
3571 r.in.domain_handle = handle;
3572 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3574 r.out.group_handle = &group_handle;
3575 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
3576 if (!NT_STATUS_IS_OK(status)) {
3580 d.in.group_handle = &group_handle;
3581 d.out.group_handle = &group_handle;
3582 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
3583 if (!NT_STATUS_IS_OK(status)) {
3590 printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
3595 static bool test_DeleteAlias_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3596 struct policy_handle *domain_handle, const char *name)
3599 struct samr_OpenAlias r;
3600 struct samr_DeleteDomAlias d;
3601 struct policy_handle alias_handle;
3604 printf("testing DeleteAlias_byname\n");
3606 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
3607 if (!NT_STATUS_IS_OK(status)) {
3611 r.in.domain_handle = domain_handle;
3612 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3614 r.out.alias_handle = &alias_handle;
3615 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
3616 if (!NT_STATUS_IS_OK(status)) {
3620 d.in.alias_handle = &alias_handle;
3621 d.out.alias_handle = &alias_handle;
3622 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
3623 if (!NT_STATUS_IS_OK(status)) {
3630 printf("DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
3634 static bool test_DeleteAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3635 struct policy_handle *alias_handle)
3637 struct samr_DeleteDomAlias d;
3640 printf("Testing DeleteAlias\n");
3642 d.in.alias_handle = alias_handle;
3643 d.out.alias_handle = alias_handle;
3645 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
3646 if (!NT_STATUS_IS_OK(status)) {
3647 printf("DeleteAlias failed - %s\n", nt_errstr(status));
3654 static bool test_CreateAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
3655 struct policy_handle *domain_handle,
3656 struct policy_handle *alias_handle,
3657 const struct dom_sid *domain_sid)
3660 struct samr_CreateDomAlias r;
3661 struct lsa_String name;
3665 init_lsa_String(&name, TEST_ALIASNAME);
3666 r.in.domain_handle = domain_handle;
3667 r.in.alias_name = &name;
3668 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3669 r.out.alias_handle = alias_handle;
3672 printf("Testing CreateAlias (%s)\n", r.in.alias_name->string);
3674 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
3676 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
3677 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
3678 printf("Server correctly refused create of '%s'\n", r.in.alias_name->string);
3681 printf("Server should have refused create of '%s', got %s instead\n", r.in.alias_name->string,
3687 if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
3688 if (!test_DeleteAlias_byname(p, tctx, domain_handle, r.in.alias_name->string)) {
3691 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
3694 if (!NT_STATUS_IS_OK(status)) {
3695 printf("CreateAlias failed - %s\n", nt_errstr(status));
3699 if (!test_alias_ops(p, tctx, alias_handle, domain_sid)) {
3706 static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3707 const char *acct_name,
3708 struct policy_handle *domain_handle, char **password)
3716 if (!test_ChangePasswordUser(p, mem_ctx, acct_name, domain_handle, password)) {
3720 if (!test_ChangePasswordUser2(p, mem_ctx, acct_name, password, 0, true)) {
3724 if (!test_OemChangePasswordUser2(p, mem_ctx, acct_name, domain_handle, password)) {
3728 /* test what happens when setting the old password again */
3729 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, *password, 0, true)) {
3734 char simple_pass[9];
3735 char *v = generate_random_str(mem_ctx, 1);
3737 ZERO_STRUCT(simple_pass);
3738 memset(simple_pass, *v, sizeof(simple_pass) - 1);
3740 /* test what happens when picking a simple password */
3741 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, simple_pass, 0, true)) {
3746 /* set samr_SetDomainInfo level 1 with min_length 5 */
3748 struct samr_QueryDomainInfo r;
3749 union samr_DomainInfo *info = NULL;
3750 struct samr_SetDomainInfo s;
3751 uint16_t len_old, len;
3752 uint32_t pwd_prop_old;
3753 int64_t min_pwd_age_old;
3758 r.in.domain_handle = domain_handle;
3762 printf("testing samr_QueryDomainInfo level 1\n");
3763 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
3764 if (!NT_STATUS_IS_OK(status)) {
3768 s.in.domain_handle = domain_handle;
3772 /* remember the old min length, so we can reset it */
3773 len_old = s.in.info->info1.min_password_length;
3774 s.in.info->info1.min_password_length = len;
3775 pwd_prop_old = s.in.info->info1.password_properties;
3776 /* turn off password complexity checks for this test */
3777 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
3779 min_pwd_age_old = s.in.info->info1.min_password_age;
3780 s.in.info->info1.min_password_age = 0;
3782 printf("testing samr_SetDomainInfo level 1\n");
3783 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
3784 if (!NT_STATUS_IS_OK(status)) {
3788 printf("calling test_ChangePasswordUser3 with too short password\n");
3790 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, len - 1, password, NULL, 0, true)) {
3794 s.in.info->info1.min_password_length = len_old;
3795 s.in.info->info1.password_properties = pwd_prop_old;
3796 s.in.info->info1.min_password_age = min_pwd_age_old;
3798 printf("testing samr_SetDomainInfo level 1\n");
3799 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
3800 if (!NT_STATUS_IS_OK(status)) {
3808 struct samr_OpenUser r;
3809 struct samr_QueryUserInfo q;
3810 union samr_UserInfo *info;
3811 struct samr_LookupNames n;
3812 struct policy_handle user_handle;
3813 struct samr_Ids rids, types;
3815 n.in.domain_handle = domain_handle;
3817 n.in.names = talloc_array(mem_ctx, struct lsa_String, 1);
3818 n.in.names[0].string = acct_name;
3820 n.out.types = &types;
3822 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
3823 if (!NT_STATUS_IS_OK(status)) {
3824 printf("LookupNames failed - %s\n", nt_errstr(status));
3828 r.in.domain_handle = domain_handle;
3829 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3830 r.in.rid = n.out.rids->ids[0];
3831 r.out.user_handle = &user_handle;
3833 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3834 if (!NT_STATUS_IS_OK(status)) {
3835 printf("OpenUser(%u) failed - %s\n", n.out.rids->ids[0], nt_errstr(status));
3839 q.in.user_handle = &user_handle;
3843 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
3844 if (!NT_STATUS_IS_OK(status)) {
3845 printf("QueryUserInfo failed - %s\n", nt_errstr(status));
3849 printf("calling test_ChangePasswordUser3 with too early password change\n");
3851 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL,
3852 info->info5.last_password_change, true)) {
3857 /* we change passwords twice - this has the effect of verifying
3858 they were changed correctly for the final call */
3859 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, true)) {
3863 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, true)) {
3870 static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
3871 struct policy_handle *domain_handle,
3872 struct policy_handle *user_handle_out,
3873 struct dom_sid *domain_sid,
3874 enum torture_samr_choice which_ops,
3875 struct cli_credentials *machine_credentials)
3878 TALLOC_CTX *user_ctx;
3881 struct samr_CreateUser r;
3882 struct samr_QueryUserInfo q;
3883 union samr_UserInfo *info;
3884 struct samr_DeleteUser d;
3887 /* This call creates a 'normal' account - check that it really does */
3888 const uint32_t acct_flags = ACB_NORMAL;
3889 struct lsa_String name;
3892 struct policy_handle user_handle;
3893 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
3894 init_lsa_String(&name, TEST_ACCOUNT_NAME);
3896 r.in.domain_handle = domain_handle;
3897 r.in.account_name = &name;
3898 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3899 r.out.user_handle = &user_handle;
3902 printf("Testing CreateUser(%s)\n", r.in.account_name->string);
3904 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
3906 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
3907 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
3908 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
3911 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
3917 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
3918 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
3919 talloc_free(user_ctx);
3922 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
3924 if (!NT_STATUS_IS_OK(status)) {
3925 talloc_free(user_ctx);
3926 printf("CreateUser failed - %s\n", nt_errstr(status));
3929 q.in.user_handle = &user_handle;
3933 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
3934 if (!NT_STATUS_IS_OK(status)) {
3935 printf("QueryUserInfo level %u failed - %s\n",
3936 q.in.level, nt_errstr(status));
3939 if ((info->info16.acct_flags & acct_flags) != acct_flags) {
3940 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
3941 info->info16.acct_flags,
3947 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
3948 acct_flags, name.string, which_ops,
3949 machine_credentials)) {
3953 if (user_handle_out) {
3954 *user_handle_out = user_handle;
3956 printf("Testing DeleteUser (createuser test)\n");
3958 d.in.user_handle = &user_handle;
3959 d.out.user_handle = &user_handle;
3961 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
3962 if (!NT_STATUS_IS_OK(status)) {
3963 printf("DeleteUser failed - %s\n", nt_errstr(status));
3970 talloc_free(user_ctx);
3976 static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
3977 struct policy_handle *domain_handle,
3978 struct dom_sid *domain_sid,
3979 enum torture_samr_choice which_ops,
3980 struct cli_credentials *machine_credentials)
3983 struct samr_CreateUser2 r;
3984 struct samr_QueryUserInfo q;
3985 union samr_UserInfo *info;
3986 struct samr_DeleteUser d;
3987 struct policy_handle user_handle;
3989 struct lsa_String name;
3994 uint32_t acct_flags;
3995 const char *account_name;
3997 } account_types[] = {
3998 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
3999 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
4000 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
4001 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
4002 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
4003 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
4004 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
4005 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
4006 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
4007 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
4008 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
4009 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
4010 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
4011 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
4012 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
4015 for (i = 0; account_types[i].account_name; i++) {
4016 TALLOC_CTX *user_ctx;
4017 uint32_t acct_flags = account_types[i].acct_flags;
4018 uint32_t access_granted;
4019 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
4020 init_lsa_String(&name, account_types[i].account_name);
4022 r.in.domain_handle = domain_handle;
4023 r.in.account_name = &name;
4024 r.in.acct_flags = acct_flags;
4025 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4026 r.out.user_handle = &user_handle;
4027 r.out.access_granted = &access_granted;
4030 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
4032 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
4034 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
4035 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
4036 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
4039 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
4046 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
4047 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
4048 talloc_free(user_ctx);
4052 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
4055 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
4056 printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
4057 nt_errstr(status), nt_errstr(account_types[i].nt_status));
4061 if (NT_STATUS_IS_OK(status)) {
4062 q.in.user_handle = &user_handle;
4066 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
4067 if (!NT_STATUS_IS_OK(status)) {
4068 printf("QueryUserInfo level %u failed - %s\n",
4069 q.in.level, nt_errstr(status));
4072 uint32_t expected_flags = (acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
4073 if (acct_flags == ACB_NORMAL) {
4074 expected_flags |= ACB_PW_EXPIRED;
4076 if ((info->info5.acct_flags) != expected_flags) {
4077 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
4078 info->info5.acct_flags,
4082 switch (acct_flags) {
4084 if (info->info5.primary_gid != DOMAIN_RID_DCS) {
4085 printf("QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n",
4086 DOMAIN_RID_DCS, info->info5.primary_gid);
4091 if (info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
4092 printf("QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
4093 DOMAIN_RID_DOMAIN_MEMBERS, info->info5.primary_gid);
4098 if (info->info5.primary_gid != DOMAIN_RID_USERS) {
4099 printf("QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n",
4100 DOMAIN_RID_USERS, info->info5.primary_gid);
4107 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
4108 acct_flags, name.string, which_ops,
4109 machine_credentials)) {
4113 printf("Testing DeleteUser (createuser2 test)\n");
4115 d.in.user_handle = &user_handle;
4116 d.out.user_handle = &user_handle;
4118 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
4119 if (!NT_STATUS_IS_OK(status)) {
4120 printf("DeleteUser failed - %s\n", nt_errstr(status));
4124 talloc_free(user_ctx);
4130 static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4131 struct policy_handle *handle)
4134 struct samr_QueryAliasInfo r;
4135 union samr_AliasInfo *info;
4136 uint16_t levels[] = {1, 2, 3};
4140 for (i=0;i<ARRAY_SIZE(levels);i++) {
4141 printf("Testing QueryAliasInfo level %u\n", levels[i]);
4143 r.in.alias_handle = handle;
4144 r.in.level = levels[i];
4147 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
4148 if (!NT_STATUS_IS_OK(status)) {
4149 printf("QueryAliasInfo level %u failed - %s\n",
4150 levels[i], nt_errstr(status));
4158 static bool test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4159 struct policy_handle *handle)
4162 struct samr_QueryGroupInfo r;
4163 union samr_GroupInfo *info;
4164 uint16_t levels[] = {1, 2, 3, 4, 5};
4168 for (i=0;i<ARRAY_SIZE(levels);i++) {
4169 printf("Testing QueryGroupInfo level %u\n", levels[i]);
4171 r.in.group_handle = handle;
4172 r.in.level = levels[i];
4175 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
4176 if (!NT_STATUS_IS_OK(status)) {
4177 printf("QueryGroupInfo level %u failed - %s\n",
4178 levels[i], nt_errstr(status));
4186 static bool test_QueryGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4187 struct policy_handle *handle)
4190 struct samr_QueryGroupMember r;
4191 struct samr_RidTypeArray *rids = NULL;
4194 printf("Testing QueryGroupMember\n");
4196 r.in.group_handle = handle;
4199 status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &r);
4200 if (!NT_STATUS_IS_OK(status)) {
4201 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
4209 static bool test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4210 struct policy_handle *handle)
4213 struct samr_QueryGroupInfo r;
4214 union samr_GroupInfo *info;
4215 struct samr_SetGroupInfo s;
4216 uint16_t levels[] = {1, 2, 3, 4};
4217 uint16_t set_ok[] = {0, 1, 1, 1};
4221 for (i=0;i<ARRAY_SIZE(levels);i++) {
4222 printf("Testing QueryGroupInfo level %u\n", levels[i]);
4224 r.in.group_handle = handle;
4225 r.in.level = levels[i];
4228 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
4229 if (!NT_STATUS_IS_OK(status)) {
4230 printf("QueryGroupInfo level %u failed - %s\n",
4231 levels[i], nt_errstr(status));
4235 printf("Testing SetGroupInfo level %u\n", levels[i]);
4237 s.in.group_handle = handle;
4238 s.in.level = levels[i];
4239 s.in.info = *r.out.info;
4242 /* disabled this, as it changes the name only from the point of view of samr,
4243 but leaves the name from the point of view of w2k3 internals (and ldap). This means
4244 the name is still reserved, so creating the old name fails, but deleting by the old name
4246 if (s.in.level == 2) {
4247 init_lsa_String(&s.in.info->string, "NewName");
4251 if (s.in.level == 4) {
4252 init_lsa_String(&s.in.info->description, "test description");
4255 status = dcerpc_samr_SetGroupInfo(p, mem_ctx, &s);
4257 if (!NT_STATUS_IS_OK(status)) {
4258 printf("SetGroupInfo level %u failed - %s\n",
4259 r.in.level, nt_errstr(status));
4264 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
4265 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
4266 r.in.level, nt_errstr(status));
4276 static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4277 struct policy_handle *handle)
4280 struct samr_QueryUserInfo r;
4281 union samr_UserInfo *info;
4282 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
4283 11, 12, 13, 14, 16, 17, 20, 21};
4287 for (i=0;i<ARRAY_SIZE(levels);i++) {
4288 printf("Testing QueryUserInfo level %u\n", levels[i]);
4290 r.in.user_handle = handle;
4291 r.in.level = levels[i];
4294 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
4295 if (!NT_STATUS_IS_OK(status)) {
4296 printf("QueryUserInfo level %u failed - %s\n",
4297 levels[i], nt_errstr(status));
4305 static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4306 struct policy_handle *handle)
4309 struct samr_QueryUserInfo2 r;
4310 union samr_UserInfo *info;
4311 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
4312 11, 12, 13, 14, 16, 17, 20, 21};
4316 for (i=0;i<ARRAY_SIZE(levels);i++) {
4317 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
4319 r.in.user_handle = handle;
4320 r.in.level = levels[i];
4323 status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r);
4324 if (!NT_STATUS_IS_OK(status)) {
4325 printf("QueryUserInfo2 level %u failed - %s\n",
4326 levels[i], nt_errstr(status));
4334 static bool test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4335 struct policy_handle *handle, uint32_t rid)
4338 struct samr_OpenUser r;
4339 struct policy_handle user_handle;
4342 printf("Testing OpenUser(%u)\n", rid);
4344 r.in.domain_handle = handle;
4345 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4347 r.out.user_handle = &user_handle;
4349 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
4350 if (!NT_STATUS_IS_OK(status)) {
4351 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
4355 if (!test_QuerySecurity(p, mem_ctx, &user_handle)) {
4359 if (!test_QueryUserInfo(p, mem_ctx, &user_handle)) {
4363 if (!test_QueryUserInfo2(p, mem_ctx, &user_handle)) {
4367 if (!test_GetUserPwInfo(p, mem_ctx, &user_handle)) {
4371 if (!test_GetGroupsForUser(p,mem_ctx, &user_handle)) {
4375 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
4382 static bool test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4383 struct policy_handle *handle, uint32_t rid)
4386 struct samr_OpenGroup r;
4387 struct policy_handle group_handle;
4390 printf("Testing OpenGroup(%u)\n", rid);
4392 r.in.domain_handle = handle;
4393 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4395 r.out.group_handle = &group_handle;
4397 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
4398 if (!NT_STATUS_IS_OK(status)) {
4399 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
4403 if (!test_QuerySecurity(p, mem_ctx, &group_handle)) {
4407 if (!test_QueryGroupInfo(p, mem_ctx, &group_handle)) {
4411 if (!test_QueryGroupMember(p, mem_ctx, &group_handle)) {
4415 if (!test_samr_handle_Close(p, mem_ctx, &group_handle)) {
4422 static bool test_OpenAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
4423 struct policy_handle *handle, uint32_t rid)
4426 struct samr_OpenAlias r;
4427 struct policy_handle alias_handle;
4430 torture_comment(tctx, "Testing OpenAlias(%u)\n", rid);
4432 r.in.domain_handle = handle;
4433 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4435 r.out.alias_handle = &alias_handle;
4437 status = dcerpc_samr_OpenAlias(p, tctx, &r);
4438 if (!NT_STATUS_IS_OK(status)) {
4439 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
4443 if (!test_QuerySecurity(p, tctx, &alias_handle)) {
4447 if (!test_QueryAliasInfo(p, tctx, &alias_handle)) {
4451 if (!test_GetMembersInAlias(p, tctx, &alias_handle)) {
4455 if (!test_samr_handle_Close(p, tctx, &alias_handle)) {
4462 static bool check_mask(struct dcerpc_pipe *p, struct torture_context *tctx,
4463 struct policy_handle *handle, uint32_t rid,
4464 uint32_t acct_flag_mask)
4467 struct samr_OpenUser r;
4468 struct samr_QueryUserInfo q;
4469 union samr_UserInfo *info;
4470 struct policy_handle user_handle;
4473 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
4475 r.in.domain_handle = handle;
4476 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4478 r.out.user_handle = &user_handle;
4480 status = dcerpc_samr_OpenUser(p, tctx, &r);
4481 if (!NT_STATUS_IS_OK(status)) {
4482 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
4486 q.in.user_handle = &user_handle;
4490 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
4491 if (!NT_STATUS_IS_OK(status)) {
4492 printf("QueryUserInfo level 16 failed - %s\n",
4496 if ((acct_flag_mask & info->info16.acct_flags) == 0) {
4497 printf("Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
4498 acct_flag_mask, info->info16.acct_flags, rid);
4503 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
4510 static bool test_EnumDomainUsers(struct dcerpc_pipe *p, struct torture_context *tctx,
4511 struct policy_handle *handle)
4513 NTSTATUS status = STATUS_MORE_ENTRIES;
4514 struct samr_EnumDomainUsers r;
4515 uint32_t mask, resume_handle=0;
4518 struct samr_LookupNames n;
4519 struct samr_LookupRids lr ;
4520 struct lsa_Strings names;
4521 struct samr_Ids rids, types;
4522 struct samr_SamArray *sam = NULL;
4523 uint32_t num_entries = 0;
4525 uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
4526 ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
4527 ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
4530 printf("Testing EnumDomainUsers\n");
4532 for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
4533 r.in.domain_handle = handle;
4534 r.in.resume_handle = &resume_handle;
4535 r.in.acct_flags = mask = masks[mask_idx];
4536 r.in.max_size = (uint32_t)-1;
4537 r.out.resume_handle = &resume_handle;
4538 r.out.num_entries = &num_entries;
4541 status = dcerpc_samr_EnumDomainUsers(p, tctx, &r);
4542 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
4543 !NT_STATUS_IS_OK(status)) {
4544 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
4548 torture_assert(tctx, sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
4550 if (sam->count == 0) {
4554 for (i=0;i<sam->count;i++) {
4556 if (!check_mask(p, tctx, handle, sam->entries[i].idx, mask)) {
4559 } else if (!test_OpenUser(p, tctx, handle, sam->entries[i].idx)) {
4565 printf("Testing LookupNames\n");
4566 n.in.domain_handle = handle;
4567 n.in.num_names = sam->count;
4568 n.in.names = talloc_array(tctx, struct lsa_String, sam->count);
4570 n.out.types = &types;
4571 for (i=0;i<sam->count;i++) {
4572 n.in.names[i].string = sam->entries[i].name.string;
4574 status = dcerpc_samr_LookupNames(p, tctx, &n);
4575 if (!NT_STATUS_IS_OK(status)) {
4576 printf("LookupNames failed - %s\n", nt_errstr(status));
4581 printf("Testing LookupRids\n");
4582 lr.in.domain_handle = handle;
4583 lr.in.num_rids = sam->count;
4584 lr.in.rids = talloc_array(tctx, uint32_t, sam->count);
4585 lr.out.names = &names;
4586 lr.out.types = &types;
4587 for (i=0;i<sam->count;i++) {
4588 lr.in.rids[i] = sam->entries[i].idx;
4590 status = dcerpc_samr_LookupRids(p, tctx, &lr);
4591 torture_assert_ntstatus_ok(tctx, status, "LookupRids");
4597 try blasting the server with a bunch of sync requests
4599 static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, struct torture_context *tctx,
4600 struct policy_handle *handle)
4603 struct samr_EnumDomainUsers r;
4604 uint32_t resume_handle=0;
4606 #define ASYNC_COUNT 100
4607 struct rpc_request *req[ASYNC_COUNT];
4609 if (!torture_setting_bool(tctx, "dangerous", false)) {
4610 torture_skip(tctx, "samr async test disabled - enable dangerous tests to use\n");
4613 torture_comment(tctx, "Testing EnumDomainUsers_async\n");
4615 r.in.domain_handle = handle;
4616 r.in.resume_handle = &resume_handle;
4617 r.in.acct_flags = 0;
4618 r.in.max_size = (uint32_t)-1;
4619 r.out.resume_handle = &resume_handle;
4621 for (i=0;i<ASYNC_COUNT;i++) {
4622 req[i] = dcerpc_samr_EnumDomainUsers_send(p, tctx, &r);
4625 for (i=0;i<ASYNC_COUNT;i++) {
4626 status = dcerpc_ndr_request_recv(req[i]);
4627 if (!NT_STATUS_IS_OK(status)) {
4628 printf("EnumDomainUsers[%d] failed - %s\n",
4629 i, nt_errstr(status));
4634 torture_comment(tctx, "%d async requests OK\n", i);
4639 static bool test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4640 struct policy_handle *handle)
4643 struct samr_EnumDomainGroups r;
4644 uint32_t resume_handle=0;
4645 struct samr_SamArray *sam = NULL;
4646 uint32_t num_entries = 0;
4650 printf("Testing EnumDomainGroups\n");
4652 r.in.domain_handle = handle;
4653 r.in.resume_handle = &resume_handle;
4654 r.in.max_size = (uint32_t)-1;
4655 r.out.resume_handle = &resume_handle;
4656 r.out.num_entries = &num_entries;
4659 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
4660 if (!NT_STATUS_IS_OK(status)) {
4661 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
4669 for (i=0;i<sam->count;i++) {
4670 if (!test_OpenGroup(p, mem_ctx, handle, sam->entries[i].idx)) {
4678 static bool test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4679 struct policy_handle *handle)
4682 struct samr_EnumDomainAliases r;
4683 uint32_t resume_handle=0;
4684 struct samr_SamArray *sam = NULL;
4685 uint32_t num_entries = 0;
4689 printf("Testing EnumDomainAliases\n");
4691 r.in.domain_handle = handle;
4692 r.in.resume_handle = &resume_handle;
4693 r.in.max_size = (uint32_t)-1;
4695 r.out.num_entries = &num_entries;
4696 r.out.resume_handle = &resume_handle;
4698 status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
4699 if (!NT_STATUS_IS_OK(status)) {
4700 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
4708 for (i=0;i<sam->count;i++) {
4709 if (!test_OpenAlias(p, mem_ctx, handle, sam->entries[i].idx)) {
4717 static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4718 struct policy_handle *handle)
4721 struct samr_GetDisplayEnumerationIndex r;
4723 uint16_t levels[] = {1, 2, 3, 4, 5};
4724 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
4725 struct lsa_String name;
4729 for (i=0;i<ARRAY_SIZE(levels);i++) {
4730 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
4732 init_lsa_String(&name, TEST_ACCOUNT_NAME);
4734 r.in.domain_handle = handle;
4735 r.in.level = levels[i];
4739 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
4742 !NT_STATUS_IS_OK(status) &&
4743 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
4744 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
4745 levels[i], nt_errstr(status));
4749 init_lsa_String(&name, "zzzzzzzz");
4751 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
4753 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
4754 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
4755 levels[i], nt_errstr(status));
4763 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4764 struct policy_handle *handle)
4767 struct samr_GetDisplayEnumerationIndex2 r;
4769 uint16_t levels[] = {1, 2, 3, 4, 5};
4770 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
4771 struct lsa_String name;
4775 for (i=0;i<ARRAY_SIZE(levels);i++) {
4776 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
4778 init_lsa_String(&name, TEST_ACCOUNT_NAME);
4780 r.in.domain_handle = handle;
4781 r.in.level = levels[i];
4785 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
4787 !NT_STATUS_IS_OK(status) &&
4788 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
4789 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
4790 levels[i], nt_errstr(status));
4794 init_lsa_String(&name, "zzzzzzzz");
4796 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
4797 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
4798 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
4799 levels[i], nt_errstr(status));
4807 #define STRING_EQUAL_QUERY(s1, s2, user) \
4808 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
4809 /* odd, but valid */ \
4810 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
4811 printf("%s mismatch for %s: %s != %s (%s)\n", \
4812 #s1, user.string, s1.string, s2.string, __location__); \
4815 #define INT_EQUAL_QUERY(s1, s2, user) \
4817 printf("%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
4818 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
4822 static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4823 struct samr_QueryDisplayInfo *querydisplayinfo,
4824 bool *seen_testuser)
4826 struct samr_OpenUser r;
4827 struct samr_QueryUserInfo q;
4828 union samr_UserInfo *info;
4829 struct policy_handle user_handle;
4832 r.in.domain_handle = querydisplayinfo->in.domain_handle;
4833 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4834 for (i = 0; ; i++) {
4835 switch (querydisplayinfo->in.level) {
4837 if (i >= querydisplayinfo->out.info->info1.count) {
4840 r.in.rid = querydisplayinfo->out.info->info1.entries[i].rid;
4843 if (i >= querydisplayinfo->out.info->info2.count) {
4846 r.in.rid = querydisplayinfo->out.info->info2.entries[i].rid;
4852 /* Not interested in validating just the account name */
4856 r.out.user_handle = &user_handle;
4858 switch (querydisplayinfo->in.level) {
4861 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
4862 if (!NT_STATUS_IS_OK(status)) {
4863 printf("OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(status));
4868 q.in.user_handle = &user_handle;
4871 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
4872 if (!NT_STATUS_IS_OK(status)) {
4873 printf("QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(status));
4877 switch (querydisplayinfo->in.level) {
4879 if (seen_testuser && strcmp(info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
4880 *seen_testuser = true;
4882 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].full_name,
4883 info->info21.full_name, info->info21.account_name);
4884 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].account_name,
4885 info->info21.account_name, info->info21.account_name);
4886 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].description,
4887 info->info21.description, info->info21.account_name);
4888 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].rid,
4889 info->info21.rid, info->info21.account_name);
4890 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].acct_flags,
4891 info->info21.acct_flags, info->info21.account_name);
4895 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].account_name,
4896 info->info21.account_name, info->info21.account_name);
4897 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].description,
4898 info->info21.description, info->info21.account_name);
4899 INT_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].rid,
4900 info->info21.rid, info->info21.account_name);
4901 INT_EQUAL_QUERY((querydisplayinfo->out.info->info2.entries[i].acct_flags & ~ACB_NORMAL),
4902 info->info21.acct_flags, info->info21.account_name);
4904 if (!(querydisplayinfo->out.info->info2.entries[i].acct_flags & ACB_NORMAL)) {
4905 printf("Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
4906 info->info21.account_name.string);
4909 if (!(info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
4910 printf("Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
4911 info->info21.account_name.string,
4912 querydisplayinfo->out.info->info2.entries[i].acct_flags,
4913 info->info21.acct_flags);
4920 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
4927 static bool test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4928 struct policy_handle *handle)
4931 struct samr_QueryDisplayInfo r;
4932 struct samr_QueryDomainInfo dom_info;
4933 union samr_DomainInfo *info = NULL;
4935 uint16_t levels[] = {1, 2, 3, 4, 5};
4937 bool seen_testuser = false;
4938 uint32_t total_size;
4939 uint32_t returned_size;
4940 union samr_DispInfo disp_info;
4943 for (i=0;i<ARRAY_SIZE(levels);i++) {
4944 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
4947 status = STATUS_MORE_ENTRIES;
4948 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
4949 r.in.domain_handle = handle;
4950 r.in.level = levels[i];
4951 r.in.max_entries = 2;
4952 r.in.buf_size = (uint32_t)-1;
4953 r.out.total_size = &total_size;
4954 r.out.returned_size = &returned_size;
4955 r.out.info = &disp_info;
4957 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
4958 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(status)) {
4959 printf("QueryDisplayInfo level %u failed - %s\n",
4960 levels[i], nt_errstr(status));
4963 switch (r.in.level) {
4965 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, &seen_testuser)) {
4968 r.in.start_idx += r.out.info->info1.count;
4971 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, NULL)) {
4974 r.in.start_idx += r.out.info->info2.count;
4977 r.in.start_idx += r.out.info->info3.count;
4980 r.in.start_idx += r.out.info->info4.count;
4983 r.in.start_idx += r.out.info->info5.count;
4987 dom_info.in.domain_handle = handle;
4988 dom_info.in.level = 2;
4989 dom_info.out.info = &info;
4991 /* Check number of users returned is correct */
4992 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &dom_info);
4993 if (!NT_STATUS_IS_OK(status)) {
4994 printf("QueryDomainInfo level %u failed - %s\n",
4995 r.in.level, nt_errstr(status));
4999 switch (r.in.level) {
5002 if (info->general.num_users < r.in.start_idx) {
5003 printf("QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
5004 r.in.start_idx, info->general.num_groups,
5005 info->general.domain_name.string);
5008 if (!seen_testuser) {
5009 struct policy_handle user_handle;
5010 if (NT_STATUS_IS_OK(test_OpenUser_byname(p, mem_ctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
5011 printf("Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
5012 info->general.domain_name.string);
5014 test_samr_handle_Close(p, mem_ctx, &user_handle);
5020 if (info->general.num_groups != r.in.start_idx) {
5021 printf("QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
5022 r.in.start_idx, info->general.num_groups,
5023 info->general.domain_name.string);
5035 static bool test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
5036 struct policy_handle *handle)
5039 struct samr_QueryDisplayInfo2 r;
5041 uint16_t levels[] = {1, 2, 3, 4, 5};
5043 uint32_t total_size;
5044 uint32_t returned_size;
5045 union samr_DispInfo info;
5047 for (i=0;i<ARRAY_SIZE(levels);i++) {
5048 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
5050 r.in.domain_handle = handle;
5051 r.in.level = levels[i];
5053 r.in.max_entries = 1000;
5054 r.in.buf_size = (uint32_t)-1;
5055 r.out.total_size = &total_size;
5056 r.out.returned_size = &returned_size;
5059 status = dcerpc_samr_QueryDisplayInfo2(p, mem_ctx, &r);
5060 if (!NT_STATUS_IS_OK(status)) {
5061 printf("QueryDisplayInfo2 level %u failed - %s\n",
5062 levels[i], nt_errstr(status));
5070 static bool test_QueryDisplayInfo3(struct dcerpc_pipe *p, struct torture_context *tctx,
5071 struct policy_handle *handle)
5074 struct samr_QueryDisplayInfo3 r;
5076 uint16_t levels[] = {1, 2, 3, 4, 5};
5078 uint32_t total_size;
5079 uint32_t returned_size;
5080 union samr_DispInfo info;
5082 for (i=0;i<ARRAY_SIZE(levels);i++) {
5083 torture_comment(tctx, "Testing QueryDisplayInfo3 level %u\n", levels[i]);
5085 r.in.domain_handle = handle;
5086 r.in.level = levels[i];
5088 r.in.max_entries = 1000;
5089 r.in.buf_size = (uint32_t)-1;
5090 r.out.total_size = &total_size;
5091 r.out.returned_size = &returned_size;
5094 status = dcerpc_samr_QueryDisplayInfo3(p, tctx, &r);
5095 if (!NT_STATUS_IS_OK(status)) {
5096 printf("QueryDisplayInfo3 level %u failed - %s\n",
5097 levels[i], nt_errstr(status));
5106 static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
5107 struct policy_handle *handle)
5110 struct samr_QueryDisplayInfo r;
5112 uint32_t total_size;
5113 uint32_t returned_size;
5114 union samr_DispInfo info;
5116 printf("Testing QueryDisplayInfo continuation\n");
5118 r.in.domain_handle = handle;
5121 r.in.max_entries = 1;
5122 r.in.buf_size = (uint32_t)-1;
5123 r.out.total_size = &total_size;
5124 r.out.returned_size = &returned_size;
5128 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
5129 if (NT_STATUS_IS_OK(status) && *r.out.returned_size != 0) {
5130 if (r.out.info->info1.entries[0].idx != r.in.start_idx + 1) {
5131 printf("expected idx %d but got %d\n",
5133 r.out.info->info1.entries[0].idx);
5137 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
5138 !NT_STATUS_IS_OK(status)) {
5139 printf("QueryDisplayInfo level %u failed - %s\n",
5140 r.in.level, nt_errstr(status));
5145 } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
5146 NT_STATUS_IS_OK(status)) &&
5147 *r.out.returned_size != 0);
5152 static bool test_QueryDomainInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
5153 struct policy_handle *handle)
5156 struct samr_QueryDomainInfo r;
5157 union samr_DomainInfo *info = NULL;
5158 struct samr_SetDomainInfo s;
5159 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
5160 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
5163 const char *domain_comment = talloc_asprintf(tctx,
5164 "Tortured by Samba4 RPC-SAMR: %s",
5165 timestring(tctx, time(NULL)));
5167 s.in.domain_handle = handle;
5169 s.in.info = talloc(tctx, union samr_DomainInfo);
5171 s.in.info->oem.oem_information.string = domain_comment;
5172 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
5173 if (!NT_STATUS_IS_OK(status)) {
5174 printf("SetDomainInfo level %u (set comment) failed - %s\n",
5175 s.in.level, nt_errstr(status));
5179 for (i=0;i<ARRAY_SIZE(levels);i++) {
5180 torture_comment(tctx, "Testing QueryDomainInfo level %u\n", levels[i]);
5182 r.in.domain_handle = handle;
5183 r.in.level = levels[i];
5186 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
5187 if (!NT_STATUS_IS_OK(status)) {
5188 printf("QueryDomainInfo level %u failed - %s\n",
5189 r.in.level, nt_errstr(status));
5194 switch (levels[i]) {
5196 if (strcmp(info->general.oem_information.string, domain_comment) != 0) {
5197 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
5198 levels[i], info->general.oem_information.string, domain_comment);
5201 if (!info->general.primary.string) {
5202 printf("QueryDomainInfo level %u returned no PDC name\n",
5205 } else if (info->general.role == SAMR_ROLE_DOMAIN_PDC) {
5206 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), info->general.primary.string) != 0) {
5207 printf("QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
5208 levels[i], info->general.primary.string, dcerpc_server_name(p));
5213 if (strcmp(info->oem.oem_information.string, domain_comment) != 0) {
5214 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
5215 levels[i], info->oem.oem_information.string, domain_comment);
5220 if (!info->info6.primary.string) {
5221 printf("QueryDomainInfo level %u returned no PDC name\n",
5227 if (strcmp(info->general2.general.oem_information.string, domain_comment) != 0) {
5228 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
5229 levels[i], info->general2.general.oem_information.string, domain_comment);
5235 torture_comment(tctx, "Testing SetDomainInfo level %u\n", levels[i]);
5237 s.in.domain_handle = handle;
5238 s.in.level = levels[i];
5241 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
5243 if (!NT_STATUS_IS_OK(status)) {
5244 printf("SetDomainInfo level %u failed - %s\n",
5245 r.in.level, nt_errstr(status));
5250 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
5251 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
5252 r.in.level, nt_errstr(status));
5258 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
5259 if (!NT_STATUS_IS_OK(status)) {
5260 printf("QueryDomainInfo level %u failed - %s\n",
5261 r.in.level, nt_errstr(status));
5271 static bool test_QueryDomainInfo2(struct dcerpc_pipe *p, struct torture_context *tctx,
5272 struct policy_handle *handle)
5275 struct samr_QueryDomainInfo2 r;
5276 union samr_DomainInfo *info = NULL;
5277 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
5281 for (i=0;i<ARRAY_SIZE(levels);i++) {
5282 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
5284 r.in.domain_handle = handle;
5285 r.in.level = levels[i];
5288 status = dcerpc_samr_QueryDomainInfo2(p, tctx, &r);
5289 if (!NT_STATUS_IS_OK(status)) {
5290 printf("QueryDomainInfo2 level %u failed - %s\n",
5291 r.in.level, nt_errstr(status));
5300 /* Test whether querydispinfo level 5 and enumdomgroups return the same
5301 set of group names. */
5302 static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx,
5303 struct policy_handle *handle)
5305 struct samr_EnumDomainGroups q1;
5306 struct samr_QueryDisplayInfo q2;
5308 uint32_t resume_handle=0;
5309 struct samr_SamArray *sam = NULL;
5310 uint32_t num_entries = 0;
5313 uint32_t total_size;
5314 uint32_t returned_size;
5315 union samr_DispInfo info;
5318 const char **names = NULL;
5320 torture_comment(tctx, "Testing coherency of querydispinfo vs enumdomgroups\n");
5322 q1.in.domain_handle = handle;
5323 q1.in.resume_handle = &resume_handle;
5325 q1.out.resume_handle = &resume_handle;
5326 q1.out.num_entries = &num_entries;
5329 status = STATUS_MORE_ENTRIES;
5330 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
5331 status = dcerpc_samr_EnumDomainGroups(p, tctx, &q1);
5333 if (!NT_STATUS_IS_OK(status) &&
5334 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
5337 for (i=0; i<*q1.out.num_entries; i++) {
5338 add_string_to_array(tctx,
5339 sam->entries[i].name.string,
5340 &names, &num_names);
5344 torture_assert_ntstatus_ok(tctx, status, "EnumDomainGroups");
5346 torture_assert(tctx, sam, "EnumDomainGroups failed to return sam");
5348 q2.in.domain_handle = handle;
5350 q2.in.start_idx = 0;
5351 q2.in.max_entries = 5;
5352 q2.in.buf_size = (uint32_t)-1;
5353 q2.out.total_size = &total_size;
5354 q2.out.returned_size = &returned_size;
5355 q2.out.info = &info;
5357 status = STATUS_MORE_ENTRIES;
5358 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
5359 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &q2);
5361 if (!NT_STATUS_IS_OK(status) &&
5362 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
5365 for (i=0; i<q2.out.info->info5.count; i++) {
5367 const char *name = q2.out.info->info5.entries[i].account_name.string;
5369 for (j=0; j<num_names; j++) {
5370 if (names[j] == NULL)
5372 if (strequal(names[j], name)) {
5380 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
5385 q2.in.start_idx += q2.out.info->info5.count;
5388 if (!NT_STATUS_IS_OK(status)) {
5389 printf("QueryDisplayInfo level 5 failed - %s\n",
5394 for (i=0; i<num_names; i++) {
5395 if (names[i] != NULL) {
5396 printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
5405 static bool test_DeleteDomainGroup(struct dcerpc_pipe *p, struct torture_context *tctx,
5406 struct policy_handle *group_handle)
5408 struct samr_DeleteDomainGroup d;
5411 torture_comment(tctx, "Testing DeleteDomainGroup\n");
5413 d.in.group_handle = group_handle;
5414 d.out.group_handle = group_handle;
5416 status = dcerpc_samr_DeleteDomainGroup(p, tctx, &d);
5417 torture_assert_ntstatus_ok(tctx, status, "DeleteDomainGroup");
5422 static bool test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
5423 struct policy_handle *domain_handle)
5425 struct samr_TestPrivateFunctionsDomain r;
5429 torture_comment(tctx, "Testing TestPrivateFunctionsDomain\n");
5431 r.in.domain_handle = domain_handle;
5433 status = dcerpc_samr_TestPrivateFunctionsDomain(p, tctx, &r);
5434 torture_assert_ntstatus_equal(tctx, NT_STATUS_NOT_IMPLEMENTED, status, "TestPrivateFunctionsDomain");
5439 static bool test_RidToSid(struct dcerpc_pipe *p, struct torture_context *tctx,
5440 struct dom_sid *domain_sid,
5441 struct policy_handle *domain_handle)
5443 struct samr_RidToSid r;
5446 struct dom_sid *calc_sid, *out_sid;
5447 int rids[] = { 0, 42, 512, 10200 };
5450 for (i=0;i<ARRAY_SIZE(rids);i++) {
5451 torture_comment(tctx, "Testing RidToSid\n");
5453 calc_sid = dom_sid_dup(tctx, domain_sid);
5454 r.in.domain_handle = domain_handle;
5456 r.out.sid = &out_sid;
5458 status = dcerpc_samr_RidToSid(p, tctx, &r);
5459 if (!NT_STATUS_IS_OK(status)) {
5460 printf("RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
5463 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
5465 if (!dom_sid_equal(calc_sid, out_sid)) {
5466 printf("RidToSid for %d failed - got %s, expected %s\n", rids[i],
5467 dom_sid_string(tctx, out_sid),
5468 dom_sid_string(tctx, calc_sid));
5477 static bool test_GetBootKeyInformation(struct dcerpc_pipe *p, struct torture_context *tctx,
5478 struct policy_handle *domain_handle)
5480 struct samr_GetBootKeyInformation r;
5483 uint32_t unknown = 0;
5485 torture_comment(tctx, "Testing GetBootKeyInformation\n");
5487 r.in.domain_handle = domain_handle;
5488 r.out.unknown = &unknown;
5490 status = dcerpc_samr_GetBootKeyInformation(p, tctx, &r);
5491 if (!NT_STATUS_IS_OK(status)) {
5492 /* w2k3 seems to fail this sometimes and pass it sometimes */
5493 torture_comment(tctx, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
5499 static bool test_AddGroupMember(struct dcerpc_pipe *p, struct torture_context *tctx,
5500 struct policy_handle *domain_handle,
5501 struct policy_handle *group_handle)
5504 struct samr_AddGroupMember r;
5505 struct samr_DeleteGroupMember d;
5506 struct samr_QueryGroupMember q;
5507 struct samr_RidTypeArray *rids = NULL;
5508 struct samr_SetMemberAttributesOfGroup s;
5511 status = test_LookupName(p, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
5512 torture_assert_ntstatus_ok(tctx, status, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME);
5514 r.in.group_handle = group_handle;
5516 r.in.flags = 0; /* ??? */
5518 torture_comment(tctx, "Testing AddGroupMember and DeleteGroupMember\n");
5520 d.in.group_handle = group_handle;
5523 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
5524 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_NOT_IN_GROUP, status, "DeleteGroupMember");
5526 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5527 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
5529 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5530 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_IN_GROUP, status, "AddGroupMember");
5532 if (torture_setting_bool(tctx, "samba4", false)) {
5533 torture_comment(tctx, "skipping SetMemberAttributesOfGroup test against Samba4\n");
5535 /* this one is quite strange. I am using random inputs in the
5536 hope of triggering an error that might give us a clue */
5538 s.in.group_handle = group_handle;
5539 s.in.unknown1 = random();
5540 s.in.unknown2 = random();
5542 status = dcerpc_samr_SetMemberAttributesOfGroup(p, tctx, &s);
5543 torture_assert_ntstatus_ok(tctx, status, "SetMemberAttributesOfGroup");
5546 q.in.group_handle = group_handle;
5549 status = dcerpc_samr_QueryGroupMember(p, tctx, &q);
5550 torture_assert_ntstatus_ok(tctx, status, "QueryGroupMember");
5552 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
5553 torture_assert_ntstatus_ok(tctx, status, "DeleteGroupMember");
5555 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5556 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
5562 static bool test_CreateDomainGroup(struct dcerpc_pipe *p,
5563 struct torture_context *tctx,
5564 struct policy_handle *domain_handle,
5565 struct policy_handle *group_handle,
5566 struct dom_sid *domain_sid)
5569 struct samr_CreateDomainGroup r;
5571 struct lsa_String name;
5574 init_lsa_String(&name, TEST_GROUPNAME);
5576 r.in.domain_handle = domain_handle;
5578 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5579 r.out.group_handle = group_handle;
5582 printf("Testing CreateDomainGroup(%s)\n", r.in.name->string);
5584 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
5586 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5587 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5588 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.name->string);
5591 printf("Server should have refused create of '%s', got %s instead\n", r.in.name->string,
5597 if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS)) {
5598 if (!test_DeleteGroup_byname(p, tctx, domain_handle, r.in.name->string)) {
5599 printf("CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
5603 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
5605 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
5606 if (!test_DeleteUser_byname(p, tctx, domain_handle, r.in.name->string)) {
5608 printf("CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
5612 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
5614 torture_assert_ntstatus_ok(tctx, status, "CreateDomainGroup");
5616 if (!test_AddGroupMember(p, tctx, domain_handle, group_handle)) {
5617 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
5621 if (!test_SetGroupInfo(p, tctx, group_handle)) {
5630 its not totally clear what this does. It seems to accept any sid you like.
5632 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p,
5633 struct torture_context *tctx,
5634 struct policy_handle *domain_handle)
5637 struct samr_RemoveMemberFromForeignDomain r;
5639 r.in.domain_handle = domain_handle;
5640 r.in.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-12-34-56-78");
5642 status = dcerpc_samr_RemoveMemberFromForeignDomain(p, tctx, &r);
5643 torture_assert_ntstatus_ok(tctx, status, "RemoveMemberFromForeignDomain");
5650 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
5651 struct policy_handle *handle);
5653 static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
5654 struct policy_handle *handle, struct dom_sid *sid,
5655 enum torture_samr_choice which_ops,
5656 struct cli_credentials *machine_credentials)
5659 struct samr_OpenDomain r;
5660 struct policy_handle domain_handle;
5661 struct policy_handle alias_handle;
5662 struct policy_handle user_handle;
5663 struct policy_handle group_handle;
5666 ZERO_STRUCT(alias_handle);
5667 ZERO_STRUCT(user_handle);
5668 ZERO_STRUCT(group_handle);
5669 ZERO_STRUCT(domain_handle);
5671 torture_comment(tctx, "Testing OpenDomain of %s\n", dom_sid_string(tctx, sid));
5673 r.in.connect_handle = handle;
5674 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5676 r.out.domain_handle = &domain_handle;
5678 status = dcerpc_samr_OpenDomain(p, tctx, &r);
5679 torture_assert_ntstatus_ok(tctx, status, "OpenDomain");
5681 /* run the domain tests with the main handle closed - this tests
5682 the servers reference counting */
5683 ret &= test_samr_handle_Close(p, tctx, handle);
5685 switch (which_ops) {
5686 case TORTURE_SAMR_USER_ATTRIBUTES:
5687 case TORTURE_SAMR_PASSWORDS:
5688 if (!torture_setting_bool(tctx, "samba3", false)) {
5689 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops, NULL);
5691 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops, NULL);
5692 /* This test needs 'complex' users to validate */
5693 ret &= test_QueryDisplayInfo(p, tctx, &domain_handle);
5695 printf("Testing PASSWORDS or ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
5698 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
5699 if (!torture_setting_bool(tctx, "samba3", false)) {
5700 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops, machine_credentials);
5702 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops, machine_credentials);
5704 printf("Testing PASSWORDS PWDLASTSET on domain %s failed!\n", dom_sid_string(tctx, sid));
5707 case TORTURE_SAMR_OTHER:
5708 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops, NULL);
5710 printf("Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid));
5712 ret &= test_QuerySecurity(p, tctx, &domain_handle);
5713 ret &= test_RemoveMemberFromForeignDomain(p, tctx, &domain_handle);
5714 ret &= test_CreateAlias(p, tctx, &domain_handle, &alias_handle, sid);
5715 ret &= test_CreateDomainGroup(p, tctx, &domain_handle, &group_handle, sid);
5716 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
5717 ret &= test_QueryDomainInfo2(p, tctx, &domain_handle);
5718 ret &= test_EnumDomainUsers(p, tctx, &domain_handle);
5719 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
5720 ret &= test_EnumDomainGroups(p, tctx, &domain_handle);
5721 ret &= test_EnumDomainAliases(p, tctx, &domain_handle);
5722 ret &= test_QueryDisplayInfo2(p, tctx, &domain_handle);
5723 ret &= test_QueryDisplayInfo3(p, tctx, &domain_handle);
5724 ret &= test_QueryDisplayInfo_continue(p, tctx, &domain_handle);
5726 if (torture_setting_bool(tctx, "samba4", false)) {
5727 torture_comment(tctx, "skipping GetDisplayEnumerationIndex test against Samba4\n");
5729 ret &= test_GetDisplayEnumerationIndex(p, tctx, &domain_handle);
5730 ret &= test_GetDisplayEnumerationIndex2(p, tctx, &domain_handle);
5732 ret &= test_GroupList(p, tctx, &domain_handle);
5733 ret &= test_TestPrivateFunctionsDomain(p, tctx, &domain_handle);
5734 ret &= test_RidToSid(p, tctx, sid, &domain_handle);
5735 ret &= test_GetBootKeyInformation(p, tctx, &domain_handle);
5737 torture_comment(tctx, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx, sid));
5742 if (!policy_handle_empty(&user_handle) &&
5743 !test_DeleteUser(p, tctx, &user_handle)) {
5747 if (!policy_handle_empty(&alias_handle) &&
5748 !test_DeleteAlias(p, tctx, &alias_handle)) {
5752 if (!policy_handle_empty(&group_handle) &&
5753 !test_DeleteDomainGroup(p, tctx, &group_handle)) {
5757 ret &= test_samr_handle_Close(p, tctx, &domain_handle);
5759 /* reconnect the main handle */
5760 ret &= test_Connect(p, tctx, handle);
5763 printf("Testing domain %s failed!\n", dom_sid_string(tctx, sid));
5769 static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
5770 struct policy_handle *handle, const char *domain,
5771 enum torture_samr_choice which_ops,
5772 struct cli_credentials *machine_credentials)
5775 struct samr_LookupDomain r;
5776 struct dom_sid2 *sid = NULL;
5777 struct lsa_String n1;
5778 struct lsa_String n2;
5781 torture_comment(tctx, "Testing LookupDomain(%s)\n", domain);
5783 /* check for correct error codes */
5784 r.in.connect_handle = handle;
5785 r.in.domain_name = &n2;
5789 status = dcerpc_samr_LookupDomain(p, tctx, &r);
5790 torture_assert_ntstatus_equal(tctx, NT_STATUS_INVALID_PARAMETER, status, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
5792 init_lsa_String(&n2, "xxNODOMAINxx");
5794 status = dcerpc_samr_LookupDomain(p, tctx, &r);
5795 torture_assert_ntstatus_equal(tctx, NT_STATUS_NO_SUCH_DOMAIN, status, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
5797 r.in.connect_handle = handle;
5799 init_lsa_String(&n1, domain);
5800 r.in.domain_name = &n1;
5802 status = dcerpc_samr_LookupDomain(p, tctx, &r);
5803 torture_assert_ntstatus_ok(tctx, status, "LookupDomain");
5805 if (!test_GetDomPwInfo(p, tctx, &n1)) {
5809 if (!test_OpenDomain(p, tctx, handle, *r.out.sid, which_ops,
5810 machine_credentials)) {
5818 static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
5819 struct policy_handle *handle, enum torture_samr_choice which_ops,
5820 struct cli_credentials *machine_credentials)
5823 struct samr_EnumDomains r;
5824 uint32_t resume_handle = 0;
5825 uint32_t num_entries = 0;
5826 struct samr_SamArray *sam = NULL;
5830 r.in.connect_handle = handle;
5831 r.in.resume_handle = &resume_handle;
5832 r.in.buf_size = (uint32_t)-1;
5833 r.out.resume_handle = &resume_handle;
5834 r.out.num_entries = &num_entries;
5837 status = dcerpc_samr_EnumDomains(p, tctx, &r);
5838 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
5844 for (i=0;i<sam->count;i++) {
5845 if (!test_LookupDomain(p, tctx, handle,
5846 sam->entries[i].name.string, which_ops,
5847 machine_credentials)) {
5852 status = dcerpc_samr_EnumDomains(p, tctx, &r);
5853 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
5859 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
5860 struct policy_handle *handle)
5863 struct samr_Connect r;
5864 struct samr_Connect2 r2;
5865 struct samr_Connect3 r3;
5866 struct samr_Connect4 r4;
5867 struct samr_Connect5 r5;
5868 union samr_ConnectInfo info;
5869 struct policy_handle h;
5870 uint32_t level_out = 0;
5871 bool ret = true, got_handle = false;
5873 torture_comment(tctx, "testing samr_Connect\n");
5875 r.in.system_name = 0;
5876 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5877 r.out.connect_handle = &h;
5879 status = dcerpc_samr_Connect(p, tctx, &r);
5880 if (!NT_STATUS_IS_OK(status)) {
5881 torture_comment(tctx, "Connect failed - %s\n", nt_errstr(status));
5888 torture_comment(tctx, "testing samr_Connect2\n");
5890 r2.in.system_name = NULL;
5891 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5892 r2.out.connect_handle = &h;
5894 status = dcerpc_samr_Connect2(p, tctx, &r2);
5895 if (!NT_STATUS_IS_OK(status)) {
5896 torture_comment(tctx, "Connect2 failed - %s\n", nt_errstr(status));
5900 test_samr_handle_Close(p, tctx, handle);
5906 torture_comment(tctx, "testing samr_Connect3\n");
5908 r3.in.system_name = NULL;
5910 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5911 r3.out.connect_handle = &h;
5913 status = dcerpc_samr_Connect3(p, tctx, &r3);
5914 if (!NT_STATUS_IS_OK(status)) {
5915 printf("Connect3 failed - %s\n", nt_errstr(status));
5919 test_samr_handle_Close(p, tctx, handle);
5925 torture_comment(tctx, "testing samr_Connect4\n");
5927 r4.in.system_name = "";
5928 r4.in.client_version = 0;
5929 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5930 r4.out.connect_handle = &h;
5932 status = dcerpc_samr_Connect4(p, tctx, &r4);
5933 if (!NT_STATUS_IS_OK(status)) {
5934 printf("Connect4 failed - %s\n", nt_errstr(status));
5938 test_samr_handle_Close(p, tctx, handle);
5944 torture_comment(tctx, "testing samr_Connect5\n");
5946 info.info1.client_version = 0;
5947 info.info1.unknown2 = 0;
5949 r5.in.system_name = "";
5950 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5952 r5.out.level_out = &level_out;
5953 r5.in.info_in = &info;
5954 r5.out.info_out = &info;
5955 r5.out.connect_handle = &h;
5957 status = dcerpc_samr_Connect5(p, tctx, &r5);
5958 if (!NT_STATUS_IS_OK(status)) {
5959 printf("Connect5 failed - %s\n", nt_errstr(status));
5963 test_samr_handle_Close(p, tctx, handle);
5973 bool torture_rpc_samr(struct torture_context *torture)
5976 struct dcerpc_pipe *p;
5978 struct policy_handle handle;
5980 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
5981 if (!NT_STATUS_IS_OK(status)) {
5985 ret &= test_Connect(p, torture, &handle);
5987 ret &= test_QuerySecurity(p, torture, &handle);
5989 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_OTHER, NULL);
5991 ret &= test_SetDsrmPassword(p, torture, &handle);
5993 ret &= test_Shutdown(p, torture, &handle);
5995 ret &= test_samr_handle_Close(p, torture, &handle);
6001 bool torture_rpc_samr_users(struct torture_context *torture)
6004 struct dcerpc_pipe *p;
6006 struct policy_handle handle;
6008 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6009 if (!NT_STATUS_IS_OK(status)) {
6013 ret &= test_Connect(p, torture, &handle);
6015 ret &= test_QuerySecurity(p, torture, &handle);
6017 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_USER_ATTRIBUTES, NULL);
6019 ret &= test_SetDsrmPassword(p, torture, &handle);
6021 ret &= test_Shutdown(p, torture, &handle);
6023 ret &= test_samr_handle_Close(p, torture, &handle);
6029 bool torture_rpc_samr_passwords(struct torture_context *torture)
6032 struct dcerpc_pipe *p;
6034 struct policy_handle handle;
6036 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6037 if (!NT_STATUS_IS_OK(status)) {
6041 ret &= test_Connect(p, torture, &handle);
6043 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_PASSWORDS, NULL);
6045 ret &= test_samr_handle_Close(p, torture, &handle);
6050 static bool torture_rpc_samr_pwdlastset(struct torture_context *torture,
6051 struct dcerpc_pipe *p2,
6052 struct cli_credentials *machine_credentials)
6055 struct dcerpc_pipe *p;
6057 struct policy_handle handle;
6059 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6060 if (!NT_STATUS_IS_OK(status)) {
6064 ret &= test_Connect(p, torture, &handle);
6066 ret &= test_EnumDomains(p, torture, &handle,
6067 TORTURE_SAMR_PASSWORDS_PWDLASTSET,
6068 machine_credentials);
6070 ret &= test_samr_handle_Close(p, torture, &handle);
6075 struct torture_suite *torture_rpc_samr_passwords_pwdlastset(TALLOC_CTX *mem_ctx)
6077 struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-PASSWORDS-PWDLASTSET");
6078 struct torture_rpc_tcase *tcase;
6080 tcase = torture_suite_add_machine_rpc_iface_tcase(suite, "samr",
6082 TEST_ACCOUNT_NAME_PWD);
6084 torture_rpc_tcase_add_test_creds(tcase, "pwdLastSet",
6085 torture_rpc_samr_pwdlastset);