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_samr_c.h"
27 #include "lib/crypto/crypto.h"
28 #include "libcli/auth/libcli_auth.h"
29 #include "libcli/security/security.h"
30 #include "torture/rpc/rpc.h"
31 #include "param/param.h"
33 #define TEST_ACCOUNT_NAME "samrtorturetest"
34 #define TEST_ALIASNAME "samrtorturetestalias"
35 #define TEST_GROUPNAME "samrtorturetestgroup"
36 #define TEST_MACHINENAME "samrtestmach$"
37 #define TEST_DOMAINNAME "samrtestdom$"
39 enum torture_samr_choice {
40 TORTURE_SAMR_PASSWORDS,
41 TORTURE_SAMR_USER_ATTRIBUTES,
45 static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
46 struct policy_handle *handle);
48 static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
49 struct policy_handle *handle);
51 static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
52 struct policy_handle *handle);
54 static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
55 const char *acct_name,
56 struct policy_handle *domain_handle, char **password);
58 static void init_lsa_String(struct lsa_String *string, const char *s)
63 bool test_samr_handle_Close(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
64 struct policy_handle *handle)
70 r.out.handle = handle;
72 status = dcerpc_samr_Close(p, mem_ctx, &r);
73 if (!NT_STATUS_IS_OK(status)) {
74 printf("Close handle failed - %s\n", nt_errstr(status));
81 static bool test_Shutdown(struct dcerpc_pipe *p, struct torture_context *tctx,
82 struct policy_handle *handle)
85 struct samr_Shutdown r;
87 if (!torture_setting_bool(tctx, "dangerous", false)) {
88 printf("samr_Shutdown disabled - enable dangerous tests to use\n");
92 r.in.connect_handle = handle;
94 printf("testing samr_Shutdown\n");
96 status = dcerpc_samr_Shutdown(p, tctx, &r);
97 if (!NT_STATUS_IS_OK(status)) {
98 printf("samr_Shutdown failed - %s\n", nt_errstr(status));
105 static bool test_SetDsrmPassword(struct dcerpc_pipe *p, struct torture_context *tctx,
106 struct policy_handle *handle)
109 struct samr_SetDsrmPassword r;
110 struct lsa_String string;
111 struct samr_Password hash;
113 if (!torture_setting_bool(tctx, "dangerous", false)) {
114 printf("samr_SetDsrmPassword disabled - enable dangerous tests to use\n");
118 E_md4hash("TeSTDSRM123", hash.hash);
120 init_lsa_String(&string, "Administrator");
126 printf("testing samr_SetDsrmPassword\n");
128 status = dcerpc_samr_SetDsrmPassword(p, tctx, &r);
129 if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
130 printf("samr_SetDsrmPassword failed - %s\n", nt_errstr(status));
138 static bool test_QuerySecurity(struct dcerpc_pipe *p,
139 struct torture_context *tctx,
140 struct policy_handle *handle)
143 struct samr_QuerySecurity r;
144 struct samr_SetSecurity s;
146 r.in.handle = handle;
149 status = dcerpc_samr_QuerySecurity(p, tctx, &r);
150 if (!NT_STATUS_IS_OK(status)) {
151 printf("QuerySecurity failed - %s\n", nt_errstr(status));
155 if (r.out.sdbuf == NULL) {
159 s.in.handle = handle;
161 s.in.sdbuf = r.out.sdbuf;
163 if (torture_setting_bool(tctx, "samba4", false)) {
164 printf("skipping SetSecurity test against Samba4\n");
168 status = dcerpc_samr_SetSecurity(p, tctx, &s);
169 if (!NT_STATUS_IS_OK(status)) {
170 printf("SetSecurity failed - %s\n", nt_errstr(status));
174 status = dcerpc_samr_QuerySecurity(p, tctx, &r);
175 if (!NT_STATUS_IS_OK(status)) {
176 printf("QuerySecurity failed - %s\n", nt_errstr(status));
184 static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
185 struct policy_handle *handle, uint32_t base_acct_flags,
186 const char *base_account_name)
189 struct samr_SetUserInfo s;
190 struct samr_SetUserInfo2 s2;
191 struct samr_QueryUserInfo q;
192 struct samr_QueryUserInfo q0;
193 union samr_UserInfo u;
195 const char *test_account_name;
197 uint32_t user_extra_flags = 0;
198 if (base_acct_flags == ACB_NORMAL) {
199 /* When created, accounts are expired by default */
200 user_extra_flags = ACB_PW_EXPIRED;
203 s.in.user_handle = handle;
206 s2.in.user_handle = handle;
209 q.in.user_handle = handle;
213 #define TESTCALL(call, r) \
214 status = dcerpc_samr_ ##call(p, tctx, &r); \
215 if (!NT_STATUS_IS_OK(status)) { \
216 printf(#call " level %u failed - %s (%s)\n", \
217 r.in.level, nt_errstr(status), __location__); \
222 #define STRING_EQUAL(s1, s2, field) \
223 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
224 printf("Failed to set %s to '%s' (%s)\n", \
225 #field, s2, __location__); \
230 #define INT_EQUAL(i1, i2, field) \
232 printf("Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \
233 #field, (unsigned long long)i2, (unsigned long long)i1, __location__); \
238 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
239 printf("field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
241 TESTCALL(QueryUserInfo, q) \
243 s2.in.level = lvl1; \
246 ZERO_STRUCT(u.info21); \
247 u.info21.fields_present = fpval; \
249 init_lsa_String(&u.info ## lvl1.field1, value); \
250 TESTCALL(SetUserInfo, s) \
251 TESTCALL(SetUserInfo2, s2) \
252 init_lsa_String(&u.info ## lvl1.field1, ""); \
253 TESTCALL(QueryUserInfo, q); \
255 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
257 TESTCALL(QueryUserInfo, q) \
259 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
262 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
263 printf("field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
265 TESTCALL(QueryUserInfo, q) \
267 s2.in.level = lvl1; \
270 uint8_t *bits = u.info21.logon_hours.bits; \
271 ZERO_STRUCT(u.info21); \
272 if (fpval == SAMR_FIELD_LOGON_HOURS) { \
273 u.info21.logon_hours.units_per_week = 168; \
274 u.info21.logon_hours.bits = bits; \
276 u.info21.fields_present = fpval; \
278 u.info ## lvl1.field1 = value; \
279 TESTCALL(SetUserInfo, s) \
280 TESTCALL(SetUserInfo2, s2) \
281 u.info ## lvl1.field1 = 0; \
282 TESTCALL(QueryUserInfo, q); \
284 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
286 TESTCALL(QueryUserInfo, q) \
288 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
291 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
292 TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
296 do { TESTCALL(QueryUserInfo, q0) } while (0);
298 TEST_USERINFO_STRING(2, comment, 1, comment, "xx2-1 comment", 0);
299 TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
300 TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment",
303 test_account_name = talloc_asprintf(tctx, "%sxx7-1", base_account_name);
304 TEST_USERINFO_STRING(7, account_name, 1, account_name, base_account_name, 0);
305 test_account_name = talloc_asprintf(tctx, "%sxx7-3", base_account_name);
306 TEST_USERINFO_STRING(7, account_name, 3, account_name, base_account_name, 0);
307 test_account_name = talloc_asprintf(tctx, "%sxx7-5", base_account_name);
308 TEST_USERINFO_STRING(7, account_name, 5, account_name, base_account_name, 0);
309 test_account_name = talloc_asprintf(tctx, "%sxx7-6", base_account_name);
310 TEST_USERINFO_STRING(7, account_name, 6, account_name, base_account_name, 0);
311 test_account_name = talloc_asprintf(tctx, "%sxx7-7", base_account_name);
312 TEST_USERINFO_STRING(7, account_name, 7, account_name, base_account_name, 0);
313 test_account_name = talloc_asprintf(tctx, "%sxx7-21", base_account_name);
314 TEST_USERINFO_STRING(7, account_name, 21, account_name, base_account_name, 0);
315 test_account_name = base_account_name;
316 TEST_USERINFO_STRING(21, account_name, 21, account_name, base_account_name,
317 SAMR_FIELD_ACCOUNT_NAME);
319 TEST_USERINFO_STRING(6, full_name, 1, full_name, "xx6-1 full_name", 0);
320 TEST_USERINFO_STRING(6, full_name, 3, full_name, "xx6-3 full_name", 0);
321 TEST_USERINFO_STRING(6, full_name, 5, full_name, "xx6-5 full_name", 0);
322 TEST_USERINFO_STRING(6, full_name, 6, full_name, "xx6-6 full_name", 0);
323 TEST_USERINFO_STRING(6, full_name, 8, full_name, "xx6-8 full_name", 0);
324 TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
325 TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
326 TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name",
327 SAMR_FIELD_FULL_NAME);
329 TEST_USERINFO_STRING(6, full_name, 1, full_name, "", 0);
330 TEST_USERINFO_STRING(6, full_name, 3, full_name, "", 0);
331 TEST_USERINFO_STRING(6, full_name, 5, full_name, "", 0);
332 TEST_USERINFO_STRING(6, full_name, 6, full_name, "", 0);
333 TEST_USERINFO_STRING(6, full_name, 8, full_name, "", 0);
334 TEST_USERINFO_STRING(6, full_name, 21, full_name, "", 0);
335 TEST_USERINFO_STRING(8, full_name, 21, full_name, "", 0);
336 TEST_USERINFO_STRING(21, full_name, 21, full_name, "",
337 SAMR_FIELD_FULL_NAME);
339 TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
340 TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
341 TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
342 TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script",
343 SAMR_FIELD_LOGON_SCRIPT);
345 TEST_USERINFO_STRING(12, profile_path, 3, profile_path, "xx12-3 profile_path", 0);
346 TEST_USERINFO_STRING(12, profile_path, 5, profile_path, "xx12-5 profile_path", 0);
347 TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
348 TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path",
349 SAMR_FIELD_PROFILE_PATH);
351 TEST_USERINFO_STRING(10, home_directory, 3, home_directory, "xx10-3 home_directory", 0);
352 TEST_USERINFO_STRING(10, home_directory, 5, home_directory, "xx10-5 home_directory", 0);
353 TEST_USERINFO_STRING(10, home_directory, 21, home_directory, "xx10-21 home_directory", 0);
354 TEST_USERINFO_STRING(21, home_directory, 21, home_directory, "xx21-21 home_directory",
355 SAMR_FIELD_HOME_DIRECTORY);
356 TEST_USERINFO_STRING(21, home_directory, 10, home_directory, "xx21-10 home_directory",
357 SAMR_FIELD_HOME_DIRECTORY);
359 TEST_USERINFO_STRING(10, home_drive, 3, home_drive, "xx10-3 home_drive", 0);
360 TEST_USERINFO_STRING(10, home_drive, 5, home_drive, "xx10-5 home_drive", 0);
361 TEST_USERINFO_STRING(10, home_drive, 21, home_drive, "xx10-21 home_drive", 0);
362 TEST_USERINFO_STRING(21, home_drive, 21, home_drive, "xx21-21 home_drive",
363 SAMR_FIELD_HOME_DRIVE);
364 TEST_USERINFO_STRING(21, home_drive, 10, home_drive, "xx21-10 home_drive",
365 SAMR_FIELD_HOME_DRIVE);
367 TEST_USERINFO_STRING(13, description, 1, description, "xx13-1 description", 0);
368 TEST_USERINFO_STRING(13, description, 5, description, "xx13-5 description", 0);
369 TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
370 TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description",
371 SAMR_FIELD_DESCRIPTION);
373 TEST_USERINFO_STRING(14, workstations, 3, workstations, "14workstation3", 0);
374 TEST_USERINFO_STRING(14, workstations, 5, workstations, "14workstation4", 0);
375 TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
376 TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21",
377 SAMR_FIELD_WORKSTATIONS);
378 TEST_USERINFO_STRING(21, workstations, 3, workstations, "21workstation3",
379 SAMR_FIELD_WORKSTATIONS);
380 TEST_USERINFO_STRING(21, workstations, 5, workstations, "21workstation5",
381 SAMR_FIELD_WORKSTATIONS);
382 TEST_USERINFO_STRING(21, workstations, 14, workstations, "21workstation14",
383 SAMR_FIELD_WORKSTATIONS);
385 TEST_USERINFO_STRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
386 TEST_USERINFO_STRING(21, parameters, 21, parameters, "xx21-21 parameters",
387 SAMR_FIELD_PARAMETERS);
388 TEST_USERINFO_STRING(21, parameters, 20, parameters, "xx21-20 parameters",
389 SAMR_FIELD_PARAMETERS);
391 TEST_USERINFO_INT(2, country_code, 2, country_code, __LINE__, 0);
392 TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
393 TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__,
394 SAMR_FIELD_COUNTRY_CODE);
395 TEST_USERINFO_INT(21, country_code, 2, country_code, __LINE__,
396 SAMR_FIELD_COUNTRY_CODE);
398 TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
399 TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__,
400 SAMR_FIELD_CODE_PAGE);
401 TEST_USERINFO_INT(21, code_page, 2, code_page, __LINE__,
402 SAMR_FIELD_CODE_PAGE);
404 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, __LINE__, 0);
405 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, __LINE__, 0);
406 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, __LINE__,
407 SAMR_FIELD_ACCT_EXPIRY);
408 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, __LINE__,
409 SAMR_FIELD_ACCT_EXPIRY);
410 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, __LINE__,
411 SAMR_FIELD_ACCT_EXPIRY);
413 TEST_USERINFO_INT(4, logon_hours.bits[3], 3, logon_hours.bits[3], 1, 0);
414 TEST_USERINFO_INT(4, logon_hours.bits[3], 5, logon_hours.bits[3], 2, 0);
415 TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
416 TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4,
417 SAMR_FIELD_LOGON_HOURS);
419 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
420 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
421 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
423 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
424 (base_acct_flags | ACB_DISABLED),
425 (base_acct_flags | ACB_DISABLED | user_extra_flags),
428 /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
429 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
430 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
431 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
433 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
434 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
435 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
439 /* The 'autolock' flag doesn't stick - check this */
440 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
441 (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK),
442 (base_acct_flags | ACB_DISABLED | user_extra_flags),
445 /* Removing the 'disabled' flag doesn't stick - check this */
446 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
448 (base_acct_flags | ACB_DISABLED | user_extra_flags),
451 /* The 'store plaintext' flag does stick */
452 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
453 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED),
454 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags),
456 /* The 'use DES' flag does stick */
457 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
458 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY),
459 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags),
461 /* The 'don't require kerberos pre-authentication flag does stick */
462 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
463 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH),
464 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags),
466 /* The 'no kerberos PAC required' flag sticks */
467 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
468 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD),
469 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags),
472 TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags,
473 (base_acct_flags | ACB_DISABLED),
474 (base_acct_flags | ACB_DISABLED | user_extra_flags),
475 SAMR_FIELD_ACCT_FLAGS);
478 /* these fail with win2003 - it appears you can't set the primary gid?
479 the set succeeds, but the gid isn't changed. Very weird! */
480 TEST_USERINFO_INT(9, primary_gid, 1, primary_gid, 513);
481 TEST_USERINFO_INT(9, primary_gid, 3, primary_gid, 513);
482 TEST_USERINFO_INT(9, primary_gid, 5, primary_gid, 513);
483 TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
490 generate a random password for password change tests
492 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
494 size_t len = MAX(8, min_len) + (random() % 6);
495 char *s = generate_random_str(mem_ctx, len);
496 printf("Generated password '%s'\n", s);
501 generate a random password for password change tests (fixed length)
503 static char *samr_rand_pass_fixed_len(TALLOC_CTX *mem_ctx, int len)
505 char *s = generate_random_str(mem_ctx, len);
506 printf("Generated password '%s'\n", s);
510 static bool test_SetUserPass(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
511 struct policy_handle *handle, char **password)
514 struct samr_SetUserInfo s;
515 union samr_UserInfo u;
517 DATA_BLOB session_key;
519 struct samr_GetUserPwInfo pwp;
520 int policy_min_pw_len = 0;
521 pwp.in.user_handle = handle;
523 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
524 if (NT_STATUS_IS_OK(status)) {
525 policy_min_pw_len = pwp.out.info.min_password_length;
527 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
529 s.in.user_handle = handle;
533 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
534 /* w2k3 ignores this length */
535 u.info24.pw_len = strlen_m(newpass) * 2;
537 status = dcerpc_fetch_session_key(p, &session_key);
538 if (!NT_STATUS_IS_OK(status)) {
539 printf("SetUserInfo level %u - no session key - %s\n",
540 s.in.level, nt_errstr(status));
544 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
546 printf("Testing SetUserInfo level 24 (set password)\n");
548 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
549 if (!NT_STATUS_IS_OK(status)) {
550 printf("SetUserInfo level %u failed - %s\n",
551 s.in.level, nt_errstr(status));
561 static bool test_SetUserPass_23(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
562 struct policy_handle *handle, uint32_t fields_present,
566 struct samr_SetUserInfo s;
567 union samr_UserInfo u;
569 DATA_BLOB session_key;
571 struct samr_GetUserPwInfo pwp;
572 int policy_min_pw_len = 0;
573 pwp.in.user_handle = handle;
575 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
576 if (NT_STATUS_IS_OK(status)) {
577 policy_min_pw_len = pwp.out.info.min_password_length;
579 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
581 s.in.user_handle = handle;
587 u.info23.info.fields_present = fields_present;
589 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
591 status = dcerpc_fetch_session_key(p, &session_key);
592 if (!NT_STATUS_IS_OK(status)) {
593 printf("SetUserInfo level %u - no session key - %s\n",
594 s.in.level, nt_errstr(status));
598 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
600 printf("Testing SetUserInfo level 23 (set password)\n");
602 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
603 if (!NT_STATUS_IS_OK(status)) {
604 printf("SetUserInfo level %u failed - %s\n",
605 s.in.level, nt_errstr(status));
611 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
613 status = dcerpc_fetch_session_key(p, &session_key);
614 if (!NT_STATUS_IS_OK(status)) {
615 printf("SetUserInfo level %u - no session key - %s\n",
616 s.in.level, nt_errstr(status));
620 /* This should break the key nicely */
621 session_key.length--;
622 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
624 printf("Testing SetUserInfo level 23 (set password) with wrong password\n");
626 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
627 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
628 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
629 s.in.level, nt_errstr(status));
637 static bool test_SetUserPassEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
638 struct policy_handle *handle, bool makeshort,
642 struct samr_SetUserInfo s;
643 union samr_UserInfo u;
645 DATA_BLOB session_key;
646 DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
647 uint8_t confounder[16];
649 struct MD5Context ctx;
650 struct samr_GetUserPwInfo pwp;
651 int policy_min_pw_len = 0;
652 pwp.in.user_handle = handle;
654 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
655 if (NT_STATUS_IS_OK(status)) {
656 policy_min_pw_len = pwp.out.info.min_password_length;
658 if (makeshort && policy_min_pw_len) {
659 newpass = samr_rand_pass_fixed_len(mem_ctx, policy_min_pw_len - 1);
661 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
664 s.in.user_handle = handle;
668 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
669 u.info26.pw_len = strlen(newpass);
671 status = dcerpc_fetch_session_key(p, &session_key);
672 if (!NT_STATUS_IS_OK(status)) {
673 printf("SetUserInfo level %u - no session key - %s\n",
674 s.in.level, nt_errstr(status));
678 generate_random_buffer((uint8_t *)confounder, 16);
681 MD5Update(&ctx, confounder, 16);
682 MD5Update(&ctx, session_key.data, session_key.length);
683 MD5Final(confounded_session_key.data, &ctx);
685 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
686 memcpy(&u.info26.password.data[516], confounder, 16);
688 printf("Testing SetUserInfo level 26 (set password ex)\n");
690 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
691 if (!NT_STATUS_IS_OK(status)) {
692 printf("SetUserInfo level %u failed - %s\n",
693 s.in.level, nt_errstr(status));
699 /* This should break the key nicely */
700 confounded_session_key.data[0]++;
702 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
703 memcpy(&u.info26.password.data[516], confounder, 16);
705 printf("Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
707 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
708 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
709 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
710 s.in.level, nt_errstr(status));
719 static bool test_SetUserPass_25(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
720 struct policy_handle *handle, uint32_t fields_present,
724 struct samr_SetUserInfo s;
725 union samr_UserInfo u;
727 DATA_BLOB session_key;
728 DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
729 struct MD5Context ctx;
730 uint8_t confounder[16];
732 struct samr_GetUserPwInfo pwp;
733 int policy_min_pw_len = 0;
734 pwp.in.user_handle = handle;
736 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
737 if (NT_STATUS_IS_OK(status)) {
738 policy_min_pw_len = pwp.out.info.min_password_length;
740 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
742 s.in.user_handle = handle;
748 u.info25.info.fields_present = fields_present;
750 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
752 status = dcerpc_fetch_session_key(p, &session_key);
753 if (!NT_STATUS_IS_OK(status)) {
754 printf("SetUserInfo level %u - no session key - %s\n",
755 s.in.level, nt_errstr(status));
759 generate_random_buffer((uint8_t *)confounder, 16);
762 MD5Update(&ctx, confounder, 16);
763 MD5Update(&ctx, session_key.data, session_key.length);
764 MD5Final(confounded_session_key.data, &ctx);
766 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
767 memcpy(&u.info25.password.data[516], confounder, 16);
769 printf("Testing SetUserInfo level 25 (set password ex)\n");
771 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
772 if (!NT_STATUS_IS_OK(status)) {
773 printf("SetUserInfo level %u failed - %s\n",
774 s.in.level, nt_errstr(status));
780 /* This should break the key nicely */
781 confounded_session_key.data[0]++;
783 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
784 memcpy(&u.info25.password.data[516], confounder, 16);
786 printf("Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
788 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
789 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
790 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
791 s.in.level, nt_errstr(status));
798 static bool test_SetAliasInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
799 struct policy_handle *handle)
802 struct samr_SetAliasInfo r;
803 struct samr_QueryAliasInfo q;
804 uint16_t levels[] = {2, 3};
808 /* Ignoring switch level 1, as that includes the number of members for the alias
809 * and setting this to a wrong value might have negative consequences
812 for (i=0;i<ARRAY_SIZE(levels);i++) {
813 printf("Testing SetAliasInfo level %u\n", levels[i]);
815 r.in.alias_handle = handle;
816 r.in.level = levels[i];
817 r.in.info = talloc(tctx, union samr_AliasInfo);
818 switch (r.in.level) {
819 case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
820 case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
821 "Test Description, should test I18N as well"); break;
822 case ALIASINFOALL: printf("ALIASINFOALL ignored\n"); break;
825 status = dcerpc_samr_SetAliasInfo(p, tctx, &r);
826 if (!NT_STATUS_IS_OK(status)) {
827 printf("SetAliasInfo level %u failed - %s\n",
828 levels[i], nt_errstr(status));
832 q.in.alias_handle = handle;
833 q.in.level = levels[i];
835 status = dcerpc_samr_QueryAliasInfo(p, tctx, &q);
836 if (!NT_STATUS_IS_OK(status)) {
837 printf("QueryAliasInfo level %u failed - %s\n",
838 levels[i], nt_errstr(status));
846 static bool test_GetGroupsForUser(struct dcerpc_pipe *p, struct torture_context *tctx,
847 struct policy_handle *user_handle)
849 struct samr_GetGroupsForUser r;
853 printf("testing GetGroupsForUser\n");
855 r.in.user_handle = user_handle;
857 status = dcerpc_samr_GetGroupsForUser(p, tctx, &r);
858 if (!NT_STATUS_IS_OK(status)) {
859 printf("GetGroupsForUser failed - %s\n",nt_errstr(status));
867 static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
868 struct lsa_String *domain_name)
871 struct samr_GetDomPwInfo r;
874 r.in.domain_name = domain_name;
875 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
877 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
878 if (!NT_STATUS_IS_OK(status)) {
879 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
883 r.in.domain_name->string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
884 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
886 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
887 if (!NT_STATUS_IS_OK(status)) {
888 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
892 r.in.domain_name->string = "\\\\__NONAME__";
893 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
895 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
896 if (!NT_STATUS_IS_OK(status)) {
897 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
901 r.in.domain_name->string = "\\\\Builtin";
902 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
904 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
905 if (!NT_STATUS_IS_OK(status)) {
906 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
914 static bool test_GetUserPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
915 struct policy_handle *handle)
918 struct samr_GetUserPwInfo r;
921 printf("Testing GetUserPwInfo\n");
923 r.in.user_handle = handle;
925 status = dcerpc_samr_GetUserPwInfo(p, tctx, &r);
926 if (!NT_STATUS_IS_OK(status)) {
927 printf("GetUserPwInfo failed - %s\n", nt_errstr(status));
934 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, struct torture_context *tctx,
935 struct policy_handle *domain_handle, const char *name,
939 struct samr_LookupNames n;
940 struct lsa_String sname[2];
942 init_lsa_String(&sname[0], name);
944 n.in.domain_handle = domain_handle;
947 status = dcerpc_samr_LookupNames(p, tctx, &n);
948 if (NT_STATUS_IS_OK(status)) {
949 *rid = n.out.rids.ids[0];
954 init_lsa_String(&sname[1], "xxNONAMExx");
956 status = dcerpc_samr_LookupNames(p, tctx, &n);
957 if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
958 printf("LookupNames[2] failed - %s\n", nt_errstr(status));
959 if (NT_STATUS_IS_OK(status)) {
960 return NT_STATUS_UNSUCCESSFUL;
966 status = dcerpc_samr_LookupNames(p, tctx, &n);
967 if (!NT_STATUS_IS_OK(status)) {
968 printf("LookupNames[0] failed - %s\n", nt_errstr(status));
972 init_lsa_String(&sname[0], "xxNONAMExx");
974 status = dcerpc_samr_LookupNames(p, tctx, &n);
975 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
976 printf("LookupNames[1 bad name] failed - %s\n", nt_errstr(status));
977 if (NT_STATUS_IS_OK(status)) {
978 return NT_STATUS_UNSUCCESSFUL;
983 init_lsa_String(&sname[0], "xxNONAMExx");
984 init_lsa_String(&sname[1], "xxNONAME2xx");
986 status = dcerpc_samr_LookupNames(p, tctx, &n);
987 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
988 printf("LookupNames[2 bad names] failed - %s\n", nt_errstr(status));
989 if (NT_STATUS_IS_OK(status)) {
990 return NT_STATUS_UNSUCCESSFUL;
998 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
999 struct policy_handle *domain_handle,
1000 const char *name, struct policy_handle *user_handle)
1003 struct samr_OpenUser r;
1006 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
1007 if (!NT_STATUS_IS_OK(status)) {
1011 r.in.domain_handle = domain_handle;
1012 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1014 r.out.user_handle = user_handle;
1015 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
1016 if (!NT_STATUS_IS_OK(status)) {
1017 printf("OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(status));
1024 static bool test_ChangePasswordNT3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1025 struct policy_handle *handle)
1028 struct samr_ChangePasswordUser r;
1030 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1031 struct policy_handle user_handle;
1032 char *oldpass = "test";
1033 char *newpass = "test2";
1034 uint8_t old_nt_hash[16], new_nt_hash[16];
1035 uint8_t old_lm_hash[16], new_lm_hash[16];
1037 status = test_OpenUser_byname(p, mem_ctx, handle, "testuser", &user_handle);
1038 if (!NT_STATUS_IS_OK(status)) {
1042 printf("Testing ChangePasswordUser for user 'testuser'\n");
1044 printf("old password: %s\n", oldpass);
1045 printf("new password: %s\n", newpass);
1047 E_md4hash(oldpass, old_nt_hash);
1048 E_md4hash(newpass, new_nt_hash);
1049 E_deshash(oldpass, old_lm_hash);
1050 E_deshash(newpass, new_lm_hash);
1052 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1053 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1054 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1055 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1056 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1057 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1059 r.in.handle = &user_handle;
1060 r.in.lm_present = 1;
1061 r.in.old_lm_crypted = &hash1;
1062 r.in.new_lm_crypted = &hash2;
1063 r.in.nt_present = 1;
1064 r.in.old_nt_crypted = &hash3;
1065 r.in.new_nt_crypted = &hash4;
1066 r.in.cross1_present = 1;
1067 r.in.nt_cross = &hash5;
1068 r.in.cross2_present = 1;
1069 r.in.lm_cross = &hash6;
1071 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1072 if (!NT_STATUS_IS_OK(status)) {
1073 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1077 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1085 static bool test_ChangePasswordUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1086 const char *acct_name,
1087 struct policy_handle *handle, char **password)
1090 struct samr_ChangePasswordUser r;
1092 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1093 struct policy_handle user_handle;
1095 uint8_t old_nt_hash[16], new_nt_hash[16];
1096 uint8_t old_lm_hash[16], new_lm_hash[16];
1097 bool changed = true;
1100 struct samr_GetUserPwInfo pwp;
1101 int policy_min_pw_len = 0;
1103 status = test_OpenUser_byname(p, mem_ctx, handle, acct_name, &user_handle);
1104 if (!NT_STATUS_IS_OK(status)) {
1107 pwp.in.user_handle = &user_handle;
1109 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
1110 if (NT_STATUS_IS_OK(status)) {
1111 policy_min_pw_len = pwp.out.info.min_password_length;
1113 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1115 printf("Testing ChangePasswordUser\n");
1118 printf("Failing ChangePasswordUser as old password was NULL. Previous test failed?\n");
1122 oldpass = *password;
1124 E_md4hash(oldpass, old_nt_hash);
1125 E_md4hash(newpass, new_nt_hash);
1126 E_deshash(oldpass, old_lm_hash);
1127 E_deshash(newpass, new_lm_hash);
1129 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1130 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1131 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1132 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1133 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1134 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1136 r.in.user_handle = &user_handle;
1137 r.in.lm_present = 1;
1138 /* Break the LM hash */
1140 r.in.old_lm_crypted = &hash1;
1141 r.in.new_lm_crypted = &hash2;
1142 r.in.nt_present = 1;
1143 r.in.old_nt_crypted = &hash3;
1144 r.in.new_nt_crypted = &hash4;
1145 r.in.cross1_present = 1;
1146 r.in.nt_cross = &hash5;
1147 r.in.cross2_present = 1;
1148 r.in.lm_cross = &hash6;
1150 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1151 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1152 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash, got %s\n", nt_errstr(status));
1156 /* Unbreak the LM hash */
1159 r.in.user_handle = &user_handle;
1160 r.in.lm_present = 1;
1161 r.in.old_lm_crypted = &hash1;
1162 r.in.new_lm_crypted = &hash2;
1163 /* Break the NT hash */
1165 r.in.nt_present = 1;
1166 r.in.old_nt_crypted = &hash3;
1167 r.in.new_nt_crypted = &hash4;
1168 r.in.cross1_present = 1;
1169 r.in.nt_cross = &hash5;
1170 r.in.cross2_present = 1;
1171 r.in.lm_cross = &hash6;
1173 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1174 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1175 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash, got %s\n", nt_errstr(status));
1179 /* Unbreak the NT hash */
1182 r.in.user_handle = &user_handle;
1183 r.in.lm_present = 1;
1184 r.in.old_lm_crypted = &hash1;
1185 r.in.new_lm_crypted = &hash2;
1186 r.in.nt_present = 1;
1187 r.in.old_nt_crypted = &hash3;
1188 r.in.new_nt_crypted = &hash4;
1189 r.in.cross1_present = 1;
1190 r.in.nt_cross = &hash5;
1191 r.in.cross2_present = 1;
1192 /* Break the LM cross */
1194 r.in.lm_cross = &hash6;
1196 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1197 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1198 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status));
1202 /* Unbreak the LM cross */
1205 r.in.user_handle = &user_handle;
1206 r.in.lm_present = 1;
1207 r.in.old_lm_crypted = &hash1;
1208 r.in.new_lm_crypted = &hash2;
1209 r.in.nt_present = 1;
1210 r.in.old_nt_crypted = &hash3;
1211 r.in.new_nt_crypted = &hash4;
1212 r.in.cross1_present = 1;
1213 /* Break the NT cross */
1215 r.in.nt_cross = &hash5;
1216 r.in.cross2_present = 1;
1217 r.in.lm_cross = &hash6;
1219 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1220 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1221 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status));
1225 /* Unbreak the NT cross */
1229 /* Reset the hashes to not broken values */
1230 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1231 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1232 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1233 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1234 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1235 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1237 r.in.user_handle = &user_handle;
1238 r.in.lm_present = 1;
1239 r.in.old_lm_crypted = &hash1;
1240 r.in.new_lm_crypted = &hash2;
1241 r.in.nt_present = 1;
1242 r.in.old_nt_crypted = &hash3;
1243 r.in.new_nt_crypted = &hash4;
1244 r.in.cross1_present = 1;
1245 r.in.nt_cross = &hash5;
1246 r.in.cross2_present = 0;
1247 r.in.lm_cross = NULL;
1249 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1250 if (NT_STATUS_IS_OK(status)) {
1252 *password = newpass;
1253 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1254 printf("ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(status));
1259 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1261 E_md4hash(oldpass, old_nt_hash);
1262 E_md4hash(newpass, new_nt_hash);
1263 E_deshash(oldpass, old_lm_hash);
1264 E_deshash(newpass, new_lm_hash);
1267 /* Reset the hashes to not broken values */
1268 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1269 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1270 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1271 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1272 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1273 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1275 r.in.user_handle = &user_handle;
1276 r.in.lm_present = 1;
1277 r.in.old_lm_crypted = &hash1;
1278 r.in.new_lm_crypted = &hash2;
1279 r.in.nt_present = 1;
1280 r.in.old_nt_crypted = &hash3;
1281 r.in.new_nt_crypted = &hash4;
1282 r.in.cross1_present = 0;
1283 r.in.nt_cross = NULL;
1284 r.in.cross2_present = 1;
1285 r.in.lm_cross = &hash6;
1287 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1288 if (NT_STATUS_IS_OK(status)) {
1290 *password = newpass;
1291 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1292 printf("ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status));
1297 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1299 E_md4hash(oldpass, old_nt_hash);
1300 E_md4hash(newpass, new_nt_hash);
1301 E_deshash(oldpass, old_lm_hash);
1302 E_deshash(newpass, new_lm_hash);
1305 /* Reset the hashes to not broken values */
1306 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1307 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1308 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1309 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1310 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1311 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1313 r.in.user_handle = &user_handle;
1314 r.in.lm_present = 1;
1315 r.in.old_lm_crypted = &hash1;
1316 r.in.new_lm_crypted = &hash2;
1317 r.in.nt_present = 1;
1318 r.in.old_nt_crypted = &hash3;
1319 r.in.new_nt_crypted = &hash4;
1320 r.in.cross1_present = 1;
1321 r.in.nt_cross = &hash5;
1322 r.in.cross2_present = 1;
1323 r.in.lm_cross = &hash6;
1325 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1326 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1327 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1328 } else if (!NT_STATUS_IS_OK(status)) {
1329 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1333 *password = newpass;
1336 r.in.user_handle = &user_handle;
1337 r.in.lm_present = 1;
1338 r.in.old_lm_crypted = &hash1;
1339 r.in.new_lm_crypted = &hash2;
1340 r.in.nt_present = 1;
1341 r.in.old_nt_crypted = &hash3;
1342 r.in.new_nt_crypted = &hash4;
1343 r.in.cross1_present = 1;
1344 r.in.nt_cross = &hash5;
1345 r.in.cross2_present = 1;
1346 r.in.lm_cross = &hash6;
1349 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1350 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1351 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1352 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1353 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status));
1359 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1367 static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1368 const char *acct_name,
1369 struct policy_handle *handle, char **password)
1372 struct samr_OemChangePasswordUser2 r;
1374 struct samr_Password lm_verifier;
1375 struct samr_CryptPassword lm_pass;
1376 struct lsa_AsciiString server, account, account_bad;
1379 uint8_t old_lm_hash[16], new_lm_hash[16];
1381 struct samr_GetDomPwInfo dom_pw_info;
1382 int policy_min_pw_len = 0;
1384 struct lsa_String domain_name;
1386 domain_name.string = "";
1387 dom_pw_info.in.domain_name = &domain_name;
1389 printf("Testing OemChangePasswordUser2\n");
1392 printf("Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?\n");
1396 oldpass = *password;
1398 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &dom_pw_info);
1399 if (NT_STATUS_IS_OK(status)) {
1400 policy_min_pw_len = dom_pw_info.out.info.min_password_length;
1403 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1405 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1406 account.string = acct_name;
1408 E_deshash(oldpass, old_lm_hash);
1409 E_deshash(newpass, new_lm_hash);
1411 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1412 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1413 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1415 r.in.server = &server;
1416 r.in.account = &account;
1417 r.in.password = &lm_pass;
1418 r.in.hash = &lm_verifier;
1420 /* Break the verification */
1421 lm_verifier.hash[0]++;
1423 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1425 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1426 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1427 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1432 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1433 /* Break the old password */
1435 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1436 /* unbreak it for the next operation */
1438 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1440 r.in.server = &server;
1441 r.in.account = &account;
1442 r.in.password = &lm_pass;
1443 r.in.hash = &lm_verifier;
1445 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1447 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1448 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1449 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1454 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1455 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1457 r.in.server = &server;
1458 r.in.account = &account;
1459 r.in.password = &lm_pass;
1462 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1464 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1465 && !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1466 printf("ChangePasswordUser3 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
1471 /* This shouldn't be a valid name */
1472 account_bad.string = TEST_ACCOUNT_NAME "XX";
1473 r.in.account = &account_bad;
1475 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1477 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1478 printf("ChangePasswordUser3 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
1483 /* This shouldn't be a valid name */
1484 account_bad.string = TEST_ACCOUNT_NAME "XX";
1485 r.in.account = &account_bad;
1486 r.in.password = &lm_pass;
1487 r.in.hash = &lm_verifier;
1489 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1491 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1492 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1497 /* This shouldn't be a valid name */
1498 account_bad.string = TEST_ACCOUNT_NAME "XX";
1499 r.in.account = &account_bad;
1500 r.in.password = NULL;
1501 r.in.hash = &lm_verifier;
1503 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1505 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1506 printf("ChangePasswordUser3 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
1511 E_deshash(oldpass, old_lm_hash);
1512 E_deshash(newpass, new_lm_hash);
1514 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1515 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1516 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1518 r.in.server = &server;
1519 r.in.account = &account;
1520 r.in.password = &lm_pass;
1521 r.in.hash = &lm_verifier;
1523 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1524 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1525 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1526 } else if (!NT_STATUS_IS_OK(status)) {
1527 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
1530 *password = newpass;
1537 static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1538 const char *acct_name,
1540 char *newpass, bool allow_password_restriction)
1543 struct samr_ChangePasswordUser2 r;
1545 struct lsa_String server, account;
1546 struct samr_CryptPassword nt_pass, lm_pass;
1547 struct samr_Password nt_verifier, lm_verifier;
1549 uint8_t old_nt_hash[16], new_nt_hash[16];
1550 uint8_t old_lm_hash[16], new_lm_hash[16];
1552 struct samr_GetDomPwInfo dom_pw_info;
1554 struct lsa_String domain_name;
1556 domain_name.string = "";
1557 dom_pw_info.in.domain_name = &domain_name;
1559 printf("Testing ChangePasswordUser2 on %s\n", acct_name);
1562 printf("Failing ChangePasswordUser3 as old password was NULL. Previous test failed?\n");
1565 oldpass = *password;
1568 int policy_min_pw_len = 0;
1569 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &dom_pw_info);
1570 if (NT_STATUS_IS_OK(status)) {
1571 policy_min_pw_len = dom_pw_info.out.info.min_password_length;
1574 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1577 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1578 init_lsa_String(&account, acct_name);
1580 E_md4hash(oldpass, old_nt_hash);
1581 E_md4hash(newpass, new_nt_hash);
1583 E_deshash(oldpass, old_lm_hash);
1584 E_deshash(newpass, new_lm_hash);
1586 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
1587 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1588 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1590 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1591 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1592 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1594 r.in.server = &server;
1595 r.in.account = &account;
1596 r.in.nt_password = &nt_pass;
1597 r.in.nt_verifier = &nt_verifier;
1599 r.in.lm_password = &lm_pass;
1600 r.in.lm_verifier = &lm_verifier;
1602 status = dcerpc_samr_ChangePasswordUser2(p, mem_ctx, &r);
1603 if (allow_password_restriction && NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1604 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1605 } else if (!NT_STATUS_IS_OK(status)) {
1606 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
1609 *password = newpass;
1616 bool test_ChangePasswordUser3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1617 const char *account_string,
1618 int policy_min_pw_len,
1620 const char *newpass,
1621 NTTIME last_password_change,
1622 bool handle_reject_reason)
1625 struct samr_ChangePasswordUser3 r;
1627 struct lsa_String server, account, account_bad;
1628 struct samr_CryptPassword nt_pass, lm_pass;
1629 struct samr_Password nt_verifier, lm_verifier;
1631 uint8_t old_nt_hash[16], new_nt_hash[16];
1632 uint8_t old_lm_hash[16], new_lm_hash[16];
1635 printf("Testing ChangePasswordUser3\n");
1637 if (newpass == NULL) {
1639 if (policy_min_pw_len == 0) {
1640 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1642 newpass = samr_rand_pass_fixed_len(mem_ctx, policy_min_pw_len);
1644 } while (check_password_quality(newpass) == false);
1646 printf("Using password '%s'\n", newpass);
1650 printf("Failing ChangePasswordUser3 as old password was NULL. Previous test failed?\n");
1654 oldpass = *password;
1655 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1656 init_lsa_String(&account, account_string);
1658 E_md4hash(oldpass, old_nt_hash);
1659 E_md4hash(newpass, new_nt_hash);
1661 E_deshash(oldpass, old_lm_hash);
1662 E_deshash(newpass, new_lm_hash);
1664 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1665 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1666 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1668 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1669 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1670 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1672 /* Break the verification */
1673 nt_verifier.hash[0]++;
1675 r.in.server = &server;
1676 r.in.account = &account;
1677 r.in.nt_password = &nt_pass;
1678 r.in.nt_verifier = &nt_verifier;
1680 r.in.lm_password = &lm_pass;
1681 r.in.lm_verifier = &lm_verifier;
1682 r.in.password3 = NULL;
1684 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1685 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1686 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1687 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1692 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1693 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1694 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1696 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1697 /* Break the NT hash */
1699 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1700 /* Unbreak it again */
1702 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1704 r.in.server = &server;
1705 r.in.account = &account;
1706 r.in.nt_password = &nt_pass;
1707 r.in.nt_verifier = &nt_verifier;
1709 r.in.lm_password = &lm_pass;
1710 r.in.lm_verifier = &lm_verifier;
1711 r.in.password3 = NULL;
1713 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1714 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1715 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1716 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1721 /* This shouldn't be a valid name */
1722 init_lsa_String(&account_bad, talloc_asprintf(mem_ctx, "%sXX", account_string));
1724 r.in.account = &account_bad;
1725 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1726 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1727 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
1732 E_md4hash(oldpass, old_nt_hash);
1733 E_md4hash(newpass, new_nt_hash);
1735 E_deshash(oldpass, old_lm_hash);
1736 E_deshash(newpass, new_lm_hash);
1738 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1739 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1740 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1742 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1743 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1744 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1746 r.in.server = &server;
1747 r.in.account = &account;
1748 r.in.nt_password = &nt_pass;
1749 r.in.nt_verifier = &nt_verifier;
1751 r.in.lm_password = &lm_pass;
1752 r.in.lm_verifier = &lm_verifier;
1753 r.in.password3 = NULL;
1755 unix_to_nt_time(&t, time(NULL));
1757 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1759 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1762 && handle_reject_reason
1763 && (!null_nttime(last_password_change) || !r.out.dominfo->min_password_age)) {
1764 if (r.out.dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
1766 if (r.out.reject && (r.out.reject->reason != SAMR_REJECT_OTHER)) {
1767 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1768 SAMR_REJECT_OTHER, r.out.reject->reason);
1773 /* We tested the order of precendence which is as follows:
1782 if ((r.out.dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
1783 (last_password_change + r.out.dominfo->min_password_age > t)) {
1785 if (r.out.reject->reason != SAMR_REJECT_OTHER) {
1786 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1787 SAMR_REJECT_OTHER, r.out.reject->reason);
1791 } else if ((r.out.dominfo->min_password_length > 0) &&
1792 (strlen(newpass) < r.out.dominfo->min_password_length)) {
1794 if (r.out.reject->reason != SAMR_REJECT_TOO_SHORT) {
1795 printf("expected SAMR_REJECT_TOO_SHORT (%d), got %d\n",
1796 SAMR_REJECT_TOO_SHORT, r.out.reject->reason);
1800 } else if ((r.out.dominfo->password_history_length > 0) &&
1801 strequal(oldpass, newpass)) {
1803 if (r.out.reject->reason != SAMR_REJECT_IN_HISTORY) {
1804 printf("expected SAMR_REJECT_IN_HISTORY (%d), got %d\n",
1805 SAMR_REJECT_IN_HISTORY, r.out.reject->reason);
1808 } else if (r.out.dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
1810 if (r.out.reject->reason != SAMR_REJECT_COMPLEXITY) {
1811 printf("expected SAMR_REJECT_COMPLEXITY (%d), got %d\n",
1812 SAMR_REJECT_COMPLEXITY, r.out.reject->reason);
1818 if (r.out.reject->reason == SAMR_REJECT_TOO_SHORT) {
1819 /* retry with adjusted size */
1820 return test_ChangePasswordUser3(p, mem_ctx, account_string,
1821 r.out.dominfo->min_password_length,
1822 password, NULL, 0, false);
1826 } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1827 if (r.out.reject && r.out.reject->reason != SAMR_REJECT_OTHER) {
1828 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1829 SAMR_REJECT_OTHER, r.out.reject->reason);
1832 /* Perhaps the server has a 'min password age' set? */
1834 } else if (!NT_STATUS_IS_OK(status)) {
1835 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
1838 *password = talloc_strdup(mem_ctx, newpass);
1845 static bool test_GetMembersInAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1846 struct policy_handle *alias_handle)
1848 struct samr_GetMembersInAlias r;
1849 struct lsa_SidArray sids;
1853 printf("Testing GetMembersInAlias\n");
1855 r.in.alias_handle = alias_handle;
1858 status = dcerpc_samr_GetMembersInAlias(p, mem_ctx, &r);
1859 if (!NT_STATUS_IS_OK(status)) {
1860 printf("GetMembersInAlias failed - %s\n",
1868 static bool test_AddMemberToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1869 struct policy_handle *alias_handle,
1870 const struct dom_sid *domain_sid)
1872 struct samr_AddAliasMember r;
1873 struct samr_DeleteAliasMember d;
1876 struct dom_sid *sid;
1878 sid = dom_sid_add_rid(mem_ctx, domain_sid, 512);
1880 printf("testing AddAliasMember\n");
1881 r.in.alias_handle = alias_handle;
1884 status = dcerpc_samr_AddAliasMember(p, mem_ctx, &r);
1885 if (!NT_STATUS_IS_OK(status)) {
1886 printf("AddAliasMember failed - %s\n", nt_errstr(status));
1890 d.in.alias_handle = alias_handle;
1893 status = dcerpc_samr_DeleteAliasMember(p, mem_ctx, &d);
1894 if (!NT_STATUS_IS_OK(status)) {
1895 printf("DelAliasMember failed - %s\n", nt_errstr(status));
1902 static bool test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1903 struct policy_handle *alias_handle)
1905 struct samr_AddMultipleMembersToAlias a;
1906 struct samr_RemoveMultipleMembersFromAlias r;
1909 struct lsa_SidArray sids;
1911 printf("testing AddMultipleMembersToAlias\n");
1912 a.in.alias_handle = alias_handle;
1916 sids.sids = talloc_array(mem_ctx, struct lsa_SidPtr, 3);
1918 sids.sids[0].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-1");
1919 sids.sids[1].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-2");
1920 sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-3");
1922 status = dcerpc_samr_AddMultipleMembersToAlias(p, mem_ctx, &a);
1923 if (!NT_STATUS_IS_OK(status)) {
1924 printf("AddMultipleMembersToAlias failed - %s\n", nt_errstr(status));
1929 printf("testing RemoveMultipleMembersFromAlias\n");
1930 r.in.alias_handle = alias_handle;
1933 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1934 if (!NT_STATUS_IS_OK(status)) {
1935 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1939 /* strange! removing twice doesn't give any error */
1940 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1941 if (!NT_STATUS_IS_OK(status)) {
1942 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1946 /* but removing an alias that isn't there does */
1947 sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-4");
1949 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1950 if (!NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_NOT_FOUND, status)) {
1951 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1958 static bool test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1959 struct policy_handle *user_handle)
1961 struct samr_TestPrivateFunctionsUser r;
1965 printf("Testing TestPrivateFunctionsUser\n");
1967 r.in.user_handle = user_handle;
1969 status = dcerpc_samr_TestPrivateFunctionsUser(p, mem_ctx, &r);
1970 if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
1971 printf("TestPrivateFunctionsUser failed - %s\n", nt_errstr(status));
1979 static bool test_user_ops(struct dcerpc_pipe *p,
1980 struct torture_context *tctx,
1981 struct policy_handle *user_handle,
1982 struct policy_handle *domain_handle,
1983 uint32_t base_acct_flags,
1984 const char *base_acct_name, enum torture_samr_choice which_ops)
1986 char *password = NULL;
1987 struct samr_QueryUserInfo q;
1993 const uint32_t password_fields[] = {
1994 SAMR_FIELD_PASSWORD,
1995 SAMR_FIELD_PASSWORD2,
1996 SAMR_FIELD_PASSWORD | SAMR_FIELD_PASSWORD2,
2000 status = test_LookupName(p, tctx, domain_handle, base_acct_name, &rid);
2001 if (!NT_STATUS_IS_OK(status)) {
2005 switch (which_ops) {
2006 case TORTURE_SAMR_USER_ATTRIBUTES:
2007 if (!test_QuerySecurity(p, tctx, user_handle)) {
2011 if (!test_QueryUserInfo(p, tctx, user_handle)) {
2015 if (!test_QueryUserInfo2(p, tctx, user_handle)) {
2019 if (!test_SetUserInfo(p, tctx, user_handle, base_acct_flags,
2024 if (!test_GetUserPwInfo(p, tctx, user_handle)) {
2028 if (!test_TestPrivateFunctionsUser(p, tctx, user_handle)) {
2032 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
2036 case TORTURE_SAMR_PASSWORDS:
2037 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
2038 char simple_pass[9];
2039 char *v = generate_random_str(tctx, 1);
2041 ZERO_STRUCT(simple_pass);
2042 memset(simple_pass, *v, sizeof(simple_pass) - 1);
2044 printf("Testing machine account password policy rules\n");
2046 /* Workstation trust accounts don't seem to need to honour password quality policy */
2047 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
2051 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
2055 /* reset again, to allow another 'user' password change */
2056 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
2060 /* Try a 'short' password */
2061 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
2067 for (i = 0; password_fields[i]; i++) {
2068 if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
2072 /* check it was set right */
2073 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
2078 for (i = 0; password_fields[i]; i++) {
2079 if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
2083 /* check it was set right */
2084 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
2089 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
2093 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
2097 q.in.user_handle = user_handle;
2100 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
2101 if (!NT_STATUS_IS_OK(status)) {
2102 printf("QueryUserInfo level %u failed - %s\n",
2103 q.in.level, nt_errstr(status));
2106 uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
2107 if ((q.out.info->info5.acct_flags) != expected_flags) {
2108 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2109 q.out.info->info5.acct_flags,
2113 if (q.out.info->info5.rid != rid) {
2114 printf("QuerUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
2115 q.out.info->info5.rid, rid);
2121 case TORTURE_SAMR_OTHER:
2122 /* We just need the account to exist */
2128 static bool test_alias_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
2129 struct policy_handle *alias_handle,
2130 const struct dom_sid *domain_sid)
2134 if (!test_QuerySecurity(p, tctx, alias_handle)) {
2138 if (!test_QueryAliasInfo(p, tctx, alias_handle)) {
2142 if (!test_SetAliasInfo(p, tctx, alias_handle)) {
2146 if (!test_AddMemberToAlias(p, tctx, alias_handle, domain_sid)) {
2150 if (torture_setting_bool(tctx, "samba4", false)) {
2151 printf("skipping MultipleMembers Alias tests against Samba4\n");
2155 if (!test_AddMultipleMembersToAlias(p, tctx, alias_handle)) {
2163 static bool test_DeleteUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2164 struct policy_handle *user_handle)
2166 struct samr_DeleteUser d;
2169 printf("Testing DeleteUser\n");
2171 d.in.user_handle = user_handle;
2172 d.out.user_handle = user_handle;
2174 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
2175 if (!NT_STATUS_IS_OK(status)) {
2176 printf("DeleteUser failed - %s\n", nt_errstr(status));
2183 bool test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2184 struct policy_handle *handle, const char *name)
2187 struct samr_DeleteUser d;
2188 struct policy_handle user_handle;
2191 status = test_LookupName(p, mem_ctx, handle, name, &rid);
2192 if (!NT_STATUS_IS_OK(status)) {
2196 status = test_OpenUser_byname(p, mem_ctx, handle, name, &user_handle);
2197 if (!NT_STATUS_IS_OK(status)) {
2201 d.in.user_handle = &user_handle;
2202 d.out.user_handle = &user_handle;
2203 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
2204 if (!NT_STATUS_IS_OK(status)) {
2211 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
2216 static bool test_DeleteGroup_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2217 struct policy_handle *handle, const char *name)
2220 struct samr_OpenGroup r;
2221 struct samr_DeleteDomainGroup d;
2222 struct policy_handle group_handle;
2225 status = test_LookupName(p, mem_ctx, handle, name, &rid);
2226 if (!NT_STATUS_IS_OK(status)) {
2230 r.in.domain_handle = handle;
2231 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2233 r.out.group_handle = &group_handle;
2234 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
2235 if (!NT_STATUS_IS_OK(status)) {
2239 d.in.group_handle = &group_handle;
2240 d.out.group_handle = &group_handle;
2241 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
2242 if (!NT_STATUS_IS_OK(status)) {
2249 printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
2254 static bool test_DeleteAlias_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2255 struct policy_handle *domain_handle, const char *name)
2258 struct samr_OpenAlias r;
2259 struct samr_DeleteDomAlias d;
2260 struct policy_handle alias_handle;
2263 printf("testing DeleteAlias_byname\n");
2265 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
2266 if (!NT_STATUS_IS_OK(status)) {
2270 r.in.domain_handle = domain_handle;
2271 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2273 r.out.alias_handle = &alias_handle;
2274 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
2275 if (!NT_STATUS_IS_OK(status)) {
2279 d.in.alias_handle = &alias_handle;
2280 d.out.alias_handle = &alias_handle;
2281 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
2282 if (!NT_STATUS_IS_OK(status)) {
2289 printf("DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
2293 static bool test_DeleteAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2294 struct policy_handle *alias_handle)
2296 struct samr_DeleteDomAlias d;
2299 printf("Testing DeleteAlias\n");
2301 d.in.alias_handle = alias_handle;
2302 d.out.alias_handle = alias_handle;
2304 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
2305 if (!NT_STATUS_IS_OK(status)) {
2306 printf("DeleteAlias failed - %s\n", nt_errstr(status));
2313 static bool test_CreateAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2314 struct policy_handle *domain_handle,
2315 struct policy_handle *alias_handle,
2316 const struct dom_sid *domain_sid)
2319 struct samr_CreateDomAlias r;
2320 struct lsa_String name;
2324 init_lsa_String(&name, TEST_ALIASNAME);
2325 r.in.domain_handle = domain_handle;
2326 r.in.alias_name = &name;
2327 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2328 r.out.alias_handle = alias_handle;
2331 printf("Testing CreateAlias (%s)\n", r.in.alias_name->string);
2333 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
2335 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2336 printf("Server refused create of '%s'\n", r.in.alias_name->string);
2340 if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
2341 if (!test_DeleteAlias_byname(p, tctx, domain_handle, r.in.alias_name->string)) {
2344 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
2347 if (!NT_STATUS_IS_OK(status)) {
2348 printf("CreateAlias failed - %s\n", nt_errstr(status));
2352 if (!test_alias_ops(p, tctx, alias_handle, domain_sid)) {
2359 static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2360 const char *acct_name,
2361 struct policy_handle *domain_handle, char **password)
2369 if (!test_ChangePasswordUser(p, mem_ctx, acct_name, domain_handle, password)) {
2373 if (!test_ChangePasswordUser2(p, mem_ctx, acct_name, password, 0, true)) {
2377 if (!test_OemChangePasswordUser2(p, mem_ctx, acct_name, domain_handle, password)) {
2381 /* test what happens when setting the old password again */
2382 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, *password, 0, true)) {
2387 char simple_pass[9];
2388 char *v = generate_random_str(mem_ctx, 1);
2390 ZERO_STRUCT(simple_pass);
2391 memset(simple_pass, *v, sizeof(simple_pass) - 1);
2393 /* test what happens when picking a simple password */
2394 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, simple_pass, 0, true)) {
2399 /* set samr_SetDomainInfo level 1 with min_length 5 */
2401 struct samr_QueryDomainInfo r;
2402 struct samr_SetDomainInfo s;
2403 uint16_t len_old, len;
2404 uint32_t pwd_prop_old;
2405 int64_t min_pwd_age_old;
2410 r.in.domain_handle = domain_handle;
2413 printf("testing samr_QueryDomainInfo level 1\n");
2414 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2415 if (!NT_STATUS_IS_OK(status)) {
2419 s.in.domain_handle = domain_handle;
2421 s.in.info = r.out.info;
2423 /* remember the old min length, so we can reset it */
2424 len_old = s.in.info->info1.min_password_length;
2425 s.in.info->info1.min_password_length = len;
2426 pwd_prop_old = s.in.info->info1.password_properties;
2427 /* turn off password complexity checks for this test */
2428 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
2430 min_pwd_age_old = s.in.info->info1.min_password_age;
2431 s.in.info->info1.min_password_age = 0;
2433 printf("testing samr_SetDomainInfo level 1\n");
2434 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2435 if (!NT_STATUS_IS_OK(status)) {
2439 printf("calling test_ChangePasswordUser3 with too short password\n");
2441 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, len - 1, password, NULL, 0, true)) {
2445 s.in.info->info1.min_password_length = len_old;
2446 s.in.info->info1.password_properties = pwd_prop_old;
2447 s.in.info->info1.min_password_age = min_pwd_age_old;
2449 printf("testing samr_SetDomainInfo level 1\n");
2450 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2451 if (!NT_STATUS_IS_OK(status)) {
2459 struct samr_OpenUser r;
2460 struct samr_QueryUserInfo q;
2461 struct samr_LookupNames n;
2462 struct policy_handle user_handle;
2464 n.in.domain_handle = domain_handle;
2466 n.in.names = talloc_array(mem_ctx, struct lsa_String, 1);
2467 n.in.names[0].string = acct_name;
2469 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
2470 if (!NT_STATUS_IS_OK(status)) {
2471 printf("LookupNames failed - %s\n", nt_errstr(status));
2475 r.in.domain_handle = domain_handle;
2476 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2477 r.in.rid = n.out.rids.ids[0];
2478 r.out.user_handle = &user_handle;
2480 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
2481 if (!NT_STATUS_IS_OK(status)) {
2482 printf("OpenUser(%u) failed - %s\n", n.out.rids.ids[0], nt_errstr(status));
2486 q.in.user_handle = &user_handle;
2489 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
2490 if (!NT_STATUS_IS_OK(status)) {
2491 printf("QueryUserInfo failed - %s\n", nt_errstr(status));
2495 printf("calling test_ChangePasswordUser3 with too early password change\n");
2497 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL,
2498 q.out.info->info5.last_password_change, true)) {
2503 /* we change passwords twice - this has the effect of verifying
2504 they were changed correctly for the final call */
2505 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, true)) {
2509 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, true)) {
2516 static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2517 struct policy_handle *domain_handle,
2518 struct policy_handle *user_handle_out,
2519 enum torture_samr_choice which_ops)
2522 TALLOC_CTX *user_ctx;
2525 struct samr_CreateUser r;
2526 struct samr_QueryUserInfo q;
2527 struct samr_DeleteUser d;
2530 /* This call creates a 'normal' account - check that it really does */
2531 const uint32_t acct_flags = ACB_NORMAL;
2532 struct lsa_String name;
2535 struct policy_handle user_handle;
2536 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
2537 init_lsa_String(&name, TEST_ACCOUNT_NAME);
2539 r.in.domain_handle = domain_handle;
2540 r.in.account_name = &name;
2541 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2542 r.out.user_handle = &user_handle;
2545 printf("Testing CreateUser(%s)\n", r.in.account_name->string);
2547 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
2549 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2550 printf("Server refused create of '%s': %s\n", r.in.account_name->string, nt_errstr(status));
2551 talloc_free(user_ctx);
2555 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
2556 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
2557 talloc_free(user_ctx);
2560 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
2562 if (!NT_STATUS_IS_OK(status)) {
2563 talloc_free(user_ctx);
2564 printf("CreateUser failed - %s\n", nt_errstr(status));
2567 q.in.user_handle = &user_handle;
2570 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
2571 if (!NT_STATUS_IS_OK(status)) {
2572 printf("QueryUserInfo level %u failed - %s\n",
2573 q.in.level, nt_errstr(status));
2576 if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
2577 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2578 q.out.info->info16.acct_flags,
2584 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
2585 acct_flags, name.string, which_ops)) {
2589 if (user_handle_out) {
2590 *user_handle_out = user_handle;
2592 printf("Testing DeleteUser (createuser test)\n");
2594 d.in.user_handle = &user_handle;
2595 d.out.user_handle = &user_handle;
2597 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
2598 if (!NT_STATUS_IS_OK(status)) {
2599 printf("DeleteUser failed - %s\n", nt_errstr(status));
2606 talloc_free(user_ctx);
2612 static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
2613 struct policy_handle *domain_handle, enum torture_samr_choice which_ops)
2616 struct samr_CreateUser2 r;
2617 struct samr_QueryUserInfo q;
2618 struct samr_DeleteUser d;
2619 struct policy_handle user_handle;
2621 struct lsa_String name;
2626 uint32_t acct_flags;
2627 const char *account_name;
2629 } account_types[] = {
2630 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
2631 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2632 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2633 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
2634 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2635 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2636 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
2637 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2638 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2639 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
2640 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
2641 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
2642 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2643 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2644 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
2647 for (i = 0; account_types[i].account_name; i++) {
2648 TALLOC_CTX *user_ctx;
2649 uint32_t acct_flags = account_types[i].acct_flags;
2650 uint32_t access_granted;
2651 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
2652 init_lsa_String(&name, account_types[i].account_name);
2654 r.in.domain_handle = domain_handle;
2655 r.in.account_name = &name;
2656 r.in.acct_flags = acct_flags;
2657 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2658 r.out.user_handle = &user_handle;
2659 r.out.access_granted = &access_granted;
2662 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
2664 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
2666 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2667 talloc_free(user_ctx);
2668 printf("Server refused create of '%s'\n", r.in.account_name->string);
2671 } else if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
2672 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
2673 talloc_free(user_ctx);
2677 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
2680 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
2681 printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
2682 nt_errstr(status), nt_errstr(account_types[i].nt_status));
2686 if (NT_STATUS_IS_OK(status)) {
2687 q.in.user_handle = &user_handle;
2690 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
2691 if (!NT_STATUS_IS_OK(status)) {
2692 printf("QueryUserInfo level %u failed - %s\n",
2693 q.in.level, nt_errstr(status));
2696 uint32_t expected_flags = (acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
2697 if (acct_flags == ACB_NORMAL) {
2698 expected_flags |= ACB_PW_EXPIRED;
2700 if ((q.out.info->info5.acct_flags) != expected_flags) {
2701 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2702 q.out.info->info5.acct_flags,
2706 switch (acct_flags) {
2708 if (q.out.info->info5.primary_gid != DOMAIN_RID_DCS) {
2709 printf("QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n",
2710 DOMAIN_RID_DCS, q.out.info->info5.primary_gid);
2715 if (q.out.info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
2716 printf("QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
2717 DOMAIN_RID_DOMAIN_MEMBERS, q.out.info->info5.primary_gid);
2722 if (q.out.info->info5.primary_gid != DOMAIN_RID_USERS) {
2723 printf("QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n",
2724 DOMAIN_RID_USERS, q.out.info->info5.primary_gid);
2731 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
2732 acct_flags, name.string, which_ops)) {
2736 printf("Testing DeleteUser (createuser2 test)\n");
2738 d.in.user_handle = &user_handle;
2739 d.out.user_handle = &user_handle;
2741 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
2742 if (!NT_STATUS_IS_OK(status)) {
2743 printf("DeleteUser failed - %s\n", nt_errstr(status));
2747 talloc_free(user_ctx);
2753 static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2754 struct policy_handle *handle)
2757 struct samr_QueryAliasInfo r;
2758 uint16_t levels[] = {1, 2, 3};
2762 for (i=0;i<ARRAY_SIZE(levels);i++) {
2763 printf("Testing QueryAliasInfo level %u\n", levels[i]);
2765 r.in.alias_handle = handle;
2766 r.in.level = levels[i];
2768 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
2769 if (!NT_STATUS_IS_OK(status)) {
2770 printf("QueryAliasInfo level %u failed - %s\n",
2771 levels[i], nt_errstr(status));
2779 static bool test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2780 struct policy_handle *handle)
2783 struct samr_QueryGroupInfo r;
2784 uint16_t levels[] = {1, 2, 3, 4, 5};
2788 for (i=0;i<ARRAY_SIZE(levels);i++) {
2789 printf("Testing QueryGroupInfo level %u\n", levels[i]);
2791 r.in.group_handle = handle;
2792 r.in.level = levels[i];
2794 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
2795 if (!NT_STATUS_IS_OK(status)) {
2796 printf("QueryGroupInfo level %u failed - %s\n",
2797 levels[i], nt_errstr(status));
2805 static bool test_QueryGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2806 struct policy_handle *handle)
2809 struct samr_QueryGroupMember r;
2812 printf("Testing QueryGroupMember\n");
2814 r.in.group_handle = handle;
2816 status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &r);
2817 if (!NT_STATUS_IS_OK(status)) {
2818 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
2826 static bool test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2827 struct policy_handle *handle)
2830 struct samr_QueryGroupInfo r;
2831 struct samr_SetGroupInfo s;
2832 uint16_t levels[] = {1, 2, 3, 4};
2833 uint16_t set_ok[] = {0, 1, 1, 1};
2837 for (i=0;i<ARRAY_SIZE(levels);i++) {
2838 printf("Testing QueryGroupInfo level %u\n", levels[i]);
2840 r.in.group_handle = handle;
2841 r.in.level = levels[i];
2843 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
2844 if (!NT_STATUS_IS_OK(status)) {
2845 printf("QueryGroupInfo level %u failed - %s\n",
2846 levels[i], nt_errstr(status));
2850 printf("Testing SetGroupInfo level %u\n", levels[i]);
2852 s.in.group_handle = handle;
2853 s.in.level = levels[i];
2854 s.in.info = r.out.info;
2857 /* disabled this, as it changes the name only from the point of view of samr,
2858 but leaves the name from the point of view of w2k3 internals (and ldap). This means
2859 the name is still reserved, so creating the old name fails, but deleting by the old name
2861 if (s.in.level == 2) {
2862 init_lsa_String(&s.in.info->string, "NewName");
2866 if (s.in.level == 4) {
2867 init_lsa_String(&s.in.info->description, "test description");
2870 status = dcerpc_samr_SetGroupInfo(p, mem_ctx, &s);
2872 if (!NT_STATUS_IS_OK(status)) {
2873 printf("SetGroupInfo level %u failed - %s\n",
2874 r.in.level, nt_errstr(status));
2879 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
2880 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
2881 r.in.level, nt_errstr(status));
2891 static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2892 struct policy_handle *handle)
2895 struct samr_QueryUserInfo r;
2896 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
2897 11, 12, 13, 14, 16, 17, 20, 21};
2901 for (i=0;i<ARRAY_SIZE(levels);i++) {
2902 printf("Testing QueryUserInfo level %u\n", levels[i]);
2904 r.in.user_handle = handle;
2905 r.in.level = levels[i];
2907 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
2908 if (!NT_STATUS_IS_OK(status)) {
2909 printf("QueryUserInfo level %u failed - %s\n",
2910 levels[i], nt_errstr(status));
2918 static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2919 struct policy_handle *handle)
2922 struct samr_QueryUserInfo2 r;
2923 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
2924 11, 12, 13, 14, 16, 17, 20, 21};
2928 for (i=0;i<ARRAY_SIZE(levels);i++) {
2929 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
2931 r.in.user_handle = handle;
2932 r.in.level = levels[i];
2934 status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r);
2935 if (!NT_STATUS_IS_OK(status)) {
2936 printf("QueryUserInfo2 level %u failed - %s\n",
2937 levels[i], nt_errstr(status));
2945 static bool test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2946 struct policy_handle *handle, uint32_t rid)
2949 struct samr_OpenUser r;
2950 struct policy_handle user_handle;
2953 printf("Testing OpenUser(%u)\n", rid);
2955 r.in.domain_handle = handle;
2956 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2958 r.out.user_handle = &user_handle;
2960 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
2961 if (!NT_STATUS_IS_OK(status)) {
2962 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
2966 if (!test_QuerySecurity(p, mem_ctx, &user_handle)) {
2970 if (!test_QueryUserInfo(p, mem_ctx, &user_handle)) {
2974 if (!test_QueryUserInfo2(p, mem_ctx, &user_handle)) {
2978 if (!test_GetUserPwInfo(p, mem_ctx, &user_handle)) {
2982 if (!test_GetGroupsForUser(p,mem_ctx, &user_handle)) {
2986 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
2993 static bool test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2994 struct policy_handle *handle, uint32_t rid)
2997 struct samr_OpenGroup r;
2998 struct policy_handle group_handle;
3001 printf("Testing OpenGroup(%u)\n", rid);
3003 r.in.domain_handle = handle;
3004 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3006 r.out.group_handle = &group_handle;
3008 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
3009 if (!NT_STATUS_IS_OK(status)) {
3010 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
3014 if (!test_QuerySecurity(p, mem_ctx, &group_handle)) {
3018 if (!test_QueryGroupInfo(p, mem_ctx, &group_handle)) {
3022 if (!test_QueryGroupMember(p, mem_ctx, &group_handle)) {
3026 if (!test_samr_handle_Close(p, mem_ctx, &group_handle)) {
3033 static bool test_OpenAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3034 struct policy_handle *handle, uint32_t rid)
3037 struct samr_OpenAlias r;
3038 struct policy_handle alias_handle;
3041 printf("Testing OpenAlias(%u)\n", rid);
3043 r.in.domain_handle = handle;
3044 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3046 r.out.alias_handle = &alias_handle;
3048 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
3049 if (!NT_STATUS_IS_OK(status)) {
3050 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
3054 if (!test_QuerySecurity(p, mem_ctx, &alias_handle)) {
3058 if (!test_QueryAliasInfo(p, mem_ctx, &alias_handle)) {
3062 if (!test_GetMembersInAlias(p, mem_ctx, &alias_handle)) {
3066 if (!test_samr_handle_Close(p, mem_ctx, &alias_handle)) {
3073 static bool check_mask(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3074 struct policy_handle *handle, uint32_t rid,
3075 uint32_t acct_flag_mask)
3078 struct samr_OpenUser r;
3079 struct samr_QueryUserInfo q;
3080 struct policy_handle user_handle;
3083 printf("Testing OpenUser(%u)\n", rid);
3085 r.in.domain_handle = handle;
3086 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3088 r.out.user_handle = &user_handle;
3090 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3091 if (!NT_STATUS_IS_OK(status)) {
3092 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
3096 q.in.user_handle = &user_handle;
3099 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
3100 if (!NT_STATUS_IS_OK(status)) {
3101 printf("QueryUserInfo level 16 failed - %s\n",
3105 if ((acct_flag_mask & q.out.info->info16.acct_flags) == 0) {
3106 printf("Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
3107 acct_flag_mask, q.out.info->info16.acct_flags, rid);
3112 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
3119 static bool test_EnumDomainUsers(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3120 struct policy_handle *handle)
3122 NTSTATUS status = STATUS_MORE_ENTRIES;
3123 struct samr_EnumDomainUsers r;
3124 uint32_t mask, resume_handle=0;
3127 struct samr_LookupNames n;
3128 struct samr_LookupRids lr ;
3129 uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
3130 ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
3131 ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
3134 printf("Testing EnumDomainUsers\n");
3136 for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
3137 r.in.domain_handle = handle;
3138 r.in.resume_handle = &resume_handle;
3139 r.in.acct_flags = mask = masks[mask_idx];
3140 r.in.max_size = (uint32_t)-1;
3141 r.out.resume_handle = &resume_handle;
3143 status = dcerpc_samr_EnumDomainUsers(p, mem_ctx, &r);
3144 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
3145 !NT_STATUS_IS_OK(status)) {
3146 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
3151 printf("EnumDomainUsers failed: r.out.sam unexpectedly NULL\n");
3155 if (r.out.sam->count == 0) {
3159 for (i=0;i<r.out.sam->count;i++) {
3161 if (!check_mask(p, mem_ctx, handle, r.out.sam->entries[i].idx, mask)) {
3164 } else if (!test_OpenUser(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
3170 printf("Testing LookupNames\n");
3171 n.in.domain_handle = handle;
3172 n.in.num_names = r.out.sam->count;
3173 n.in.names = talloc_array(mem_ctx, struct lsa_String, r.out.sam->count);
3174 for (i=0;i<r.out.sam->count;i++) {
3175 n.in.names[i].string = r.out.sam->entries[i].name.string;
3177 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
3178 if (!NT_STATUS_IS_OK(status)) {
3179 printf("LookupNames failed - %s\n", nt_errstr(status));
3184 printf("Testing LookupRids\n");
3185 lr.in.domain_handle = handle;
3186 lr.in.num_rids = r.out.sam->count;
3187 lr.in.rids = talloc_array(mem_ctx, uint32_t, r.out.sam->count);
3188 for (i=0;i<r.out.sam->count;i++) {
3189 lr.in.rids[i] = r.out.sam->entries[i].idx;
3191 status = dcerpc_samr_LookupRids(p, mem_ctx, &lr);
3192 if (!NT_STATUS_IS_OK(status)) {
3193 printf("LookupRids failed - %s\n", nt_errstr(status));
3201 try blasting the server with a bunch of sync requests
3203 static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, TALLOC_CTX *tctx,
3204 struct policy_handle *handle)
3207 struct samr_EnumDomainUsers r;
3208 uint32_t resume_handle=0;
3210 #define ASYNC_COUNT 100
3211 struct rpc_request *req[ASYNC_COUNT];
3213 if (!torture_setting_bool(tctx, "dangerous", false)) {
3214 printf("samr async test disabled - enable dangerous tests to use\n");
3218 printf("Testing EnumDomainUsers_async\n");
3220 r.in.domain_handle = handle;
3221 r.in.resume_handle = &resume_handle;
3222 r.in.acct_flags = 0;
3223 r.in.max_size = (uint32_t)-1;
3224 r.out.resume_handle = &resume_handle;
3226 for (i=0;i<ASYNC_COUNT;i++) {
3227 req[i] = dcerpc_samr_EnumDomainUsers_send(p, tctx, &r);
3230 for (i=0;i<ASYNC_COUNT;i++) {
3231 status = dcerpc_ndr_request_recv(req[i]);
3232 if (!NT_STATUS_IS_OK(status)) {
3233 printf("EnumDomainUsers[%d] failed - %s\n",
3234 i, nt_errstr(status));
3239 printf("%d async requests OK\n", i);
3244 static bool test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3245 struct policy_handle *handle)
3248 struct samr_EnumDomainGroups r;
3249 uint32_t resume_handle=0;
3253 printf("Testing EnumDomainGroups\n");
3255 r.in.domain_handle = handle;
3256 r.in.resume_handle = &resume_handle;
3257 r.in.max_size = (uint32_t)-1;
3258 r.out.resume_handle = &resume_handle;
3260 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
3261 if (!NT_STATUS_IS_OK(status)) {
3262 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
3270 for (i=0;i<r.out.sam->count;i++) {
3271 if (!test_OpenGroup(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
3279 static bool test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3280 struct policy_handle *handle)
3283 struct samr_EnumDomainAliases r;
3284 uint32_t resume_handle=0;
3288 printf("Testing EnumDomainAliases\n");
3290 r.in.domain_handle = handle;
3291 r.in.resume_handle = &resume_handle;
3292 r.in.acct_flags = (uint32_t)-1;
3293 r.out.resume_handle = &resume_handle;
3295 status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
3296 if (!NT_STATUS_IS_OK(status)) {
3297 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
3305 for (i=0;i<r.out.sam->count;i++) {
3306 if (!test_OpenAlias(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
3314 static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3315 struct policy_handle *handle)
3318 struct samr_GetDisplayEnumerationIndex r;
3320 uint16_t levels[] = {1, 2, 3, 4, 5};
3321 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
3324 for (i=0;i<ARRAY_SIZE(levels);i++) {
3325 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
3327 r.in.domain_handle = handle;
3328 r.in.level = levels[i];
3329 init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
3331 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
3334 !NT_STATUS_IS_OK(status) &&
3335 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3336 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
3337 levels[i], nt_errstr(status));
3341 init_lsa_String(&r.in.name, "zzzzzzzz");
3343 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
3345 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3346 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
3347 levels[i], nt_errstr(status));
3355 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3356 struct policy_handle *handle)
3359 struct samr_GetDisplayEnumerationIndex2 r;
3361 uint16_t levels[] = {1, 2, 3, 4, 5};
3362 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
3365 for (i=0;i<ARRAY_SIZE(levels);i++) {
3366 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
3368 r.in.domain_handle = handle;
3369 r.in.level = levels[i];
3370 init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
3372 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
3374 !NT_STATUS_IS_OK(status) &&
3375 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3376 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
3377 levels[i], nt_errstr(status));
3381 init_lsa_String(&r.in.name, "zzzzzzzz");
3383 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
3384 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3385 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
3386 levels[i], nt_errstr(status));
3394 #define STRING_EQUAL_QUERY(s1, s2, user) \
3395 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
3396 /* odd, but valid */ \
3397 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
3398 printf("%s mismatch for %s: %s != %s (%s)\n", \
3399 #s1, user.string, s1.string, s2.string, __location__); \
3402 #define INT_EQUAL_QUERY(s1, s2, user) \
3404 printf("%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
3405 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
3409 static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3410 struct samr_QueryDisplayInfo *querydisplayinfo,
3411 bool *seen_testuser)
3413 struct samr_OpenUser r;
3414 struct samr_QueryUserInfo q;
3415 struct policy_handle user_handle;
3418 r.in.domain_handle = querydisplayinfo->in.domain_handle;
3419 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3420 for (i = 0; ; i++) {
3421 switch (querydisplayinfo->in.level) {
3423 if (i >= querydisplayinfo->out.info.info1.count) {
3426 r.in.rid = querydisplayinfo->out.info.info1.entries[i].rid;
3429 if (i >= querydisplayinfo->out.info.info2.count) {
3432 r.in.rid = querydisplayinfo->out.info.info2.entries[i].rid;
3438 /* Not interested in validating just the account name */
3442 r.out.user_handle = &user_handle;
3444 switch (querydisplayinfo->in.level) {
3447 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3448 if (!NT_STATUS_IS_OK(status)) {
3449 printf("OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(status));
3454 q.in.user_handle = &user_handle;
3456 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
3457 if (!NT_STATUS_IS_OK(status)) {
3458 printf("QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(status));
3462 switch (querydisplayinfo->in.level) {
3464 if (seen_testuser && strcmp(q.out.info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
3465 *seen_testuser = true;
3467 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].full_name,
3468 q.out.info->info21.full_name, q.out.info->info21.account_name);
3469 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].account_name,
3470 q.out.info->info21.account_name, q.out.info->info21.account_name);
3471 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].description,
3472 q.out.info->info21.description, q.out.info->info21.account_name);
3473 INT_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].rid,
3474 q.out.info->info21.rid, q.out.info->info21.account_name);
3475 INT_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].acct_flags,
3476 q.out.info->info21.acct_flags, q.out.info->info21.account_name);
3480 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].account_name,
3481 q.out.info->info21.account_name, q.out.info->info21.account_name);
3482 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].description,
3483 q.out.info->info21.description, q.out.info->info21.account_name);
3484 INT_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].rid,
3485 q.out.info->info21.rid, q.out.info->info21.account_name);
3486 INT_EQUAL_QUERY((querydisplayinfo->out.info.info2.entries[i].acct_flags & ~ACB_NORMAL),
3487 q.out.info->info21.acct_flags, q.out.info->info21.account_name);
3489 if (!(querydisplayinfo->out.info.info2.entries[i].acct_flags & ACB_NORMAL)) {
3490 printf("Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
3491 q.out.info->info21.account_name.string);
3494 if (!(q.out.info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
3495 printf("Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
3496 q.out.info->info21.account_name.string,
3497 querydisplayinfo->out.info.info2.entries[i].acct_flags,
3498 q.out.info->info21.acct_flags);
3505 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
3512 static bool test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3513 struct policy_handle *handle)
3516 struct samr_QueryDisplayInfo r;
3517 struct samr_QueryDomainInfo dom_info;
3519 uint16_t levels[] = {1, 2, 3, 4, 5};
3521 bool seen_testuser = false;
3523 for (i=0;i<ARRAY_SIZE(levels);i++) {
3524 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
3527 status = STATUS_MORE_ENTRIES;
3528 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
3529 r.in.domain_handle = handle;
3530 r.in.level = levels[i];
3531 r.in.max_entries = 2;
3532 r.in.buf_size = (uint32_t)-1;
3534 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
3535 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(status)) {
3536 printf("QueryDisplayInfo level %u failed - %s\n",
3537 levels[i], nt_errstr(status));
3540 switch (r.in.level) {
3542 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, &seen_testuser)) {
3545 r.in.start_idx += r.out.info.info1.count;
3548 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, NULL)) {
3551 r.in.start_idx += r.out.info.info2.count;
3554 r.in.start_idx += r.out.info.info3.count;
3557 r.in.start_idx += r.out.info.info4.count;
3560 r.in.start_idx += r.out.info.info5.count;
3564 dom_info.in.domain_handle = handle;
3565 dom_info.in.level = 2;
3566 /* Check number of users returned is correct */
3567 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &dom_info);
3568 if (!NT_STATUS_IS_OK(status)) {
3569 printf("QueryDomainInfo level %u failed - %s\n",
3570 r.in.level, nt_errstr(status));
3574 switch (r.in.level) {
3577 if (dom_info.out.info->info2.num_users < r.in.start_idx) {
3578 printf("QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
3579 r.in.start_idx, dom_info.out.info->info2.num_groups,
3580 dom_info.out.info->info2.domain_name.string);
3583 if (!seen_testuser) {
3584 struct policy_handle user_handle;
3585 if (NT_STATUS_IS_OK(test_OpenUser_byname(p, mem_ctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
3586 printf("Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
3587 dom_info.out.info->info2.domain_name.string);
3589 test_samr_handle_Close(p, mem_ctx, &user_handle);
3595 if (dom_info.out.info->info2.num_groups != r.in.start_idx) {
3596 printf("QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
3597 r.in.start_idx, dom_info.out.info->info2.num_groups,
3598 dom_info.out.info->info2.domain_name.string);
3610 static bool test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3611 struct policy_handle *handle)
3614 struct samr_QueryDisplayInfo2 r;
3616 uint16_t levels[] = {1, 2, 3, 4, 5};
3619 for (i=0;i<ARRAY_SIZE(levels);i++) {
3620 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
3622 r.in.domain_handle = handle;
3623 r.in.level = levels[i];
3625 r.in.max_entries = 1000;
3626 r.in.buf_size = (uint32_t)-1;
3628 status = dcerpc_samr_QueryDisplayInfo2(p, mem_ctx, &r);
3629 if (!NT_STATUS_IS_OK(status)) {
3630 printf("QueryDisplayInfo2 level %u failed - %s\n",
3631 levels[i], nt_errstr(status));
3639 static bool test_QueryDisplayInfo3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3640 struct policy_handle *handle)
3643 struct samr_QueryDisplayInfo3 r;
3645 uint16_t levels[] = {1, 2, 3, 4, 5};
3648 for (i=0;i<ARRAY_SIZE(levels);i++) {
3649 printf("Testing QueryDisplayInfo3 level %u\n", levels[i]);
3651 r.in.domain_handle = handle;
3652 r.in.level = levels[i];
3654 r.in.max_entries = 1000;
3655 r.in.buf_size = (uint32_t)-1;
3657 status = dcerpc_samr_QueryDisplayInfo3(p, mem_ctx, &r);
3658 if (!NT_STATUS_IS_OK(status)) {
3659 printf("QueryDisplayInfo3 level %u failed - %s\n",
3660 levels[i], nt_errstr(status));
3669 static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3670 struct policy_handle *handle)
3673 struct samr_QueryDisplayInfo r;
3676 printf("Testing QueryDisplayInfo continuation\n");
3678 r.in.domain_handle = handle;
3681 r.in.max_entries = 1;
3682 r.in.buf_size = (uint32_t)-1;
3685 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
3686 if (NT_STATUS_IS_OK(status) && r.out.returned_size != 0) {
3687 if (r.out.info.info1.entries[0].idx != r.in.start_idx + 1) {
3688 printf("expected idx %d but got %d\n",
3690 r.out.info.info1.entries[0].idx);
3694 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
3695 !NT_STATUS_IS_OK(status)) {
3696 printf("QueryDisplayInfo level %u failed - %s\n",
3697 r.in.level, nt_errstr(status));
3702 } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
3703 NT_STATUS_IS_OK(status)) &&
3704 r.out.returned_size != 0);
3709 static bool test_QueryDomainInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3710 struct policy_handle *handle)
3713 struct samr_QueryDomainInfo r;
3714 struct samr_SetDomainInfo s;
3715 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
3716 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
3719 const char *domain_comment = talloc_asprintf(mem_ctx,
3720 "Tortured by Samba4 RPC-SAMR: %s",
3721 timestring(mem_ctx, time(NULL)));
3723 s.in.domain_handle = handle;
3725 s.in.info = talloc(mem_ctx, union samr_DomainInfo);
3727 s.in.info->info4.comment.string = domain_comment;
3728 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
3729 if (!NT_STATUS_IS_OK(status)) {
3730 printf("SetDomainInfo level %u (set comment) failed - %s\n",
3731 r.in.level, nt_errstr(status));
3735 for (i=0;i<ARRAY_SIZE(levels);i++) {
3736 printf("Testing QueryDomainInfo level %u\n", levels[i]);
3738 r.in.domain_handle = handle;
3739 r.in.level = levels[i];
3741 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
3742 if (!NT_STATUS_IS_OK(status)) {
3743 printf("QueryDomainInfo level %u failed - %s\n",
3744 r.in.level, nt_errstr(status));
3749 switch (levels[i]) {
3751 if (strcmp(r.out.info->info2.comment.string, domain_comment) != 0) {
3752 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
3753 levels[i], r.out.info->info2.comment.string, domain_comment);
3756 if (!r.out.info->info2.primary.string) {
3757 printf("QueryDomainInfo level %u returned no PDC name\n",
3760 } else if (r.out.info->info2.role == SAMR_ROLE_DOMAIN_PDC) {
3761 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), r.out.info->info2.primary.string) != 0) {
3762 printf("QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
3763 levels[i], r.out.info->info2.primary.string, dcerpc_server_name(p));
3768 if (strcmp(r.out.info->info4.comment.string, domain_comment) != 0) {
3769 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
3770 levels[i], r.out.info->info4.comment.string, domain_comment);
3775 if (!r.out.info->info6.primary.string) {
3776 printf("QueryDomainInfo level %u returned no PDC name\n",
3782 if (strcmp(r.out.info->info11.info2.comment.string, domain_comment) != 0) {
3783 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
3784 levels[i], r.out.info->info11.info2.comment.string, domain_comment);
3790 printf("Testing SetDomainInfo level %u\n", levels[i]);
3792 s.in.domain_handle = handle;
3793 s.in.level = levels[i];
3794 s.in.info = r.out.info;
3796 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
3798 if (!NT_STATUS_IS_OK(status)) {
3799 printf("SetDomainInfo level %u failed - %s\n",
3800 r.in.level, nt_errstr(status));
3805 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
3806 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
3807 r.in.level, nt_errstr(status));
3813 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
3814 if (!NT_STATUS_IS_OK(status)) {
3815 printf("QueryDomainInfo level %u failed - %s\n",
3816 r.in.level, nt_errstr(status));
3826 static bool test_QueryDomainInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3827 struct policy_handle *handle)
3830 struct samr_QueryDomainInfo2 r;
3831 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
3835 for (i=0;i<ARRAY_SIZE(levels);i++) {
3836 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
3838 r.in.domain_handle = handle;
3839 r.in.level = levels[i];
3841 status = dcerpc_samr_QueryDomainInfo2(p, mem_ctx, &r);
3842 if (!NT_STATUS_IS_OK(status)) {
3843 printf("QueryDomainInfo2 level %u failed - %s\n",
3844 r.in.level, nt_errstr(status));
3853 /* Test whether querydispinfo level 5 and enumdomgroups return the same
3854 set of group names. */
3855 static bool test_GroupList(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3856 struct policy_handle *handle)
3858 struct samr_EnumDomainGroups q1;
3859 struct samr_QueryDisplayInfo q2;
3861 uint32_t resume_handle=0;
3866 const char **names = NULL;
3868 printf("Testing coherency of querydispinfo vs enumdomgroups\n");
3870 q1.in.domain_handle = handle;
3871 q1.in.resume_handle = &resume_handle;
3873 q1.out.resume_handle = &resume_handle;
3875 status = STATUS_MORE_ENTRIES;
3876 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
3877 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &q1);
3879 if (!NT_STATUS_IS_OK(status) &&
3880 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
3883 for (i=0; i<q1.out.num_entries; i++) {
3884 add_string_to_array(mem_ctx,
3885 q1.out.sam->entries[i].name.string,
3886 &names, &num_names);
3890 if (!NT_STATUS_IS_OK(status)) {
3891 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
3899 q2.in.domain_handle = handle;
3901 q2.in.start_idx = 0;
3902 q2.in.max_entries = 5;
3903 q2.in.buf_size = (uint32_t)-1;
3905 status = STATUS_MORE_ENTRIES;
3906 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
3907 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &q2);
3909 if (!NT_STATUS_IS_OK(status) &&
3910 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
3913 for (i=0; i<q2.out.info.info5.count; i++) {
3915 const char *name = q2.out.info.info5.entries[i].account_name.string;
3917 for (j=0; j<num_names; j++) {
3918 if (names[j] == NULL)
3920 if (strequal(names[j], name)) {
3928 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
3933 q2.in.start_idx += q2.out.info.info5.count;
3936 if (!NT_STATUS_IS_OK(status)) {
3937 printf("QueryDisplayInfo level 5 failed - %s\n",
3942 for (i=0; i<num_names; i++) {
3943 if (names[i] != NULL) {
3944 printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
3953 static bool test_DeleteDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3954 struct policy_handle *group_handle)
3956 struct samr_DeleteDomainGroup d;
3960 printf("Testing DeleteDomainGroup\n");
3962 d.in.group_handle = group_handle;
3963 d.out.group_handle = group_handle;
3965 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
3966 if (!NT_STATUS_IS_OK(status)) {
3967 printf("DeleteDomainGroup failed - %s\n", nt_errstr(status));
3974 static bool test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3975 struct policy_handle *domain_handle)
3977 struct samr_TestPrivateFunctionsDomain r;
3981 printf("Testing TestPrivateFunctionsDomain\n");
3983 r.in.domain_handle = domain_handle;
3985 status = dcerpc_samr_TestPrivateFunctionsDomain(p, mem_ctx, &r);
3986 if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
3987 printf("TestPrivateFunctionsDomain failed - %s\n", nt_errstr(status));
3994 static bool test_RidToSid(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3995 struct dom_sid *domain_sid,
3996 struct policy_handle *domain_handle)
3998 struct samr_RidToSid r;
4001 struct dom_sid *calc_sid;
4002 int rids[] = { 0, 42, 512, 10200 };
4005 for (i=0;i<ARRAY_SIZE(rids);i++) {
4007 printf("Testing RidToSid\n");
4009 calc_sid = dom_sid_dup(mem_ctx, domain_sid);
4010 r.in.domain_handle = domain_handle;
4013 status = dcerpc_samr_RidToSid(p, mem_ctx, &r);
4014 if (!NT_STATUS_IS_OK(status)) {
4015 printf("RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
4018 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
4020 if (!dom_sid_equal(calc_sid, r.out.sid)) {
4021 printf("RidToSid for %d failed - got %s, expected %s\n", rids[i],
4022 dom_sid_string(mem_ctx, r.out.sid),
4023 dom_sid_string(mem_ctx, calc_sid));
4032 static bool test_GetBootKeyInformation(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4033 struct policy_handle *domain_handle)
4035 struct samr_GetBootKeyInformation r;
4039 printf("Testing GetBootKeyInformation\n");
4041 r.in.domain_handle = domain_handle;
4043 status = dcerpc_samr_GetBootKeyInformation(p, mem_ctx, &r);
4044 if (!NT_STATUS_IS_OK(status)) {
4045 /* w2k3 seems to fail this sometimes and pass it sometimes */
4046 printf("GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
4052 static bool test_AddGroupMember(struct dcerpc_pipe *p, struct torture_context *tctx,
4053 struct policy_handle *domain_handle,
4054 struct policy_handle *group_handle)
4057 struct samr_AddGroupMember r;
4058 struct samr_DeleteGroupMember d;
4059 struct samr_QueryGroupMember q;
4060 struct samr_SetMemberAttributesOfGroup s;
4064 status = test_LookupName(p, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
4065 if (!NT_STATUS_IS_OK(status)) {
4066 printf("test_AddGroupMember looking up name " TEST_ACCOUNT_NAME " failed - %s\n", nt_errstr(status));
4070 r.in.group_handle = group_handle;
4072 r.in.flags = 0; /* ??? */
4074 printf("Testing AddGroupMember and DeleteGroupMember\n");
4076 d.in.group_handle = group_handle;
4079 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
4080 if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_NOT_IN_GROUP, status)) {
4081 printf("DeleteGroupMember gave %s - should be NT_STATUS_MEMBER_NOT_IN_GROUP\n",
4086 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4087 if (!NT_STATUS_IS_OK(status)) {
4088 printf("AddGroupMember failed - %s\n", nt_errstr(status));
4092 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4093 if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_IN_GROUP, status)) {
4094 printf("AddGroupMember gave %s - should be NT_STATUS_MEMBER_IN_GROUP\n",
4099 if (torture_setting_bool(tctx, "samba4", false)) {
4100 printf("skipping SetMemberAttributesOfGroup test against Samba4\n");
4102 /* this one is quite strange. I am using random inputs in the
4103 hope of triggering an error that might give us a clue */
4105 s.in.group_handle = group_handle;
4106 s.in.unknown1 = random();
4107 s.in.unknown2 = random();
4109 status = dcerpc_samr_SetMemberAttributesOfGroup(p, tctx, &s);
4110 if (!NT_STATUS_IS_OK(status)) {
4111 printf("SetMemberAttributesOfGroup failed - %s\n", nt_errstr(status));
4116 q.in.group_handle = group_handle;
4118 status = dcerpc_samr_QueryGroupMember(p, tctx, &q);
4119 if (!NT_STATUS_IS_OK(status)) {
4120 printf("QueryGroupMember failed - %s\n", nt_errstr(status));
4124 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
4125 if (!NT_STATUS_IS_OK(status)) {
4126 printf("DeleteGroupMember failed - %s\n", nt_errstr(status));
4130 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4131 if (!NT_STATUS_IS_OK(status)) {
4132 printf("AddGroupMember failed - %s\n", nt_errstr(status));
4140 static bool test_CreateDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4141 struct policy_handle *domain_handle, struct policy_handle *group_handle)
4144 struct samr_CreateDomainGroup r;
4146 struct lsa_String name;
4149 init_lsa_String(&name, TEST_GROUPNAME);
4151 r.in.domain_handle = domain_handle;
4153 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4154 r.out.group_handle = group_handle;
4157 printf("Testing CreateDomainGroup(%s)\n", r.in.name->string);
4159 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
4161 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
4162 printf("Server refused create of '%s'\n", r.in.name->string);
4163 ZERO_STRUCTP(group_handle);
4167 if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS)) {
4168 if (!test_DeleteGroup_byname(p, mem_ctx, domain_handle, r.in.name->string)) {
4170 printf("CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
4174 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
4176 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
4177 if (!test_DeleteUser_byname(p, mem_ctx, domain_handle, r.in.name->string)) {
4179 printf("CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
4183 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
4185 if (!NT_STATUS_IS_OK(status)) {
4186 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
4190 if (!test_AddGroupMember(p, mem_ctx, domain_handle, group_handle)) {
4191 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
4195 if (!test_SetGroupInfo(p, mem_ctx, group_handle)) {
4204 its not totally clear what this does. It seems to accept any sid you like.
4206 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p,
4207 TALLOC_CTX *mem_ctx,
4208 struct policy_handle *domain_handle)
4211 struct samr_RemoveMemberFromForeignDomain r;
4213 r.in.domain_handle = domain_handle;
4214 r.in.sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-12-34-56-78");
4216 status = dcerpc_samr_RemoveMemberFromForeignDomain(p, mem_ctx, &r);
4217 if (!NT_STATUS_IS_OK(status)) {
4218 printf("RemoveMemberFromForeignDomain failed - %s\n", nt_errstr(status));
4227 static bool test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4228 struct policy_handle *handle);
4230 static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
4231 struct policy_handle *handle, struct dom_sid *sid,
4232 enum torture_samr_choice which_ops)
4235 struct samr_OpenDomain r;
4236 struct policy_handle domain_handle;
4237 struct policy_handle alias_handle;
4238 struct policy_handle user_handle;
4239 struct policy_handle group_handle;
4242 ZERO_STRUCT(alias_handle);
4243 ZERO_STRUCT(user_handle);
4244 ZERO_STRUCT(group_handle);
4245 ZERO_STRUCT(domain_handle);
4247 printf("Testing OpenDomain\n");
4249 r.in.connect_handle = handle;
4250 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4252 r.out.domain_handle = &domain_handle;
4254 status = dcerpc_samr_OpenDomain(p, tctx, &r);
4255 if (!NT_STATUS_IS_OK(status)) {
4256 printf("OpenDomain failed - %s\n", nt_errstr(status));
4260 /* run the domain tests with the main handle closed - this tests
4261 the servers reference counting */
4262 ret &= test_samr_handle_Close(p, tctx, handle);
4264 switch (which_ops) {
4265 case TORTURE_SAMR_USER_ATTRIBUTES:
4266 case TORTURE_SAMR_PASSWORDS:
4267 ret &= test_CreateUser2(p, tctx, &domain_handle, which_ops);
4268 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, which_ops);
4269 /* This test needs 'complex' users to validate */
4270 ret &= test_QueryDisplayInfo(p, tctx, &domain_handle);
4272 case TORTURE_SAMR_OTHER:
4273 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, which_ops);
4274 ret &= test_QuerySecurity(p, tctx, &domain_handle);
4275 ret &= test_RemoveMemberFromForeignDomain(p, tctx, &domain_handle);
4276 ret &= test_CreateAlias(p, tctx, &domain_handle, &alias_handle, sid);
4277 ret &= test_CreateDomainGroup(p, tctx, &domain_handle, &group_handle);
4278 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
4279 ret &= test_QueryDomainInfo2(p, tctx, &domain_handle);
4280 ret &= test_EnumDomainUsers(p, tctx, &domain_handle);
4281 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
4282 ret &= test_EnumDomainGroups(p, tctx, &domain_handle);
4283 ret &= test_EnumDomainAliases(p, tctx, &domain_handle);
4284 ret &= test_QueryDisplayInfo2(p, tctx, &domain_handle);
4285 ret &= test_QueryDisplayInfo3(p, tctx, &domain_handle);
4286 ret &= test_QueryDisplayInfo_continue(p, tctx, &domain_handle);
4288 if (torture_setting_bool(tctx, "samba4", false)) {
4289 printf("skipping GetDisplayEnumerationIndex test against Samba4\n");
4291 ret &= test_GetDisplayEnumerationIndex(p, tctx, &domain_handle);
4292 ret &= test_GetDisplayEnumerationIndex2(p, tctx, &domain_handle);
4294 ret &= test_GroupList(p, tctx, &domain_handle);
4295 ret &= test_TestPrivateFunctionsDomain(p, tctx, &domain_handle);
4296 ret &= test_RidToSid(p, tctx, sid, &domain_handle);
4297 ret &= test_GetBootKeyInformation(p, tctx, &domain_handle);
4301 if (!policy_handle_empty(&user_handle) &&
4302 !test_DeleteUser(p, tctx, &user_handle)) {
4306 if (!policy_handle_empty(&alias_handle) &&
4307 !test_DeleteAlias(p, tctx, &alias_handle)) {
4311 if (!policy_handle_empty(&group_handle) &&
4312 !test_DeleteDomainGroup(p, tctx, &group_handle)) {
4316 ret &= test_samr_handle_Close(p, tctx, &domain_handle);
4318 /* reconnect the main handle */
4319 ret &= test_Connect(p, tctx, handle);
4322 printf("Testing domain %s failed!\n", dom_sid_string(tctx, sid));
4328 static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
4329 struct policy_handle *handle, const char *domain,
4330 enum torture_samr_choice which_ops)
4333 struct samr_LookupDomain r;
4334 struct lsa_String n1;
4335 struct lsa_String n2;
4338 printf("Testing LookupDomain(%s)\n", domain);
4340 /* check for correct error codes */
4341 r.in.connect_handle = handle;
4342 r.in.domain_name = &n2;
4345 status = dcerpc_samr_LookupDomain(p, tctx, &r);
4346 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_PARAMETER, status)) {
4347 printf("failed: LookupDomain expected NT_STATUS_INVALID_PARAMETER - %s\n", nt_errstr(status));
4351 init_lsa_String(&n2, "xxNODOMAINxx");
4353 status = dcerpc_samr_LookupDomain(p, tctx, &r);
4354 if (!NT_STATUS_EQUAL(NT_STATUS_NO_SUCH_DOMAIN, status)) {
4355 printf("failed: LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN - %s\n", nt_errstr(status));
4359 r.in.connect_handle = handle;
4361 init_lsa_String(&n1, domain);
4362 r.in.domain_name = &n1;
4364 status = dcerpc_samr_LookupDomain(p, tctx, &r);
4365 if (!NT_STATUS_IS_OK(status)) {
4366 printf("LookupDomain failed - %s\n", nt_errstr(status));
4370 if (!test_GetDomPwInfo(p, tctx, &n1)) {
4374 if (!test_OpenDomain(p, tctx, handle, r.out.sid, which_ops)) {
4382 static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
4383 struct policy_handle *handle, enum torture_samr_choice which_ops)
4386 struct samr_EnumDomains r;
4387 uint32_t resume_handle = 0;
4391 r.in.connect_handle = handle;
4392 r.in.resume_handle = &resume_handle;
4393 r.in.buf_size = (uint32_t)-1;
4394 r.out.resume_handle = &resume_handle;
4396 status = dcerpc_samr_EnumDomains(p, tctx, &r);
4397 if (!NT_STATUS_IS_OK(status)) {
4398 printf("EnumDomains failed - %s\n", nt_errstr(status));
4406 for (i=0;i<r.out.sam->count;i++) {
4407 if (!test_LookupDomain(p, tctx, handle,
4408 r.out.sam->entries[i].name.string, which_ops)) {
4413 status = dcerpc_samr_EnumDomains(p, tctx, &r);
4414 if (!NT_STATUS_IS_OK(status)) {
4415 printf("EnumDomains failed - %s\n", nt_errstr(status));
4423 static bool test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4424 struct policy_handle *handle)
4427 struct samr_Connect r;
4428 struct samr_Connect2 r2;
4429 struct samr_Connect3 r3;
4430 struct samr_Connect4 r4;
4431 struct samr_Connect5 r5;
4432 union samr_ConnectInfo info;
4433 struct policy_handle h;
4434 bool ret = true, got_handle = false;
4436 printf("testing samr_Connect\n");
4438 r.in.system_name = 0;
4439 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4440 r.out.connect_handle = &h;
4442 status = dcerpc_samr_Connect(p, mem_ctx, &r);
4443 if (!NT_STATUS_IS_OK(status)) {
4444 printf("Connect failed - %s\n", nt_errstr(status));
4451 printf("testing samr_Connect2\n");
4453 r2.in.system_name = NULL;
4454 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4455 r2.out.connect_handle = &h;
4457 status = dcerpc_samr_Connect2(p, mem_ctx, &r2);
4458 if (!NT_STATUS_IS_OK(status)) {
4459 printf("Connect2 failed - %s\n", nt_errstr(status));
4463 test_samr_handle_Close(p, mem_ctx, handle);
4469 printf("testing samr_Connect3\n");
4471 r3.in.system_name = NULL;
4473 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4474 r3.out.connect_handle = &h;
4476 status = dcerpc_samr_Connect3(p, mem_ctx, &r3);
4477 if (!NT_STATUS_IS_OK(status)) {
4478 printf("Connect3 failed - %s\n", nt_errstr(status));
4482 test_samr_handle_Close(p, mem_ctx, handle);
4488 printf("testing samr_Connect4\n");
4490 r4.in.system_name = "";
4492 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4493 r4.out.connect_handle = &h;
4495 status = dcerpc_samr_Connect4(p, mem_ctx, &r4);
4496 if (!NT_STATUS_IS_OK(status)) {
4497 printf("Connect4 failed - %s\n", nt_errstr(status));
4501 test_samr_handle_Close(p, mem_ctx, handle);
4507 printf("testing samr_Connect5\n");
4509 info.info1.unknown1 = 0;
4510 info.info1.unknown2 = 0;
4512 r5.in.system_name = "";
4513 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4516 r5.out.info = &info;
4517 r5.out.connect_handle = &h;
4519 status = dcerpc_samr_Connect5(p, mem_ctx, &r5);
4520 if (!NT_STATUS_IS_OK(status)) {
4521 printf("Connect5 failed - %s\n", nt_errstr(status));
4525 test_samr_handle_Close(p, mem_ctx, handle);
4535 bool torture_rpc_samr(struct torture_context *torture)
4538 struct dcerpc_pipe *p;
4540 struct policy_handle handle;
4542 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4543 if (!NT_STATUS_IS_OK(status)) {
4547 ret &= test_Connect(p, torture, &handle);
4549 ret &= test_QuerySecurity(p, torture, &handle);
4551 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_OTHER);
4553 ret &= test_SetDsrmPassword(p, torture, &handle);
4555 ret &= test_Shutdown(p, torture, &handle);
4557 ret &= test_samr_handle_Close(p, torture, &handle);
4563 bool torture_rpc_samr_users(struct torture_context *torture)
4566 struct dcerpc_pipe *p;
4568 struct policy_handle handle;
4570 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4571 if (!NT_STATUS_IS_OK(status)) {
4575 ret &= test_Connect(p, torture, &handle);
4577 ret &= test_QuerySecurity(p, torture, &handle);
4579 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_USER_ATTRIBUTES);
4581 ret &= test_SetDsrmPassword(p, torture, &handle);
4583 ret &= test_Shutdown(p, torture, &handle);
4585 ret &= test_samr_handle_Close(p, torture, &handle);
4591 bool torture_rpc_samr_passwords(struct torture_context *torture)
4594 struct dcerpc_pipe *p;
4596 struct policy_handle handle;
4598 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4599 if (!NT_STATUS_IS_OK(status)) {
4603 ret &= test_Connect(p, torture, &handle);
4605 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_PASSWORDS);
4607 ret &= test_samr_handle_Close(p, torture, &handle);