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 2 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, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #include "torture/torture.h"
25 #include "system/time.h"
26 #include "librpc/gen_ndr/lsa.h"
27 #include "librpc/gen_ndr/ndr_samr_c.h"
29 #include "lib/crypto/crypto.h"
30 #include "libcli/auth/libcli_auth.h"
31 #include "libcli/security/security.h"
32 #include "torture/rpc/rpc.h"
34 #define TEST_ACCOUNT_NAME "samrtorturetest"
35 #define TEST_ALIASNAME "samrtorturetestalias"
36 #define TEST_GROUPNAME "samrtorturetestgroup"
37 #define TEST_MACHINENAME "samrtestmach$"
38 #define TEST_DOMAINNAME "samrtestdom$"
40 enum torture_samr_choice {
41 TORTURE_SAMR_PASSWORDS,
42 TORTURE_SAMR_USER_ATTRIBUTES,
46 static BOOL test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
47 struct policy_handle *handle);
49 static BOOL test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
50 struct policy_handle *handle);
52 static BOOL test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
53 struct policy_handle *handle);
55 static BOOL test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
56 const char *acct_name,
57 struct policy_handle *domain_handle, char **password);
59 static void init_lsa_String(struct lsa_String *string, const char *s)
64 BOOL test_samr_handle_Close(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
65 struct policy_handle *handle)
71 r.out.handle = handle;
73 status = dcerpc_samr_Close(p, mem_ctx, &r);
74 if (!NT_STATUS_IS_OK(status)) {
75 printf("Close handle failed - %s\n", nt_errstr(status));
82 static BOOL test_Shutdown(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
83 struct policy_handle *handle)
86 struct samr_Shutdown r;
88 if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
89 printf("samr_Shutdown disabled - enable dangerous tests to use\n");
93 r.in.connect_handle = handle;
95 printf("testing samr_Shutdown\n");
97 status = dcerpc_samr_Shutdown(p, mem_ctx, &r);
98 if (!NT_STATUS_IS_OK(status)) {
99 printf("samr_Shutdown failed - %s\n", nt_errstr(status));
106 static BOOL test_SetDsrmPassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
107 struct policy_handle *handle)
110 struct samr_SetDsrmPassword r;
111 struct lsa_String string;
112 struct samr_Password hash;
114 if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
115 printf("samr_SetDsrmPassword disabled - enable dangerous tests to use\n");
119 E_md4hash("TeSTDSRM123", hash.hash);
121 init_lsa_String(&string, "Administrator");
127 printf("testing samr_SetDsrmPassword\n");
129 status = dcerpc_samr_SetDsrmPassword(p, mem_ctx, &r);
130 if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
131 printf("samr_SetDsrmPassword failed - %s\n", nt_errstr(status));
139 static BOOL test_QuerySecurity(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
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, mem_ctx, &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 (lp_parm_bool(-1, "target", "samba4", False)) {
164 printf("skipping SetSecurity test against Samba4\n");
168 status = dcerpc_samr_SetSecurity(p, mem_ctx, &s);
169 if (!NT_STATUS_IS_OK(status)) {
170 printf("SetSecurity failed - %s\n", nt_errstr(status));
174 status = dcerpc_samr_QuerySecurity(p, mem_ctx, &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, TALLOC_CTX *mem_ctx,
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, mem_ctx, &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%x - got 0x%x (%s)\n", \
233 #field, i2, 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(mem_ctx, "%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(mem_ctx, "%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(mem_ctx, "%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(mem_ctx, "%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(mem_ctx, "%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(mem_ctx, "%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(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
330 TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
331 TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
332 TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script",
333 SAMR_FIELD_LOGON_SCRIPT);
335 TEST_USERINFO_STRING(12, profile_path, 3, profile_path, "xx12-3 profile_path", 0);
336 TEST_USERINFO_STRING(12, profile_path, 5, profile_path, "xx12-5 profile_path", 0);
337 TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
338 TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path",
339 SAMR_FIELD_PROFILE_PATH);
341 TEST_USERINFO_STRING(13, description, 1, description, "xx13-1 description", 0);
342 TEST_USERINFO_STRING(13, description, 5, description, "xx13-5 description", 0);
343 TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
344 TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description",
345 SAMR_FIELD_DESCRIPTION);
347 TEST_USERINFO_STRING(14, workstations, 3, workstations, "14workstation3", 0);
348 TEST_USERINFO_STRING(14, workstations, 5, workstations, "14workstation4", 0);
349 TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
350 TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21",
351 SAMR_FIELD_WORKSTATIONS);
353 TEST_USERINFO_STRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
354 TEST_USERINFO_STRING(21, parameters, 21, parameters, "xx21-21 parameters",
355 SAMR_FIELD_PARAMETERS);
357 TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
358 TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__,
359 SAMR_FIELD_COUNTRY_CODE);
361 TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
362 TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__,
363 SAMR_FIELD_CODE_PAGE);
365 TEST_USERINFO_INT(4, logon_hours.bits[3], 3, logon_hours.bits[3], 1, 0);
366 TEST_USERINFO_INT(4, logon_hours.bits[3], 5, logon_hours.bits[3], 2, 0);
367 TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
368 TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4,
369 SAMR_FIELD_LOGON_HOURS);
371 if (lp_parm_bool(-1, "target", "samba4", False)) {
372 printf("skipping Set Account Flag tests against Samba4\n");
376 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
377 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
378 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
380 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
381 (base_acct_flags | ACB_DISABLED),
382 (base_acct_flags | ACB_DISABLED | user_extra_flags),
385 /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
386 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
387 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
388 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
390 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
391 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
392 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
396 /* The 'autolock' flag doesn't stick - check this */
397 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
398 (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK),
399 (base_acct_flags | ACB_DISABLED | user_extra_flags),
402 /* Removing the 'disabled' flag doesn't stick - check this */
403 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
405 (base_acct_flags | ACB_DISABLED | user_extra_flags),
408 /* The 'store plaintext' flag does stick */
409 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
410 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED),
411 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags),
413 /* The 'use DES' flag does stick */
414 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
415 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY),
416 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags),
418 /* The 'don't require kerberos pre-authentication flag does stick */
419 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
420 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH),
421 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags),
423 /* The 'no kerberos PAC required' flag sticks */
424 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
425 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD),
426 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags),
429 TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags,
430 (base_acct_flags | ACB_DISABLED),
431 (base_acct_flags | ACB_DISABLED | user_extra_flags),
432 SAMR_FIELD_ACCT_FLAGS);
435 /* these fail with win2003 - it appears you can't set the primary gid?
436 the set succeeds, but the gid isn't changed. Very weird! */
437 TEST_USERINFO_INT(9, primary_gid, 1, primary_gid, 513);
438 TEST_USERINFO_INT(9, primary_gid, 3, primary_gid, 513);
439 TEST_USERINFO_INT(9, primary_gid, 5, primary_gid, 513);
440 TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
447 generate a random password for password change tests
449 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
451 size_t len = MAX(8, min_len) + (random() % 6);
452 char *s = generate_random_str(mem_ctx, len);
453 printf("Generated password '%s'\n", s);
457 static BOOL test_SetUserPass(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
458 struct policy_handle *handle, char **password)
461 struct samr_SetUserInfo s;
462 union samr_UserInfo u;
464 DATA_BLOB session_key;
466 struct samr_GetUserPwInfo pwp;
467 int policy_min_pw_len = 0;
468 pwp.in.user_handle = handle;
470 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
471 if (NT_STATUS_IS_OK(status)) {
472 policy_min_pw_len = pwp.out.info.min_password_length;
474 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
476 s.in.user_handle = handle;
480 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
481 /* w2k3 ignores this length */
482 u.info24.pw_len = strlen_m(newpass) * 2;
484 status = dcerpc_fetch_session_key(p, &session_key);
485 if (!NT_STATUS_IS_OK(status)) {
486 printf("SetUserInfo level %u - no session key - %s\n",
487 s.in.level, nt_errstr(status));
491 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
493 printf("Testing SetUserInfo level 24 (set password)\n");
495 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
496 if (!NT_STATUS_IS_OK(status)) {
497 printf("SetUserInfo level %u failed - %s\n",
498 s.in.level, nt_errstr(status));
508 static BOOL test_SetUserPass_23(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
509 struct policy_handle *handle, uint32_t fields_present,
513 struct samr_SetUserInfo s;
514 union samr_UserInfo u;
516 DATA_BLOB session_key;
518 struct samr_GetUserPwInfo pwp;
519 int policy_min_pw_len = 0;
520 pwp.in.user_handle = handle;
522 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
523 if (NT_STATUS_IS_OK(status)) {
524 policy_min_pw_len = pwp.out.info.min_password_length;
526 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
528 s.in.user_handle = handle;
534 u.info23.info.fields_present = fields_present;
536 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
538 status = dcerpc_fetch_session_key(p, &session_key);
539 if (!NT_STATUS_IS_OK(status)) {
540 printf("SetUserInfo level %u - no session key - %s\n",
541 s.in.level, nt_errstr(status));
545 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
547 printf("Testing SetUserInfo level 23 (set password)\n");
549 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
550 if (!NT_STATUS_IS_OK(status)) {
551 printf("SetUserInfo level %u failed - %s\n",
552 s.in.level, nt_errstr(status));
562 static BOOL test_SetUserPassEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
563 struct policy_handle *handle, char **password)
566 struct samr_SetUserInfo s;
567 union samr_UserInfo u;
569 DATA_BLOB session_key;
570 DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
571 uint8_t confounder[16];
573 struct MD5Context ctx;
574 struct samr_GetUserPwInfo pwp;
575 int policy_min_pw_len = 0;
576 pwp.in.user_handle = handle;
578 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
579 if (NT_STATUS_IS_OK(status)) {
580 policy_min_pw_len = pwp.out.info.min_password_length;
582 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
584 s.in.user_handle = handle;
588 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
589 u.info26.pw_len = strlen(newpass);
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 generate_random_buffer((uint8_t *)confounder, 16);
601 MD5Update(&ctx, confounder, 16);
602 MD5Update(&ctx, session_key.data, session_key.length);
603 MD5Final(confounded_session_key.data, &ctx);
605 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
606 memcpy(&u.info26.password.data[516], confounder, 16);
608 printf("Testing SetUserInfo level 26 (set password ex)\n");
610 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
611 if (!NT_STATUS_IS_OK(status)) {
612 printf("SetUserInfo level %u failed - %s\n",
613 s.in.level, nt_errstr(status));
622 static BOOL test_SetUserPass_25(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
623 struct policy_handle *handle, uint32_t fields_present,
627 struct samr_SetUserInfo s;
628 union samr_UserInfo u;
630 DATA_BLOB session_key;
631 DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
632 struct MD5Context ctx;
633 uint8_t confounder[16];
635 struct samr_GetUserPwInfo pwp;
636 int policy_min_pw_len = 0;
637 pwp.in.user_handle = handle;
639 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
640 if (NT_STATUS_IS_OK(status)) {
641 policy_min_pw_len = pwp.out.info.min_password_length;
643 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
645 s.in.user_handle = handle;
651 u.info25.info.fields_present = fields_present;
653 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
655 status = dcerpc_fetch_session_key(p, &session_key);
656 if (!NT_STATUS_IS_OK(status)) {
657 printf("SetUserInfo level %u - no session key - %s\n",
658 s.in.level, nt_errstr(status));
662 generate_random_buffer((uint8_t *)confounder, 16);
665 MD5Update(&ctx, confounder, 16);
666 MD5Update(&ctx, session_key.data, session_key.length);
667 MD5Final(confounded_session_key.data, &ctx);
669 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
670 memcpy(&u.info25.password.data[516], confounder, 16);
672 printf("Testing SetUserInfo level 25 (set password ex)\n");
674 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
675 if (!NT_STATUS_IS_OK(status)) {
676 printf("SetUserInfo level %u failed - %s\n",
677 s.in.level, nt_errstr(status));
686 static BOOL test_SetAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
687 struct policy_handle *handle)
690 struct samr_SetAliasInfo r;
691 struct samr_QueryAliasInfo q;
692 uint16_t levels[] = {2, 3};
696 /* Ignoring switch level 1, as that includes the number of members for the alias
697 * and setting this to a wrong value might have negative consequences
700 for (i=0;i<ARRAY_SIZE(levels);i++) {
701 printf("Testing SetAliasInfo level %u\n", levels[i]);
703 r.in.alias_handle = handle;
704 r.in.level = levels[i];
705 r.in.info = talloc(mem_ctx, union samr_AliasInfo);
706 switch (r.in.level) {
707 case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
708 case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
709 "Test Description, should test I18N as well"); break;
712 status = dcerpc_samr_SetAliasInfo(p, mem_ctx, &r);
713 if (!NT_STATUS_IS_OK(status)) {
714 printf("SetAliasInfo level %u failed - %s\n",
715 levels[i], nt_errstr(status));
719 q.in.alias_handle = handle;
720 q.in.level = levels[i];
722 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &q);
723 if (!NT_STATUS_IS_OK(status)) {
724 printf("QueryAliasInfo level %u failed - %s\n",
725 levels[i], nt_errstr(status));
733 static BOOL test_GetGroupsForUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
734 struct policy_handle *user_handle)
736 struct samr_GetGroupsForUser r;
740 printf("testing GetGroupsForUser\n");
742 r.in.user_handle = user_handle;
744 status = dcerpc_samr_GetGroupsForUser(p, mem_ctx, &r);
745 if (!NT_STATUS_IS_OK(status)) {
746 printf("GetGroupsForUser failed - %s\n",nt_errstr(status));
754 static BOOL test_GetDomPwInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
755 struct lsa_String *domain_name)
758 struct samr_GetDomPwInfo r;
761 r.in.domain_name = domain_name;
762 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
764 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
765 if (!NT_STATUS_IS_OK(status)) {
766 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
770 r.in.domain_name->string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
771 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
773 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
774 if (!NT_STATUS_IS_OK(status)) {
775 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
779 r.in.domain_name->string = "\\\\__NONAME__";
780 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
782 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
783 if (!NT_STATUS_IS_OK(status)) {
784 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
788 r.in.domain_name->string = "\\\\Builtin";
789 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
791 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
792 if (!NT_STATUS_IS_OK(status)) {
793 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
801 static BOOL test_GetUserPwInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
802 struct policy_handle *handle)
805 struct samr_GetUserPwInfo r;
808 printf("Testing GetUserPwInfo\n");
810 r.in.user_handle = handle;
812 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &r);
813 if (!NT_STATUS_IS_OK(status)) {
814 printf("GetUserPwInfo failed - %s\n", nt_errstr(status));
821 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
822 struct policy_handle *domain_handle, const char *name,
826 struct samr_LookupNames n;
827 struct lsa_String sname[2];
829 init_lsa_String(&sname[0], name);
831 n.in.domain_handle = domain_handle;
834 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
835 if (NT_STATUS_IS_OK(status)) {
836 *rid = n.out.rids.ids[0];
841 init_lsa_String(&sname[1], "xxNONAMExx");
843 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
844 if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
845 printf("LookupNames[2] failed - %s\n", nt_errstr(status));
849 init_lsa_String(&sname[1], "xxNONAMExx");
851 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
852 if (!NT_STATUS_IS_OK(status)) {
853 printf("LookupNames[0] failed - %s\n", nt_errstr(status));
859 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
860 struct policy_handle *domain_handle,
861 const char *name, struct policy_handle *user_handle)
864 struct samr_OpenUser r;
867 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
868 if (!NT_STATUS_IS_OK(status)) {
872 r.in.domain_handle = domain_handle;
873 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
875 r.out.user_handle = user_handle;
876 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
877 if (!NT_STATUS_IS_OK(status)) {
878 printf("OpenUser_byname(%s) failed - %s\n", name, nt_errstr(status));
885 static BOOL test_ChangePasswordNT3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
886 struct policy_handle *handle)
889 struct samr_ChangePasswordUser r;
891 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
892 struct policy_handle user_handle;
893 char *oldpass = "test";
894 char *newpass = "test2";
895 uint8_t old_nt_hash[16], new_nt_hash[16];
896 uint8_t old_lm_hash[16], new_lm_hash[16];
898 status = test_OpenUser_byname(p, mem_ctx, handle, "testuser", &user_handle);
899 if (!NT_STATUS_IS_OK(status)) {
903 printf("Testing ChangePasswordUser for user 'testuser'\n");
905 printf("old password: %s\n", oldpass);
906 printf("new password: %s\n", newpass);
908 E_md4hash(oldpass, old_nt_hash);
909 E_md4hash(newpass, new_nt_hash);
910 E_deshash(oldpass, old_lm_hash);
911 E_deshash(newpass, new_lm_hash);
913 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
914 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
915 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
916 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
917 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
918 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
920 r.in.handle = &user_handle;
922 r.in.old_lm_crypted = &hash1;
923 r.in.new_lm_crypted = &hash2;
925 r.in.old_nt_crypted = &hash3;
926 r.in.new_nt_crypted = &hash4;
927 r.in.cross1_present = 1;
928 r.in.nt_cross = &hash5;
929 r.in.cross2_present = 1;
930 r.in.lm_cross = &hash6;
932 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
933 if (!NT_STATUS_IS_OK(status)) {
934 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
938 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
946 static BOOL test_ChangePasswordUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
947 const char *acct_name,
948 struct policy_handle *handle, char **password)
951 struct samr_ChangePasswordUser r;
953 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
954 struct policy_handle user_handle;
956 uint8_t old_nt_hash[16], new_nt_hash[16];
957 uint8_t old_lm_hash[16], new_lm_hash[16];
960 struct samr_GetUserPwInfo pwp;
961 int policy_min_pw_len = 0;
963 status = test_OpenUser_byname(p, mem_ctx, handle, acct_name, &user_handle);
964 if (!NT_STATUS_IS_OK(status)) {
967 pwp.in.user_handle = &user_handle;
969 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
970 if (NT_STATUS_IS_OK(status)) {
971 policy_min_pw_len = pwp.out.info.min_password_length;
973 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
975 printf("Testing ChangePasswordUser\n");
978 printf("Failing ChangePasswordUser as old password was NULL. Previous test failed?\n");
984 E_md4hash(oldpass, old_nt_hash);
985 E_md4hash(newpass, new_nt_hash);
986 E_deshash(oldpass, old_lm_hash);
987 E_deshash(newpass, new_lm_hash);
989 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
990 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
991 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
992 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
993 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
994 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
996 r.in.user_handle = &user_handle;
998 r.in.old_lm_crypted = &hash1;
999 r.in.new_lm_crypted = &hash2;
1000 r.in.nt_present = 1;
1001 r.in.old_nt_crypted = &hash3;
1002 r.in.new_nt_crypted = &hash4;
1003 r.in.cross1_present = 1;
1004 r.in.nt_cross = &hash5;
1005 r.in.cross2_present = 1;
1006 r.in.lm_cross = &hash6;
1008 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1009 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1010 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1011 } else if (!NT_STATUS_IS_OK(status)) {
1012 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1015 *password = newpass;
1018 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1026 static BOOL test_OemChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1027 const char *acct_name,
1028 struct policy_handle *handle, char **password)
1031 struct samr_OemChangePasswordUser2 r;
1033 struct samr_Password lm_verifier;
1034 struct samr_CryptPassword lm_pass;
1035 struct lsa_AsciiString server, account, account_bad;
1038 uint8_t old_lm_hash[16], new_lm_hash[16];
1040 struct samr_GetDomPwInfo dom_pw_info;
1041 int policy_min_pw_len = 0;
1043 struct lsa_String domain_name;
1045 domain_name.string = "";
1046 dom_pw_info.in.domain_name = &domain_name;
1048 printf("Testing OemChangePasswordUser2\n");
1051 printf("Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?\n");
1055 oldpass = *password;
1057 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &dom_pw_info);
1058 if (NT_STATUS_IS_OK(status)) {
1059 policy_min_pw_len = dom_pw_info.out.info.min_password_length;
1062 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1064 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1065 account.string = acct_name;
1067 E_deshash(oldpass, old_lm_hash);
1068 E_deshash(newpass, new_lm_hash);
1070 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1071 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1072 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1074 r.in.server = &server;
1075 r.in.account = &account;
1076 r.in.password = &lm_pass;
1077 r.in.hash = &lm_verifier;
1079 /* Break the verification */
1080 lm_verifier.hash[0]++;
1082 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1084 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1085 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1086 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1091 /* This shouldn't be a valid name */
1092 account_bad.string = TEST_ACCOUNT_NAME "XX";
1093 r.in.account = &account_bad;
1095 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1097 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1098 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1103 E_deshash(oldpass, old_lm_hash);
1104 E_deshash(newpass, new_lm_hash);
1106 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1107 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1108 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1110 r.in.server = &server;
1111 r.in.account = &account;
1112 r.in.password = &lm_pass;
1113 r.in.hash = &lm_verifier;
1115 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1116 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1117 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1118 } else if (!NT_STATUS_IS_OK(status)) {
1119 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
1122 *password = newpass;
1129 static BOOL test_ChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1130 const char *acct_name,
1131 struct policy_handle *handle, char **password)
1134 struct samr_ChangePasswordUser2 r;
1136 struct lsa_String server, account;
1137 struct samr_CryptPassword nt_pass, lm_pass;
1138 struct samr_Password nt_verifier, lm_verifier;
1141 uint8_t old_nt_hash[16], new_nt_hash[16];
1142 uint8_t old_lm_hash[16], new_lm_hash[16];
1144 struct samr_GetDomPwInfo dom_pw_info;
1145 int policy_min_pw_len = 0;
1147 struct lsa_String domain_name;
1150 domain_name.string = "";
1151 dom_pw_info.in.domain_name = &domain_name;
1153 printf("Testing ChangePasswordUser2\n");
1156 printf("Failing ChangePasswordUser3 as old password was NULL. Previous test failed?\n");
1159 oldpass = *password;
1161 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &dom_pw_info);
1162 if (NT_STATUS_IS_OK(status)) {
1163 policy_min_pw_len = dom_pw_info.out.info.min_password_length;
1166 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1168 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1169 init_lsa_String(&account, acct_name);
1171 E_md4hash(oldpass, old_nt_hash);
1172 E_md4hash(newpass, new_nt_hash);
1174 E_deshash(oldpass, old_lm_hash);
1175 E_deshash(newpass, new_lm_hash);
1177 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
1178 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1179 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1181 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1182 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1183 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1185 r.in.server = &server;
1186 r.in.account = &account;
1187 r.in.nt_password = &nt_pass;
1188 r.in.nt_verifier = &nt_verifier;
1190 r.in.lm_password = &lm_pass;
1191 r.in.lm_verifier = &lm_verifier;
1193 status = dcerpc_samr_ChangePasswordUser2(p, mem_ctx, &r);
1194 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1195 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1196 } else if (!NT_STATUS_IS_OK(status)) {
1197 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
1200 *password = newpass;
1207 BOOL test_ChangePasswordUser3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1208 const char *account_string,
1209 int policy_min_pw_len,
1213 struct samr_ChangePasswordUser3 r;
1215 struct lsa_String server, account, account_bad;
1216 struct samr_CryptPassword nt_pass, lm_pass;
1217 struct samr_Password nt_verifier, lm_verifier;
1219 char *newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1220 uint8_t old_nt_hash[16], new_nt_hash[16];
1221 uint8_t old_lm_hash[16], new_lm_hash[16];
1223 printf("Testing ChangePasswordUser3\n");
1226 printf("Failing ChangePasswordUser3 as old password was NULL. Previous test failed?\n");
1230 oldpass = *password;
1231 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1232 init_lsa_String(&account, account_string);
1234 E_md4hash(oldpass, old_nt_hash);
1235 E_md4hash(newpass, new_nt_hash);
1237 E_deshash(oldpass, old_lm_hash);
1238 E_deshash(newpass, new_lm_hash);
1240 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1241 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1242 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1244 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1245 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1246 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1248 /* Break the verification */
1249 nt_verifier.hash[0]++;
1251 r.in.server = &server;
1252 r.in.account = &account;
1253 r.in.nt_password = &nt_pass;
1254 r.in.nt_verifier = &nt_verifier;
1256 r.in.lm_password = &lm_pass;
1257 r.in.lm_verifier = &lm_verifier;
1258 r.in.password3 = NULL;
1260 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1261 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1262 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1263 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1268 /* This shouldn't be a valid name */
1269 init_lsa_String(&account_bad, talloc_asprintf(mem_ctx, "%sXX", account_string));
1271 r.in.account = &account_bad;
1272 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1273 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1274 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
1279 E_md4hash(oldpass, old_nt_hash);
1280 E_md4hash(newpass, new_nt_hash);
1282 E_deshash(oldpass, old_lm_hash);
1283 E_deshash(newpass, new_lm_hash);
1285 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1286 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1287 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1289 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1290 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1291 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1293 r.in.server = &server;
1294 r.in.account = &account;
1295 r.in.nt_password = &nt_pass;
1296 r.in.nt_verifier = &nt_verifier;
1298 r.in.lm_password = &lm_pass;
1299 r.in.lm_verifier = &lm_verifier;
1300 r.in.password3 = NULL;
1302 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1303 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1304 && !policy_min_pw_len) {
1305 if (r.out.dominfo) {
1306 policy_min_pw_len = r.out.dominfo->min_password_length;
1308 if (policy_min_pw_len) /* try again with the right min password length */ {
1309 ret = test_ChangePasswordUser3(p, mem_ctx, account_string, policy_min_pw_len, password);
1311 printf("ChangePasswordUser3 failed (no min length known) - %s\n", nt_errstr(status));
1314 } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1315 printf("ChangePasswordUser3 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1316 } else if (!NT_STATUS_IS_OK(status)) {
1317 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
1320 *password = newpass;
1327 static BOOL test_GetMembersInAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1328 struct policy_handle *alias_handle)
1330 struct samr_GetMembersInAlias r;
1331 struct lsa_SidArray sids;
1335 printf("Testing GetMembersInAlias\n");
1337 r.in.alias_handle = alias_handle;
1340 status = dcerpc_samr_GetMembersInAlias(p, mem_ctx, &r);
1341 if (!NT_STATUS_IS_OK(status)) {
1342 printf("GetMembersInAlias failed - %s\n",
1350 static BOOL test_AddMemberToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1351 struct policy_handle *alias_handle,
1352 const struct dom_sid *domain_sid)
1354 struct samr_AddAliasMember r;
1355 struct samr_DeleteAliasMember d;
1358 struct dom_sid *sid;
1360 sid = dom_sid_add_rid(mem_ctx, domain_sid, 512);
1362 printf("testing AddAliasMember\n");
1363 r.in.alias_handle = alias_handle;
1366 status = dcerpc_samr_AddAliasMember(p, mem_ctx, &r);
1367 if (!NT_STATUS_IS_OK(status)) {
1368 printf("AddAliasMember failed - %s\n", nt_errstr(status));
1372 d.in.alias_handle = alias_handle;
1375 status = dcerpc_samr_DeleteAliasMember(p, mem_ctx, &d);
1376 if (!NT_STATUS_IS_OK(status)) {
1377 printf("DelAliasMember failed - %s\n", nt_errstr(status));
1384 static BOOL test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1385 struct policy_handle *alias_handle)
1387 struct samr_AddMultipleMembersToAlias a;
1388 struct samr_RemoveMultipleMembersFromAlias r;
1391 struct lsa_SidArray sids;
1393 printf("testing AddMultipleMembersToAlias\n");
1394 a.in.alias_handle = alias_handle;
1398 sids.sids = talloc_array(mem_ctx, struct lsa_SidPtr, 3);
1400 sids.sids[0].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-1");
1401 sids.sids[1].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-2");
1402 sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-3");
1404 status = dcerpc_samr_AddMultipleMembersToAlias(p, mem_ctx, &a);
1405 if (!NT_STATUS_IS_OK(status)) {
1406 printf("AddMultipleMembersToAlias failed - %s\n", nt_errstr(status));
1411 printf("testing RemoveMultipleMembersFromAlias\n");
1412 r.in.alias_handle = alias_handle;
1415 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1416 if (!NT_STATUS_IS_OK(status)) {
1417 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1421 /* strange! removing twice doesn't give any error */
1422 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1423 if (!NT_STATUS_IS_OK(status)) {
1424 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1428 /* but removing an alias that isn't there does */
1429 sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-4");
1431 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1432 if (!NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_NOT_FOUND, status)) {
1433 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1440 static BOOL test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1441 struct policy_handle *user_handle)
1443 struct samr_TestPrivateFunctionsUser r;
1447 printf("Testing TestPrivateFunctionsUser\n");
1449 r.in.user_handle = user_handle;
1451 status = dcerpc_samr_TestPrivateFunctionsUser(p, mem_ctx, &r);
1452 if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
1453 printf("TestPrivateFunctionsUser failed - %s\n", nt_errstr(status));
1461 static BOOL test_user_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1462 struct policy_handle *user_handle,
1463 struct policy_handle *domain_handle,
1464 uint32_t base_acct_flags,
1465 const char *base_acct_name, enum torture_samr_choice which_ops)
1467 TALLOC_CTX *user_ctx;
1468 char *password = NULL;
1472 const uint32_t password_fields[] = {
1473 SAMR_FIELD_PASSWORD,
1474 SAMR_FIELD_PASSWORD2,
1475 SAMR_FIELD_PASSWORD | SAMR_FIELD_PASSWORD2,
1479 user_ctx = talloc_named(mem_ctx, 0, "test_user_ops per-user context");
1480 switch (which_ops) {
1481 case TORTURE_SAMR_USER_ATTRIBUTES:
1482 if (!test_QuerySecurity(p, user_ctx, user_handle)) {
1486 if (!test_QueryUserInfo(p, user_ctx, user_handle)) {
1490 if (!test_QueryUserInfo2(p, user_ctx, user_handle)) {
1494 if (!test_SetUserInfo(p, user_ctx, user_handle, base_acct_flags,
1499 if (!test_GetUserPwInfo(p, user_ctx, user_handle)) {
1503 if (!test_TestPrivateFunctionsUser(p, user_ctx, user_handle)) {
1507 if (!test_SetUserPass(p, user_ctx, user_handle, &password)) {
1511 case TORTURE_SAMR_PASSWORDS:
1512 for (i = 0; password_fields[i]; i++) {
1513 if (!test_SetUserPass_23(p, user_ctx, user_handle, password_fields[i], &password)) {
1517 /* check it was set right */
1518 if (!test_ChangePasswordUser3(p, user_ctx, base_acct_name, 0, &password)) {
1523 for (i = 0; password_fields[i]; i++) {
1524 if (!test_SetUserPass_25(p, user_ctx, user_handle, password_fields[i], &password)) {
1528 /* check it was set right */
1529 if (!test_ChangePasswordUser3(p, user_ctx, base_acct_name, 0, &password)) {
1534 if (!test_SetUserPassEx(p, user_ctx, user_handle, &password)) {
1538 if (!test_ChangePassword(p, user_ctx, base_acct_name, domain_handle, &password)) {
1542 case TORTURE_SAMR_OTHER:
1546 talloc_free(user_ctx);
1550 static BOOL test_alias_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1551 struct policy_handle *alias_handle,
1552 const struct dom_sid *domain_sid)
1556 if (!test_QuerySecurity(p, mem_ctx, alias_handle)) {
1560 if (!test_QueryAliasInfo(p, mem_ctx, alias_handle)) {
1564 if (!test_SetAliasInfo(p, mem_ctx, alias_handle)) {
1568 if (!test_AddMemberToAlias(p, mem_ctx, alias_handle, domain_sid)) {
1572 if (lp_parm_bool(-1, "target", "samba4", False)) {
1573 printf("skipping MultipleMembers Alias tests against Samba4\n");
1577 if (!test_AddMultipleMembersToAlias(p, mem_ctx, alias_handle)) {
1585 BOOL test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1586 struct policy_handle *handle, const char *name)
1589 struct samr_DeleteUser d;
1590 struct policy_handle user_handle;
1593 status = test_LookupName(p, mem_ctx, handle, name, &rid);
1594 if (!NT_STATUS_IS_OK(status)) {
1598 status = test_OpenUser_byname(p, mem_ctx, handle, name, &user_handle);
1599 if (!NT_STATUS_IS_OK(status)) {
1603 d.in.user_handle = &user_handle;
1604 d.out.user_handle = &user_handle;
1605 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
1606 if (!NT_STATUS_IS_OK(status)) {
1613 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
1618 static BOOL test_DeleteGroup_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1619 struct policy_handle *handle, const char *name)
1622 struct samr_OpenGroup r;
1623 struct samr_DeleteDomainGroup d;
1624 struct policy_handle group_handle;
1627 status = test_LookupName(p, mem_ctx, handle, name, &rid);
1628 if (!NT_STATUS_IS_OK(status)) {
1632 r.in.domain_handle = handle;
1633 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1635 r.out.group_handle = &group_handle;
1636 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
1637 if (!NT_STATUS_IS_OK(status)) {
1641 d.in.group_handle = &group_handle;
1642 d.out.group_handle = &group_handle;
1643 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
1644 if (!NT_STATUS_IS_OK(status)) {
1651 printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
1656 static BOOL test_DeleteAlias_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1657 struct policy_handle *domain_handle, const char *name)
1660 struct samr_OpenAlias r;
1661 struct samr_DeleteDomAlias d;
1662 struct policy_handle alias_handle;
1665 printf("testing DeleteAlias_byname\n");
1667 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
1668 if (!NT_STATUS_IS_OK(status)) {
1672 r.in.domain_handle = domain_handle;
1673 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1675 r.out.alias_handle = &alias_handle;
1676 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
1677 if (!NT_STATUS_IS_OK(status)) {
1681 d.in.alias_handle = &alias_handle;
1682 d.out.alias_handle = &alias_handle;
1683 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
1684 if (!NT_STATUS_IS_OK(status)) {
1691 printf("DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
1695 static BOOL test_DeleteAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1696 struct policy_handle *alias_handle)
1698 struct samr_DeleteDomAlias d;
1701 printf("Testing DeleteAlias\n");
1703 d.in.alias_handle = alias_handle;
1704 d.out.alias_handle = alias_handle;
1706 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
1707 if (!NT_STATUS_IS_OK(status)) {
1708 printf("DeleteAlias failed - %s\n", nt_errstr(status));
1715 static BOOL test_CreateAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1716 struct policy_handle *domain_handle,
1717 struct policy_handle *alias_handle,
1718 const struct dom_sid *domain_sid)
1721 struct samr_CreateDomAlias r;
1722 struct lsa_String name;
1726 init_lsa_String(&name, TEST_ALIASNAME);
1727 r.in.domain_handle = domain_handle;
1728 r.in.alias_name = &name;
1729 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1730 r.out.alias_handle = alias_handle;
1733 printf("Testing CreateAlias (%s)\n", r.in.alias_name->string);
1735 status = dcerpc_samr_CreateDomAlias(p, mem_ctx, &r);
1737 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1738 printf("Server refused create of '%s'\n", r.in.alias_name->string);
1742 if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
1743 if (!test_DeleteAlias_byname(p, mem_ctx, domain_handle, r.in.alias_name->string)) {
1746 status = dcerpc_samr_CreateDomAlias(p, mem_ctx, &r);
1749 if (!NT_STATUS_IS_OK(status)) {
1750 printf("CreateAlias failed - %s\n", nt_errstr(status));
1754 if (!test_alias_ops(p, mem_ctx, alias_handle, domain_sid)) {
1761 static BOOL test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1762 const char *acct_name,
1763 struct policy_handle *domain_handle, char **password)
1771 if (!test_ChangePasswordUser(p, mem_ctx, acct_name, domain_handle, password)) {
1775 if (!test_ChangePasswordUser2(p, mem_ctx, acct_name, domain_handle, password)) {
1779 if (!test_OemChangePasswordUser2(p, mem_ctx, acct_name, domain_handle, password)) {
1783 /* we change passwords twice - this has the effect of verifying
1784 they were changed correctly for the final call */
1785 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password)) {
1789 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password)) {
1796 static BOOL test_CreateUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1797 struct policy_handle *domain_handle,
1798 enum torture_samr_choice which_ops)
1801 TALLOC_CTX *user_ctx;
1804 struct samr_CreateUser r;
1805 struct samr_QueryUserInfo q;
1806 struct samr_DeleteUser d;
1809 /* This call creates a 'normal' account - check that it really does */
1810 const uint32_t acct_flags = ACB_NORMAL;
1811 struct lsa_String name;
1814 struct policy_handle user_handle;
1815 user_ctx = talloc_named(mem_ctx, 0, "test_CreateUser2 per-user context");
1816 init_lsa_String(&name, TEST_ACCOUNT_NAME);
1818 r.in.domain_handle = domain_handle;
1819 r.in.account_name = &name;
1820 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1821 r.out.user_handle = &user_handle;
1824 printf("Testing CreateUser(%s)\n", r.in.account_name->string);
1826 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
1828 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1829 printf("Server refused create of '%s': %s\n", r.in.account_name->string, nt_errstr(status));
1830 talloc_free(user_ctx);
1834 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
1835 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
1836 talloc_free(user_ctx);
1839 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
1841 if (!NT_STATUS_IS_OK(status)) {
1842 talloc_free(user_ctx);
1843 printf("CreateUser failed - %s\n", nt_errstr(status));
1846 q.in.user_handle = &user_handle;
1849 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
1850 if (!NT_STATUS_IS_OK(status)) {
1851 printf("QueryUserInfo level %u failed - %s\n",
1852 q.in.level, nt_errstr(status));
1855 if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
1856 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
1857 q.out.info->info16.acct_flags,
1863 if (!test_user_ops(p, user_ctx, &user_handle, domain_handle,
1864 acct_flags, name.string, which_ops)) {
1868 printf("Testing DeleteUser (createuser2 test)\n");
1870 d.in.user_handle = &user_handle;
1871 d.out.user_handle = &user_handle;
1873 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
1874 if (!NT_STATUS_IS_OK(status)) {
1875 printf("DeleteUser failed - %s\n", nt_errstr(status));
1881 talloc_free(user_ctx);
1887 static BOOL test_CreateUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1888 struct policy_handle *domain_handle, enum torture_samr_choice which_ops)
1891 struct samr_CreateUser2 r;
1892 struct samr_QueryUserInfo q;
1893 struct samr_DeleteUser d;
1894 struct policy_handle user_handle;
1896 struct lsa_String name;
1901 uint32_t acct_flags;
1902 const char *account_name;
1904 } account_types[] = {
1905 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
1906 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1907 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1908 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
1909 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1910 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1911 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
1912 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1913 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1914 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
1915 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
1916 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
1917 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1918 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1919 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
1922 for (i = 0; account_types[i].account_name; i++) {
1923 TALLOC_CTX *user_ctx;
1924 uint32_t acct_flags = account_types[i].acct_flags;
1925 uint32_t access_granted;
1926 user_ctx = talloc_named(mem_ctx, 0, "test_CreateUser2 per-user context");
1927 init_lsa_String(&name, account_types[i].account_name);
1929 r.in.domain_handle = domain_handle;
1930 r.in.account_name = &name;
1931 r.in.acct_flags = acct_flags;
1932 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1933 r.out.user_handle = &user_handle;
1934 r.out.access_granted = &access_granted;
1937 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
1939 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
1941 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1942 talloc_free(user_ctx);
1943 printf("Server refused create of '%s'\n", r.in.account_name->string);
1946 } else if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
1947 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
1948 talloc_free(user_ctx);
1952 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
1955 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
1956 printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
1957 nt_errstr(status), nt_errstr(account_types[i].nt_status));
1961 if (NT_STATUS_IS_OK(status)) {
1962 q.in.user_handle = &user_handle;
1965 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
1966 if (!NT_STATUS_IS_OK(status)) {
1967 printf("QueryUserInfo level %u failed - %s\n",
1968 q.in.level, nt_errstr(status));
1971 if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
1972 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
1973 q.out.info->info16.acct_flags,
1979 if (!test_user_ops(p, user_ctx, &user_handle, domain_handle,
1980 acct_flags, name.string, which_ops)) {
1984 printf("Testing DeleteUser (createuser2 test)\n");
1986 d.in.user_handle = &user_handle;
1987 d.out.user_handle = &user_handle;
1989 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
1990 if (!NT_STATUS_IS_OK(status)) {
1991 printf("DeleteUser failed - %s\n", nt_errstr(status));
1995 talloc_free(user_ctx);
2001 static BOOL test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2002 struct policy_handle *handle)
2005 struct samr_QueryAliasInfo r;
2006 uint16_t levels[] = {1, 2, 3};
2010 for (i=0;i<ARRAY_SIZE(levels);i++) {
2011 printf("Testing QueryAliasInfo level %u\n", levels[i]);
2013 r.in.alias_handle = handle;
2014 r.in.level = levels[i];
2016 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
2017 if (!NT_STATUS_IS_OK(status)) {
2018 printf("QueryAliasInfo level %u failed - %s\n",
2019 levels[i], nt_errstr(status));
2027 static BOOL test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2028 struct policy_handle *handle)
2031 struct samr_QueryGroupInfo r;
2032 uint16_t levels[] = {1, 2, 3, 4, 5};
2036 for (i=0;i<ARRAY_SIZE(levels);i++) {
2037 printf("Testing QueryGroupInfo level %u\n", levels[i]);
2039 r.in.group_handle = handle;
2040 r.in.level = levels[i];
2042 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
2043 if (!NT_STATUS_IS_OK(status)) {
2044 printf("QueryGroupInfo level %u failed - %s\n",
2045 levels[i], nt_errstr(status));
2053 static BOOL test_QueryGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2054 struct policy_handle *handle)
2057 struct samr_QueryGroupMember r;
2060 printf("Testing QueryGroupMember\n");
2062 r.in.group_handle = handle;
2064 status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &r);
2065 if (!NT_STATUS_IS_OK(status)) {
2066 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
2074 static BOOL test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2075 struct policy_handle *handle)
2078 struct samr_QueryGroupInfo r;
2079 struct samr_SetGroupInfo s;
2080 uint16_t levels[] = {1, 2, 3, 4};
2081 uint16_t set_ok[] = {0, 1, 1, 1};
2085 for (i=0;i<ARRAY_SIZE(levels);i++) {
2086 printf("Testing QueryGroupInfo level %u\n", levels[i]);
2088 r.in.group_handle = handle;
2089 r.in.level = levels[i];
2091 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
2092 if (!NT_STATUS_IS_OK(status)) {
2093 printf("QueryGroupInfo level %u failed - %s\n",
2094 levels[i], nt_errstr(status));
2098 printf("Testing SetGroupInfo level %u\n", levels[i]);
2100 s.in.group_handle = handle;
2101 s.in.level = levels[i];
2102 s.in.info = r.out.info;
2105 /* disabled this, as it changes the name only from the point of view of samr,
2106 but leaves the name from the point of view of w2k3 internals (and ldap). This means
2107 the name is still reserved, so creating the old name fails, but deleting by the old name
2109 if (s.in.level == 2) {
2110 init_lsa_String(&s.in.info->string, "NewName");
2114 if (s.in.level == 4) {
2115 init_lsa_String(&s.in.info->description, "test description");
2118 status = dcerpc_samr_SetGroupInfo(p, mem_ctx, &s);
2120 if (!NT_STATUS_IS_OK(status)) {
2121 printf("SetGroupInfo level %u failed - %s\n",
2122 r.in.level, nt_errstr(status));
2127 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
2128 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
2129 r.in.level, nt_errstr(status));
2139 static BOOL test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2140 struct policy_handle *handle)
2143 struct samr_QueryUserInfo r;
2144 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
2145 11, 12, 13, 14, 16, 17, 20, 21};
2149 for (i=0;i<ARRAY_SIZE(levels);i++) {
2150 printf("Testing QueryUserInfo level %u\n", levels[i]);
2152 r.in.user_handle = handle;
2153 r.in.level = levels[i];
2155 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
2156 if (!NT_STATUS_IS_OK(status)) {
2157 printf("QueryUserInfo level %u failed - %s\n",
2158 levels[i], nt_errstr(status));
2166 static BOOL test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2167 struct policy_handle *handle)
2170 struct samr_QueryUserInfo2 r;
2171 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
2172 11, 12, 13, 14, 16, 17, 20, 21};
2176 for (i=0;i<ARRAY_SIZE(levels);i++) {
2177 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
2179 r.in.user_handle = handle;
2180 r.in.level = levels[i];
2182 status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r);
2183 if (!NT_STATUS_IS_OK(status)) {
2184 printf("QueryUserInfo2 level %u failed - %s\n",
2185 levels[i], nt_errstr(status));
2193 static BOOL test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2194 struct policy_handle *handle, uint32_t rid)
2197 struct samr_OpenUser r;
2198 struct policy_handle user_handle;
2201 printf("Testing OpenUser(%u)\n", rid);
2203 r.in.domain_handle = handle;
2204 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2206 r.out.user_handle = &user_handle;
2208 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
2209 if (!NT_STATUS_IS_OK(status)) {
2210 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
2214 if (!test_QuerySecurity(p, mem_ctx, &user_handle)) {
2218 if (!test_QueryUserInfo(p, mem_ctx, &user_handle)) {
2222 if (!test_QueryUserInfo2(p, mem_ctx, &user_handle)) {
2226 if (!test_GetUserPwInfo(p, mem_ctx, &user_handle)) {
2230 if (!test_GetGroupsForUser(p,mem_ctx, &user_handle)) {
2234 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
2241 static BOOL test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2242 struct policy_handle *handle, uint32_t rid)
2245 struct samr_OpenGroup r;
2246 struct policy_handle group_handle;
2249 printf("Testing OpenGroup(%u)\n", rid);
2251 r.in.domain_handle = handle;
2252 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2254 r.out.group_handle = &group_handle;
2256 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
2257 if (!NT_STATUS_IS_OK(status)) {
2258 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
2262 if (!test_QuerySecurity(p, mem_ctx, &group_handle)) {
2266 if (!test_QueryGroupInfo(p, mem_ctx, &group_handle)) {
2270 if (!test_QueryGroupMember(p, mem_ctx, &group_handle)) {
2274 if (!test_samr_handle_Close(p, mem_ctx, &group_handle)) {
2281 static BOOL test_OpenAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2282 struct policy_handle *handle, uint32_t rid)
2285 struct samr_OpenAlias r;
2286 struct policy_handle alias_handle;
2289 printf("Testing OpenAlias(%u)\n", rid);
2291 r.in.domain_handle = handle;
2292 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2294 r.out.alias_handle = &alias_handle;
2296 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
2297 if (!NT_STATUS_IS_OK(status)) {
2298 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
2302 if (!test_QuerySecurity(p, mem_ctx, &alias_handle)) {
2306 if (!test_QueryAliasInfo(p, mem_ctx, &alias_handle)) {
2310 if (!test_GetMembersInAlias(p, mem_ctx, &alias_handle)) {
2314 if (!test_samr_handle_Close(p, mem_ctx, &alias_handle)) {
2321 static BOOL test_EnumDomainUsers(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2322 struct policy_handle *handle)
2325 struct samr_EnumDomainUsers r;
2326 uint32_t resume_handle=0;
2329 struct samr_LookupNames n;
2330 struct samr_LookupRids lr ;
2332 printf("Testing EnumDomainUsers\n");
2334 r.in.domain_handle = handle;
2335 r.in.resume_handle = &resume_handle;
2336 r.in.acct_flags = 0;
2337 r.in.max_size = (uint32_t)-1;
2338 r.out.resume_handle = &resume_handle;
2340 status = dcerpc_samr_EnumDomainUsers(p, mem_ctx, &r);
2341 if (!NT_STATUS_IS_OK(status)) {
2342 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
2350 if (r.out.sam->count == 0) {
2354 for (i=0;i<r.out.sam->count;i++) {
2355 if (!test_OpenUser(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
2360 printf("Testing LookupNames\n");
2361 n.in.domain_handle = handle;
2362 n.in.num_names = r.out.sam->count;
2363 n.in.names = talloc_array(mem_ctx, struct lsa_String, r.out.sam->count);
2364 for (i=0;i<r.out.sam->count;i++) {
2365 n.in.names[i].string = r.out.sam->entries[i].name.string;
2367 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
2368 if (!NT_STATUS_IS_OK(status)) {
2369 printf("LookupNames failed - %s\n", nt_errstr(status));
2374 printf("Testing LookupRids\n");
2375 lr.in.domain_handle = handle;
2376 lr.in.num_rids = r.out.sam->count;
2377 lr.in.rids = talloc_array(mem_ctx, uint32_t, r.out.sam->count);
2378 for (i=0;i<r.out.sam->count;i++) {
2379 lr.in.rids[i] = r.out.sam->entries[i].idx;
2381 status = dcerpc_samr_LookupRids(p, mem_ctx, &lr);
2382 if (!NT_STATUS_IS_OK(status)) {
2383 printf("LookupRids failed - %s\n", nt_errstr(status));
2391 try blasting the server with a bunch of sync requests
2393 static BOOL test_EnumDomainUsers_async(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2394 struct policy_handle *handle)
2397 struct samr_EnumDomainUsers r;
2398 uint32_t resume_handle=0;
2400 #define ASYNC_COUNT 100
2401 struct rpc_request *req[ASYNC_COUNT];
2403 if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
2404 printf("samr async test disabled - enable dangerous tests to use\n");
2408 printf("Testing EnumDomainUsers_async\n");
2410 r.in.domain_handle = handle;
2411 r.in.resume_handle = &resume_handle;
2412 r.in.acct_flags = 0;
2413 r.in.max_size = (uint32_t)-1;
2414 r.out.resume_handle = &resume_handle;
2416 for (i=0;i<ASYNC_COUNT;i++) {
2417 req[i] = dcerpc_samr_EnumDomainUsers_send(p, mem_ctx, &r);
2420 for (i=0;i<ASYNC_COUNT;i++) {
2421 status = dcerpc_ndr_request_recv(req[i]);
2422 if (!NT_STATUS_IS_OK(status)) {
2423 printf("EnumDomainUsers[%d] failed - %s\n",
2424 i, nt_errstr(status));
2429 printf("%d async requests OK\n", i);
2434 static BOOL test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2435 struct policy_handle *handle)
2438 struct samr_EnumDomainGroups r;
2439 uint32_t resume_handle=0;
2443 printf("Testing EnumDomainGroups\n");
2445 r.in.domain_handle = handle;
2446 r.in.resume_handle = &resume_handle;
2447 r.in.max_size = (uint32_t)-1;
2448 r.out.resume_handle = &resume_handle;
2450 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
2451 if (!NT_STATUS_IS_OK(status)) {
2452 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
2460 for (i=0;i<r.out.sam->count;i++) {
2461 if (!test_OpenGroup(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
2469 static BOOL test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2470 struct policy_handle *handle)
2473 struct samr_EnumDomainAliases r;
2474 uint32_t resume_handle=0;
2478 printf("Testing EnumDomainAliases\n");
2480 r.in.domain_handle = handle;
2481 r.in.resume_handle = &resume_handle;
2482 r.in.acct_flags = (uint32_t)-1;
2483 r.out.resume_handle = &resume_handle;
2485 status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
2486 if (!NT_STATUS_IS_OK(status)) {
2487 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
2495 for (i=0;i<r.out.sam->count;i++) {
2496 if (!test_OpenAlias(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
2504 static BOOL test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2505 struct policy_handle *handle)
2508 struct samr_GetDisplayEnumerationIndex r;
2510 uint16_t levels[] = {1, 2, 3, 4, 5};
2511 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
2514 for (i=0;i<ARRAY_SIZE(levels);i++) {
2515 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
2517 r.in.domain_handle = handle;
2518 r.in.level = levels[i];
2519 init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
2521 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
2524 !NT_STATUS_IS_OK(status) &&
2525 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2526 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
2527 levels[i], nt_errstr(status));
2531 init_lsa_String(&r.in.name, "zzzzzzzz");
2533 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
2535 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2536 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
2537 levels[i], nt_errstr(status));
2545 static BOOL test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2546 struct policy_handle *handle)
2549 struct samr_GetDisplayEnumerationIndex2 r;
2551 uint16_t levels[] = {1, 2, 3, 4, 5};
2552 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
2555 for (i=0;i<ARRAY_SIZE(levels);i++) {
2556 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
2558 r.in.domain_handle = handle;
2559 r.in.level = levels[i];
2560 init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
2562 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
2564 !NT_STATUS_IS_OK(status) &&
2565 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2566 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
2567 levels[i], nt_errstr(status));
2571 init_lsa_String(&r.in.name, "zzzzzzzz");
2573 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
2574 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2575 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
2576 levels[i], nt_errstr(status));
2584 static BOOL test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2585 struct policy_handle *handle)
2588 struct samr_QueryDisplayInfo r;
2590 uint16_t levels[] = {1, 2, 3, 4, 5};
2593 for (i=0;i<ARRAY_SIZE(levels);i++) {
2594 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
2596 r.in.domain_handle = handle;
2597 r.in.level = levels[i];
2599 r.in.max_entries = 1000;
2600 r.in.buf_size = (uint32_t)-1;
2602 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
2603 if (!NT_STATUS_IS_OK(status)) {
2604 printf("QueryDisplayInfo level %u failed - %s\n",
2605 levels[i], nt_errstr(status));
2613 static BOOL test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2614 struct policy_handle *handle)
2617 struct samr_QueryDisplayInfo2 r;
2619 uint16_t levels[] = {1, 2, 3, 4, 5};
2622 for (i=0;i<ARRAY_SIZE(levels);i++) {
2623 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
2625 r.in.domain_handle = handle;
2626 r.in.level = levels[i];
2628 r.in.max_entries = 1000;
2629 r.in.buf_size = (uint32_t)-1;
2631 status = dcerpc_samr_QueryDisplayInfo2(p, mem_ctx, &r);
2632 if (!NT_STATUS_IS_OK(status)) {
2633 printf("QueryDisplayInfo2 level %u failed - %s\n",
2634 levels[i], nt_errstr(status));
2642 static BOOL test_QueryDisplayInfo3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2643 struct policy_handle *handle)
2646 struct samr_QueryDisplayInfo3 r;
2648 uint16_t levels[] = {1, 2, 3, 4, 5};
2651 for (i=0;i<ARRAY_SIZE(levels);i++) {
2652 printf("Testing QueryDisplayInfo3 level %u\n", levels[i]);
2654 r.in.domain_handle = handle;
2655 r.in.level = levels[i];
2657 r.in.max_entries = 1000;
2658 r.in.buf_size = (uint32_t)-1;
2660 status = dcerpc_samr_QueryDisplayInfo3(p, mem_ctx, &r);
2661 if (!NT_STATUS_IS_OK(status)) {
2662 printf("QueryDisplayInfo3 level %u failed - %s\n",
2663 levels[i], nt_errstr(status));
2672 static BOOL test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2673 struct policy_handle *handle)
2676 struct samr_QueryDisplayInfo r;
2679 printf("Testing QueryDisplayInfo continuation\n");
2681 r.in.domain_handle = handle;
2684 r.in.max_entries = 1;
2685 r.in.buf_size = (uint32_t)-1;
2688 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
2689 if (NT_STATUS_IS_OK(status) && r.out.returned_size != 0) {
2690 if (r.out.info.info1.entries[0].idx != r.in.start_idx + 1) {
2691 printf("expected idx %d but got %d\n",
2693 r.out.info.info1.entries[0].idx);
2697 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
2698 !NT_STATUS_IS_OK(status)) {
2699 printf("QueryDisplayInfo level %u failed - %s\n",
2700 r.in.level, nt_errstr(status));
2705 } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
2706 NT_STATUS_IS_OK(status)) &&
2707 r.out.returned_size != 0);
2712 static BOOL test_QueryDomainInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2713 struct policy_handle *handle)
2716 struct samr_QueryDomainInfo r;
2717 struct samr_SetDomainInfo s;
2718 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
2719 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
2722 const char *domain_comment = talloc_asprintf(mem_ctx,
2723 "Tortured by Samba4 RPC-SAMR: %s",
2724 timestring(mem_ctx, time(NULL)));
2726 s.in.domain_handle = handle;
2728 s.in.info = talloc(mem_ctx, union samr_DomainInfo);
2730 s.in.info->info4.comment.string = domain_comment;
2731 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2732 if (!NT_STATUS_IS_OK(status)) {
2733 printf("SetDomainInfo level %u (set comment) failed - %s\n",
2734 r.in.level, nt_errstr(status));
2738 for (i=0;i<ARRAY_SIZE(levels);i++) {
2739 printf("Testing QueryDomainInfo level %u\n", levels[i]);
2741 r.in.domain_handle = handle;
2742 r.in.level = levels[i];
2744 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2745 if (!NT_STATUS_IS_OK(status)) {
2746 printf("QueryDomainInfo level %u failed - %s\n",
2747 r.in.level, nt_errstr(status));
2752 switch (levels[i]) {
2754 if (strcmp(r.out.info->info2.comment.string, domain_comment) != 0) {
2755 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
2756 levels[i], r.out.info->info2.comment.string, domain_comment);
2761 if (strcmp(r.out.info->info4.comment.string, domain_comment) != 0) {
2762 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
2763 levels[i], r.out.info->info4.comment.string, domain_comment);
2768 if (strcmp(r.out.info->info11.info2.comment.string, domain_comment) != 0) {
2769 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
2770 levels[i], r.out.info->info11.info2.comment.string, domain_comment);
2776 printf("Testing SetDomainInfo level %u\n", levels[i]);
2778 s.in.domain_handle = handle;
2779 s.in.level = levels[i];
2780 s.in.info = r.out.info;
2782 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2784 if (!NT_STATUS_IS_OK(status)) {
2785 printf("SetDomainInfo level %u failed - %s\n",
2786 r.in.level, nt_errstr(status));
2791 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
2792 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
2793 r.in.level, nt_errstr(status));
2799 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2800 if (!NT_STATUS_IS_OK(status)) {
2801 printf("QueryDomainInfo level %u failed - %s\n",
2802 r.in.level, nt_errstr(status));
2812 static BOOL test_QueryDomainInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2813 struct policy_handle *handle)
2816 struct samr_QueryDomainInfo2 r;
2817 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
2821 for (i=0;i<ARRAY_SIZE(levels);i++) {
2822 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
2824 r.in.domain_handle = handle;
2825 r.in.level = levels[i];
2827 status = dcerpc_samr_QueryDomainInfo2(p, mem_ctx, &r);
2828 if (!NT_STATUS_IS_OK(status)) {
2829 printf("QueryDomainInfo2 level %u failed - %s\n",
2830 r.in.level, nt_errstr(status));
2839 /* Test whether querydispinfo level 5 and enumdomgroups return the same
2840 set of group names. */
2841 static BOOL test_GroupList(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2842 struct policy_handle *handle)
2844 struct samr_EnumDomainGroups q1;
2845 struct samr_QueryDisplayInfo q2;
2847 uint32_t resume_handle=0;
2852 const char **names = NULL;
2854 printf("Testing coherency of querydispinfo vs enumdomgroups\n");
2856 q1.in.domain_handle = handle;
2857 q1.in.resume_handle = &resume_handle;
2859 q1.out.resume_handle = &resume_handle;
2861 status = STATUS_MORE_ENTRIES;
2862 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
2863 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &q1);
2865 if (!NT_STATUS_IS_OK(status) &&
2866 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
2869 for (i=0; i<q1.out.num_entries; i++) {
2870 add_string_to_array(mem_ctx,
2871 q1.out.sam->entries[i].name.string,
2872 &names, &num_names);
2876 if (!NT_STATUS_IS_OK(status)) {
2877 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
2885 q2.in.domain_handle = handle;
2887 q2.in.start_idx = 0;
2888 q2.in.max_entries = 5;
2889 q2.in.buf_size = (uint32_t)-1;
2891 status = STATUS_MORE_ENTRIES;
2892 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
2893 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &q2);
2895 if (!NT_STATUS_IS_OK(status) &&
2896 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
2899 for (i=0; i<q2.out.info.info5.count; i++) {
2901 const char *name = q2.out.info.info5.entries[i].account_name.string;
2903 for (j=0; j<num_names; j++) {
2904 if (names[j] == NULL)
2906 /* Hmm. No strequal in samba4 */
2907 if (strequal(names[j], name)) {
2915 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
2920 q2.in.start_idx += q2.out.info.info5.count;
2923 if (!NT_STATUS_IS_OK(status)) {
2924 printf("QueryDisplayInfo level 5 failed - %s\n",
2929 for (i=0; i<num_names; i++) {
2930 if (names[i] != NULL) {
2931 printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
2940 static BOOL test_DeleteDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2941 struct policy_handle *group_handle)
2943 struct samr_DeleteDomainGroup d;
2947 printf("Testing DeleteDomainGroup\n");
2949 d.in.group_handle = group_handle;
2950 d.out.group_handle = group_handle;
2952 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
2953 if (!NT_STATUS_IS_OK(status)) {
2954 printf("DeleteDomainGroup failed - %s\n", nt_errstr(status));
2961 static BOOL test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2962 struct policy_handle *domain_handle)
2964 struct samr_TestPrivateFunctionsDomain r;
2968 printf("Testing TestPrivateFunctionsDomain\n");
2970 r.in.domain_handle = domain_handle;
2972 status = dcerpc_samr_TestPrivateFunctionsDomain(p, mem_ctx, &r);
2973 if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
2974 printf("TestPrivateFunctionsDomain failed - %s\n", nt_errstr(status));
2981 static BOOL test_RidToSid(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2982 struct dom_sid *domain_sid,
2983 struct policy_handle *domain_handle)
2985 struct samr_RidToSid r;
2988 struct dom_sid *calc_sid;
2989 int rids[] = { 0, 42, 512, 10200 };
2992 for (i=0;i<ARRAY_SIZE(rids);i++) {
2994 printf("Testing RidToSid\n");
2996 calc_sid = dom_sid_dup(mem_ctx, domain_sid);
2997 r.in.domain_handle = domain_handle;
3000 status = dcerpc_samr_RidToSid(p, mem_ctx, &r);
3001 if (!NT_STATUS_IS_OK(status)) {
3002 printf("RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
3005 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
3007 if (!dom_sid_equal(calc_sid, r.out.sid)) {
3008 printf("RidToSid for %d failed - got %s, expected %s\n", rids[i],
3009 dom_sid_string(mem_ctx, r.out.sid),
3010 dom_sid_string(mem_ctx, calc_sid));
3019 static BOOL test_GetBootKeyInformation(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3020 struct policy_handle *domain_handle)
3022 struct samr_GetBootKeyInformation r;
3026 printf("Testing GetBootKeyInformation\n");
3028 r.in.domain_handle = domain_handle;
3030 status = dcerpc_samr_GetBootKeyInformation(p, mem_ctx, &r);
3031 if (!NT_STATUS_IS_OK(status)) {
3032 /* w2k3 seems to fail this sometimes and pass it sometimes */
3033 printf("GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
3039 static BOOL test_AddGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3040 struct policy_handle *domain_handle,
3041 struct policy_handle *group_handle)
3044 struct samr_AddGroupMember r;
3045 struct samr_DeleteGroupMember d;
3046 struct samr_QueryGroupMember q;
3047 struct samr_SetMemberAttributesOfGroup s;
3051 status = test_LookupName(p, mem_ctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
3052 if (!NT_STATUS_IS_OK(status)) {
3056 r.in.group_handle = group_handle;
3058 r.in.flags = 0; /* ??? */
3060 printf("Testing AddGroupMember and DeleteGroupMember\n");
3062 d.in.group_handle = group_handle;
3065 status = dcerpc_samr_DeleteGroupMember(p, mem_ctx, &d);
3066 if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_NOT_IN_GROUP, status)) {
3067 printf("DeleteGroupMember gave %s - should be NT_STATUS_MEMBER_NOT_IN_GROUP\n",
3072 status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
3073 if (!NT_STATUS_IS_OK(status)) {
3074 printf("AddGroupMember failed - %s\n", nt_errstr(status));
3078 status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
3079 if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_IN_GROUP, status)) {
3080 printf("AddGroupMember gave %s - should be NT_STATUS_MEMBER_IN_GROUP\n",
3085 if (lp_parm_bool(-1, "target", "samba4", False)) {
3086 printf("skipping SetMemberAttributesOfGroup test against Samba4\n");
3088 /* this one is quite strange. I am using random inputs in the
3089 hope of triggering an error that might give us a clue */
3091 s.in.group_handle = group_handle;
3092 s.in.unknown1 = random();
3093 s.in.unknown2 = random();
3095 status = dcerpc_samr_SetMemberAttributesOfGroup(p, mem_ctx, &s);
3096 if (!NT_STATUS_IS_OK(status)) {
3097 printf("SetMemberAttributesOfGroup failed - %s\n", nt_errstr(status));
3102 q.in.group_handle = group_handle;
3104 status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &q);
3105 if (!NT_STATUS_IS_OK(status)) {
3106 printf("QueryGroupMember failed - %s\n", nt_errstr(status));
3110 status = dcerpc_samr_DeleteGroupMember(p, mem_ctx, &d);
3111 if (!NT_STATUS_IS_OK(status)) {
3112 printf("DeleteGroupMember failed - %s\n", nt_errstr(status));
3116 status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
3117 if (!NT_STATUS_IS_OK(status)) {
3118 printf("AddGroupMember failed - %s\n", nt_errstr(status));
3126 static BOOL test_CreateDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3127 struct policy_handle *domain_handle, struct policy_handle *group_handle)
3130 struct samr_CreateDomainGroup r;
3132 struct lsa_String name;
3135 init_lsa_String(&name, TEST_GROUPNAME);
3137 r.in.domain_handle = domain_handle;
3139 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3140 r.out.group_handle = group_handle;
3143 printf("Testing CreateDomainGroup(%s)\n", r.in.name->string);
3145 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
3147 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
3148 printf("Server refused create of '%s'\n", r.in.name->string);
3149 ZERO_STRUCTP(group_handle);
3153 if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS) ||
3154 NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
3155 if (!test_DeleteGroup_byname(p, mem_ctx, domain_handle, r.in.name->string)) {
3158 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
3160 if (!NT_STATUS_IS_OK(status)) {
3161 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
3165 if (!test_AddGroupMember(p, mem_ctx, domain_handle, group_handle)) {
3169 if (!test_SetGroupInfo(p, mem_ctx, group_handle)) {
3178 its not totally clear what this does. It seems to accept any sid you like.
3180 static BOOL test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p,
3181 TALLOC_CTX *mem_ctx,
3182 struct policy_handle *domain_handle)
3185 struct samr_RemoveMemberFromForeignDomain r;
3187 r.in.domain_handle = domain_handle;
3188 r.in.sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-12-34-56-78");
3190 status = dcerpc_samr_RemoveMemberFromForeignDomain(p, mem_ctx, &r);
3191 if (!NT_STATUS_IS_OK(status)) {
3192 printf("RemoveMemberFromForeignDomain failed - %s\n", nt_errstr(status));
3201 static BOOL test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3202 struct policy_handle *handle);
3204 static BOOL test_OpenDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3205 struct policy_handle *handle, struct dom_sid *sid,
3206 enum torture_samr_choice which_ops)
3209 struct samr_OpenDomain r;
3210 struct policy_handle domain_handle;
3211 struct policy_handle alias_handle;
3212 struct policy_handle group_handle;
3215 ZERO_STRUCT(alias_handle);
3216 ZERO_STRUCT(group_handle);
3217 ZERO_STRUCT(domain_handle);
3219 printf("Testing OpenDomain\n");
3221 r.in.connect_handle = handle;
3222 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3224 r.out.domain_handle = &domain_handle;
3226 status = dcerpc_samr_OpenDomain(p, mem_ctx, &r);
3227 if (!NT_STATUS_IS_OK(status)) {
3228 printf("OpenDomain failed - %s\n", nt_errstr(status));
3232 /* run the domain tests with the main handle closed - this tests
3233 the servers reference counting */
3234 ret &= test_samr_handle_Close(p, mem_ctx, handle);
3236 switch (which_ops) {
3237 case TORTURE_SAMR_USER_ATTRIBUTES:
3238 case TORTURE_SAMR_PASSWORDS:
3239 ret &= test_CreateUser(p, mem_ctx, &domain_handle, which_ops);
3240 ret &= test_CreateUser2(p, mem_ctx, &domain_handle, which_ops);
3242 case TORTURE_SAMR_OTHER:
3243 ret &= test_QuerySecurity(p, mem_ctx, &domain_handle);
3244 ret &= test_RemoveMemberFromForeignDomain(p, mem_ctx, &domain_handle);
3245 ret &= test_CreateAlias(p, mem_ctx, &domain_handle, &alias_handle, sid);
3246 ret &= test_CreateDomainGroup(p, mem_ctx, &domain_handle, &group_handle);
3247 ret &= test_QueryDomainInfo(p, mem_ctx, &domain_handle);
3248 ret &= test_QueryDomainInfo2(p, mem_ctx, &domain_handle);
3249 ret &= test_EnumDomainUsers(p, mem_ctx, &domain_handle);
3250 ret &= test_EnumDomainUsers_async(p, mem_ctx, &domain_handle);
3251 ret &= test_EnumDomainGroups(p, mem_ctx, &domain_handle);
3252 ret &= test_EnumDomainAliases(p, mem_ctx, &domain_handle);
3253 ret &= test_QueryDisplayInfo(p, mem_ctx, &domain_handle);
3254 ret &= test_QueryDisplayInfo2(p, mem_ctx, &domain_handle);
3255 ret &= test_QueryDisplayInfo3(p, mem_ctx, &domain_handle);
3256 ret &= test_QueryDisplayInfo_continue(p, mem_ctx, &domain_handle);
3258 if (lp_parm_bool(-1, "target", "samba4", False)) {
3259 printf("skipping GetDisplayEnumerationIndex test against Samba4\n");
3261 ret &= test_GetDisplayEnumerationIndex(p, mem_ctx, &domain_handle);
3262 ret &= test_GetDisplayEnumerationIndex2(p, mem_ctx, &domain_handle);
3264 ret &= test_GroupList(p, mem_ctx, &domain_handle);
3265 ret &= test_TestPrivateFunctionsDomain(p, mem_ctx, &domain_handle);
3266 ret &= test_RidToSid(p, mem_ctx, sid, &domain_handle);
3267 ret &= test_GetBootKeyInformation(p, mem_ctx, &domain_handle);
3271 if (!policy_handle_empty(&alias_handle) &&
3272 !test_DeleteAlias(p, mem_ctx, &alias_handle)) {
3276 if (!policy_handle_empty(&group_handle) &&
3277 !test_DeleteDomainGroup(p, mem_ctx, &group_handle)) {
3281 ret &= test_samr_handle_Close(p, mem_ctx, &domain_handle);
3283 /* reconnect the main handle */
3284 ret &= test_Connect(p, mem_ctx, handle);
3289 static BOOL test_LookupDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3290 struct policy_handle *handle, const char *domain,
3291 enum torture_samr_choice which_ops)
3294 struct samr_LookupDomain r;
3295 struct lsa_String n1;
3296 struct lsa_String n2;
3299 printf("Testing LookupDomain(%s)\n", domain);
3301 /* check for correct error codes */
3302 r.in.connect_handle = handle;
3303 r.in.domain_name = &n2;
3306 status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
3307 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_PARAMETER, status)) {
3308 printf("failed: LookupDomain expected NT_STATUS_INVALID_PARAMETER - %s\n", nt_errstr(status));
3312 init_lsa_String(&n2, "xxNODOMAINxx");
3314 status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
3315 if (!NT_STATUS_EQUAL(NT_STATUS_NO_SUCH_DOMAIN, status)) {
3316 printf("failed: LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN - %s\n", nt_errstr(status));
3320 r.in.connect_handle = handle;
3322 init_lsa_String(&n1, domain);
3323 r.in.domain_name = &n1;
3325 status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
3326 if (!NT_STATUS_IS_OK(status)) {
3327 printf("LookupDomain failed - %s\n", nt_errstr(status));
3331 if (!test_GetDomPwInfo(p, mem_ctx, &n1)) {
3335 if (!test_OpenDomain(p, mem_ctx, handle, r.out.sid, which_ops)) {
3343 static BOOL test_EnumDomains(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3344 struct policy_handle *handle, enum torture_samr_choice which_ops)
3347 struct samr_EnumDomains r;
3348 uint32_t resume_handle = 0;
3352 r.in.connect_handle = handle;
3353 r.in.resume_handle = &resume_handle;
3354 r.in.buf_size = (uint32_t)-1;
3355 r.out.resume_handle = &resume_handle;
3357 status = dcerpc_samr_EnumDomains(p, mem_ctx, &r);
3358 if (!NT_STATUS_IS_OK(status)) {
3359 printf("EnumDomains failed - %s\n", nt_errstr(status));
3367 for (i=0;i<r.out.sam->count;i++) {
3368 if (!test_LookupDomain(p, mem_ctx, handle,
3369 r.out.sam->entries[i].name.string, which_ops)) {
3374 status = dcerpc_samr_EnumDomains(p, mem_ctx, &r);
3375 if (!NT_STATUS_IS_OK(status)) {
3376 printf("EnumDomains failed - %s\n", nt_errstr(status));
3384 static BOOL test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3385 struct policy_handle *handle)
3388 struct samr_Connect r;
3389 struct samr_Connect2 r2;
3390 struct samr_Connect3 r3;
3391 struct samr_Connect4 r4;
3392 struct samr_Connect5 r5;
3393 union samr_ConnectInfo info;
3394 struct policy_handle h;
3395 BOOL ret = True, got_handle = False;
3397 printf("testing samr_Connect\n");
3399 r.in.system_name = 0;
3400 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3401 r.out.connect_handle = &h;
3403 status = dcerpc_samr_Connect(p, mem_ctx, &r);
3404 if (!NT_STATUS_IS_OK(status)) {
3405 printf("Connect failed - %s\n", nt_errstr(status));
3412 printf("testing samr_Connect2\n");
3414 r2.in.system_name = NULL;
3415 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3416 r2.out.connect_handle = &h;
3418 status = dcerpc_samr_Connect2(p, mem_ctx, &r2);
3419 if (!NT_STATUS_IS_OK(status)) {
3420 printf("Connect2 failed - %s\n", nt_errstr(status));
3424 test_samr_handle_Close(p, mem_ctx, handle);
3430 printf("testing samr_Connect3\n");
3432 r3.in.system_name = NULL;
3434 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3435 r3.out.connect_handle = &h;
3437 status = dcerpc_samr_Connect3(p, mem_ctx, &r3);
3438 if (!NT_STATUS_IS_OK(status)) {
3439 printf("Connect3 failed - %s\n", nt_errstr(status));
3443 test_samr_handle_Close(p, mem_ctx, handle);
3449 printf("testing samr_Connect4\n");
3451 r4.in.system_name = "";
3453 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3454 r4.out.connect_handle = &h;
3456 status = dcerpc_samr_Connect4(p, mem_ctx, &r4);
3457 if (!NT_STATUS_IS_OK(status)) {
3458 printf("Connect4 failed - %s\n", nt_errstr(status));
3462 test_samr_handle_Close(p, mem_ctx, handle);
3468 printf("testing samr_Connect5\n");
3470 info.info1.unknown1 = 0;
3471 info.info1.unknown2 = 0;
3473 r5.in.system_name = "";
3474 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3477 r5.out.info = &info;
3478 r5.out.connect_handle = &h;
3480 status = dcerpc_samr_Connect5(p, mem_ctx, &r5);
3481 if (!NT_STATUS_IS_OK(status)) {
3482 printf("Connect5 failed - %s\n", nt_errstr(status));
3486 test_samr_handle_Close(p, mem_ctx, handle);
3496 BOOL torture_rpc_samr(struct torture_context *torture)
3499 struct dcerpc_pipe *p;
3501 struct policy_handle handle;
3503 status = torture_rpc_connection(torture, &p, &dcerpc_table_samr);
3504 if (!NT_STATUS_IS_OK(status)) {
3508 ret &= test_Connect(p, torture, &handle);
3510 ret &= test_QuerySecurity(p, torture, &handle);
3512 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_OTHER);
3514 ret &= test_SetDsrmPassword(p, torture, &handle);
3516 ret &= test_Shutdown(p, torture, &handle);
3518 ret &= test_samr_handle_Close(p, torture, &handle);
3524 BOOL torture_rpc_samr_users(struct torture_context *torture)
3527 struct dcerpc_pipe *p;
3529 struct policy_handle handle;
3531 status = torture_rpc_connection(torture, &p, &dcerpc_table_samr);
3532 if (!NT_STATUS_IS_OK(status)) {
3536 ret &= test_Connect(p, torture, &handle);
3538 ret &= test_QuerySecurity(p, torture, &handle);
3540 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_USER_ATTRIBUTES);
3542 ret &= test_SetDsrmPassword(p, torture, &handle);
3544 ret &= test_Shutdown(p, torture, &handle);
3546 ret &= test_samr_handle_Close(p, torture, &handle);
3552 BOOL torture_rpc_samr_passwords(struct torture_context *torture)
3555 struct dcerpc_pipe *p;
3557 struct policy_handle handle;
3559 status = torture_rpc_connection(torture, &p, &dcerpc_table_samr);
3560 if (!NT_STATUS_IS_OK(status)) {
3564 ret &= test_Connect(p, torture, &handle);
3566 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_PASSWORDS);
3568 ret &= test_samr_handle_Close(p, torture, &handle);