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 "librpc/gen_ndr/ndr_lsa.h"
26 #include "librpc/gen_ndr/ndr_samr.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/proto.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$"
41 static BOOL test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
42 struct policy_handle *handle);
44 static BOOL test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
45 struct policy_handle *handle);
47 static BOOL test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
48 struct policy_handle *handle);
50 static void init_lsa_String(struct lsa_String *string, const char *s)
55 BOOL test_samr_handle_Close(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
56 struct policy_handle *handle)
62 r.out.handle = handle;
64 status = dcerpc_samr_Close(p, mem_ctx, &r);
65 if (!NT_STATUS_IS_OK(status)) {
66 printf("Close handle failed - %s\n", nt_errstr(status));
73 static BOOL test_Shutdown(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
74 struct policy_handle *handle)
77 struct samr_Shutdown r;
79 if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
80 printf("samr_Shutdown disabled - enable dangerous tests to use\n");
84 r.in.connect_handle = handle;
86 printf("testing samr_Shutdown\n");
88 status = dcerpc_samr_Shutdown(p, mem_ctx, &r);
89 if (!NT_STATUS_IS_OK(status)) {
90 printf("samr_Shutdown failed - %s\n", nt_errstr(status));
97 static BOOL test_SetDsrmPassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
98 struct policy_handle *handle)
101 struct samr_SetDsrmPassword r;
102 struct lsa_String string;
103 struct samr_Password hash;
105 if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
106 printf("samr_SetDsrmPassword disabled - enable dangerous tests to use\n");
110 E_md4hash("TeSTDSRM123", hash.hash);
112 init_lsa_String(&string, "Administrator");
118 printf("testing samr_SetDsrmPassword\n");
120 status = dcerpc_samr_SetDsrmPassword(p, mem_ctx, &r);
121 if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
122 printf("samr_SetDsrmPassword failed - %s\n", nt_errstr(status));
130 static BOOL test_QuerySecurity(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
131 struct policy_handle *handle)
134 struct samr_QuerySecurity r;
135 struct samr_SetSecurity s;
137 r.in.handle = handle;
140 status = dcerpc_samr_QuerySecurity(p, mem_ctx, &r);
141 if (!NT_STATUS_IS_OK(status)) {
142 printf("QuerySecurity failed - %s\n", nt_errstr(status));
146 if (r.out.sdbuf == NULL) {
150 s.in.handle = handle;
152 s.in.sdbuf = r.out.sdbuf;
154 status = dcerpc_samr_SetSecurity(p, mem_ctx, &s);
155 if (!NT_STATUS_IS_OK(status)) {
156 printf("SetSecurity failed - %s\n", nt_errstr(status));
160 status = dcerpc_samr_QuerySecurity(p, mem_ctx, &r);
161 if (!NT_STATUS_IS_OK(status)) {
162 printf("QuerySecurity failed - %s\n", nt_errstr(status));
170 static BOOL test_SetUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
171 struct policy_handle *handle, uint32_t base_acct_flags,
172 const char *base_account_name)
175 struct samr_SetUserInfo s;
176 struct samr_SetUserInfo2 s2;
177 struct samr_QueryUserInfo q;
178 struct samr_QueryUserInfo q0;
179 union samr_UserInfo u;
181 const char *test_account_name;
183 uint32_t user_extra_flags = 0;
184 if (base_acct_flags == ACB_NORMAL) {
185 /* When created, accounts are expired by default */
186 user_extra_flags = ACB_PW_EXPIRED;
189 s.in.user_handle = handle;
192 s2.in.user_handle = handle;
195 q.in.user_handle = handle;
199 #define TESTCALL(call, r) \
200 status = dcerpc_samr_ ##call(p, mem_ctx, &r); \
201 if (!NT_STATUS_IS_OK(status)) { \
202 printf(#call " level %u failed - %s (%s)\n", \
203 r.in.level, nt_errstr(status), __location__); \
208 #define STRING_EQUAL(s1, s2, field) \
209 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
210 printf("Failed to set %s to '%s' (%s)\n", \
211 #field, s2, __location__); \
216 #define INT_EQUAL(i1, i2, field) \
218 printf("Failed to set %s to 0x%x - got 0x%x (%s)\n", \
219 #field, i2, i1, __location__); \
224 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
225 printf("field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
227 TESTCALL(QueryUserInfo, q) \
229 s2.in.level = lvl1; \
232 ZERO_STRUCT(u.info21); \
233 u.info21.fields_present = fpval; \
235 init_lsa_String(&u.info ## lvl1.field1, value); \
236 TESTCALL(SetUserInfo, s) \
237 TESTCALL(SetUserInfo2, s2) \
238 init_lsa_String(&u.info ## lvl1.field1, ""); \
239 TESTCALL(QueryUserInfo, q); \
241 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
243 TESTCALL(QueryUserInfo, q) \
245 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
248 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
249 printf("field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
251 TESTCALL(QueryUserInfo, q) \
253 s2.in.level = lvl1; \
256 uint8_t *bits = u.info21.logon_hours.bits; \
257 ZERO_STRUCT(u.info21); \
258 if (fpval == SAMR_FIELD_LOGON_HOURS) { \
259 u.info21.logon_hours.units_per_week = 168; \
260 u.info21.logon_hours.bits = bits; \
262 u.info21.fields_present = fpval; \
264 u.info ## lvl1.field1 = value; \
265 TESTCALL(SetUserInfo, s) \
266 TESTCALL(SetUserInfo2, s2) \
267 u.info ## lvl1.field1 = 0; \
268 TESTCALL(QueryUserInfo, q); \
270 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
272 TESTCALL(QueryUserInfo, q) \
274 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
277 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
278 TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
282 do { TESTCALL(QueryUserInfo, q0) } while (0);
284 TEST_USERINFO_STRING(2, comment, 1, comment, "xx2-1 comment", 0);
285 TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
286 TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment",
289 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-1", base_account_name);
290 TEST_USERINFO_STRING(7, account_name, 1, account_name, base_account_name, 0);
291 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-3", base_account_name);
292 TEST_USERINFO_STRING(7, account_name, 3, account_name, base_account_name, 0);
293 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-5", base_account_name);
294 TEST_USERINFO_STRING(7, account_name, 5, account_name, base_account_name, 0);
295 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-6", base_account_name);
296 TEST_USERINFO_STRING(7, account_name, 6, account_name, base_account_name, 0);
297 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-7", base_account_name);
298 TEST_USERINFO_STRING(7, account_name, 7, account_name, base_account_name, 0);
299 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-21", base_account_name);
300 TEST_USERINFO_STRING(7, account_name, 21, account_name, base_account_name, 0);
301 test_account_name = base_account_name;
302 TEST_USERINFO_STRING(21, account_name, 21, account_name, base_account_name,
303 SAMR_FIELD_ACCOUNT_NAME);
305 TEST_USERINFO_STRING(6, full_name, 1, full_name, "xx6-1 full_name", 0);
306 TEST_USERINFO_STRING(6, full_name, 3, full_name, "xx6-3 full_name", 0);
307 TEST_USERINFO_STRING(6, full_name, 5, full_name, "xx6-5 full_name", 0);
308 TEST_USERINFO_STRING(6, full_name, 6, full_name, "xx6-6 full_name", 0);
309 TEST_USERINFO_STRING(6, full_name, 8, full_name, "xx6-8 full_name", 0);
310 TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
311 TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
312 TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name",
313 SAMR_FIELD_FULL_NAME);
315 TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
316 TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
317 TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
318 TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script",
319 SAMR_FIELD_LOGON_SCRIPT);
321 TEST_USERINFO_STRING(12, profile_path, 3, profile_path, "xx12-3 profile_path", 0);
322 TEST_USERINFO_STRING(12, profile_path, 5, profile_path, "xx12-5 profile_path", 0);
323 TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
324 TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path",
325 SAMR_FIELD_PROFILE_PATH);
327 TEST_USERINFO_STRING(13, description, 1, description, "xx13-1 description", 0);
328 TEST_USERINFO_STRING(13, description, 5, description, "xx13-5 description", 0);
329 TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
330 TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description",
331 SAMR_FIELD_DESCRIPTION);
333 TEST_USERINFO_STRING(14, workstations, 3, workstations, "14workstation3", 0);
334 TEST_USERINFO_STRING(14, workstations, 5, workstations, "14workstation4", 0);
335 TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
336 TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21",
337 SAMR_FIELD_WORKSTATIONS);
339 TEST_USERINFO_STRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
340 TEST_USERINFO_STRING(21, parameters, 21, parameters, "xx21-21 parameters",
341 SAMR_FIELD_PARAMETERS);
343 TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
344 TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__,
345 SAMR_FIELD_COUNTRY_CODE);
347 TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
348 TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__,
349 SAMR_FIELD_CODE_PAGE);
351 TEST_USERINFO_INT(4, logon_hours.bits[3], 3, logon_hours.bits[3], 1, 0);
352 TEST_USERINFO_INT(4, logon_hours.bits[3], 5, logon_hours.bits[3], 2, 0);
353 TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
354 TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4,
355 SAMR_FIELD_LOGON_HOURS);
357 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
358 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
359 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
361 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
362 (base_acct_flags | ACB_DISABLED),
363 (base_acct_flags | ACB_DISABLED | user_extra_flags),
366 /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
367 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
368 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
369 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
371 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
372 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
373 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
376 /* The 'autolock' flag doesn't stick - check this */
377 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
378 (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK),
379 (base_acct_flags | ACB_DISABLED | user_extra_flags),
381 TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags,
382 (base_acct_flags | ACB_DISABLED),
383 (base_acct_flags | ACB_DISABLED | user_extra_flags),
384 SAMR_FIELD_ACCT_FLAGS);
387 /* these fail with win2003 - it appears you can't set the primary gid?
388 the set succeeds, but the gid isn't changed. Very weird! */
389 TEST_USERINFO_INT(9, primary_gid, 1, primary_gid, 513);
390 TEST_USERINFO_INT(9, primary_gid, 3, primary_gid, 513);
391 TEST_USERINFO_INT(9, primary_gid, 5, primary_gid, 513);
392 TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
399 generate a random password for password change tests
401 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
403 size_t len = MAX(8, min_len) + (random() % 6);
404 char *s = generate_random_str(mem_ctx, len);
405 printf("Generated password '%s'\n", s);
409 static BOOL test_SetUserPass(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
410 struct policy_handle *handle, char **password)
413 struct samr_SetUserInfo s;
414 union samr_UserInfo u;
416 DATA_BLOB session_key;
418 struct samr_GetUserPwInfo pwp;
419 int policy_min_pw_len = 0;
420 pwp.in.user_handle = handle;
422 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
423 if (NT_STATUS_IS_OK(status)) {
424 policy_min_pw_len = pwp.out.info.min_password_length;
426 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
428 s.in.user_handle = handle;
432 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
433 /* w2k3 ignores this length */
434 u.info24.pw_len = strlen_m(newpass) * 2;
436 status = dcerpc_fetch_session_key(p, &session_key);
437 if (!NT_STATUS_IS_OK(status)) {
438 printf("SetUserInfo level %u - no session key - %s\n",
439 s.in.level, nt_errstr(status));
443 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
445 printf("Testing SetUserInfo level 24 (set password)\n");
447 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
448 if (!NT_STATUS_IS_OK(status)) {
449 printf("SetUserInfo level %u failed - %s\n",
450 s.in.level, nt_errstr(status));
460 static BOOL test_SetUserPass_23(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
461 struct policy_handle *handle, uint32_t fields_present,
465 struct samr_SetUserInfo s;
466 union samr_UserInfo u;
468 DATA_BLOB session_key;
470 struct samr_GetUserPwInfo pwp;
471 int policy_min_pw_len = 0;
472 pwp.in.user_handle = handle;
474 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
475 if (NT_STATUS_IS_OK(status)) {
476 policy_min_pw_len = pwp.out.info.min_password_length;
478 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
480 s.in.user_handle = handle;
486 u.info23.info.fields_present = fields_present;
488 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
490 status = dcerpc_fetch_session_key(p, &session_key);
491 if (!NT_STATUS_IS_OK(status)) {
492 printf("SetUserInfo level %u - no session key - %s\n",
493 s.in.level, nt_errstr(status));
497 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
499 printf("Testing SetUserInfo level 23 (set password)\n");
501 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
502 if (!NT_STATUS_IS_OK(status)) {
503 printf("SetUserInfo level %u failed - %s\n",
504 s.in.level, nt_errstr(status));
514 static BOOL test_SetUserPassEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
515 struct policy_handle *handle, char **password)
518 struct samr_SetUserInfo s;
519 union samr_UserInfo u;
521 DATA_BLOB session_key;
522 DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
523 uint8_t confounder[16];
525 struct MD5Context ctx;
526 struct samr_GetUserPwInfo pwp;
527 int policy_min_pw_len = 0;
528 pwp.in.user_handle = handle;
530 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
531 if (NT_STATUS_IS_OK(status)) {
532 policy_min_pw_len = pwp.out.info.min_password_length;
534 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
536 s.in.user_handle = handle;
540 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
541 u.info26.pw_len = strlen(newpass);
543 status = dcerpc_fetch_session_key(p, &session_key);
544 if (!NT_STATUS_IS_OK(status)) {
545 printf("SetUserInfo level %u - no session key - %s\n",
546 s.in.level, nt_errstr(status));
550 generate_random_buffer((uint8_t *)confounder, 16);
553 MD5Update(&ctx, confounder, 16);
554 MD5Update(&ctx, session_key.data, session_key.length);
555 MD5Final(confounded_session_key.data, &ctx);
557 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
558 memcpy(&u.info26.password.data[516], confounder, 16);
560 printf("Testing SetUserInfo level 26 (set password ex)\n");
562 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
563 if (!NT_STATUS_IS_OK(status)) {
564 printf("SetUserInfo level %u failed - %s\n",
565 s.in.level, nt_errstr(status));
574 static BOOL test_SetUserPass_25(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
575 struct policy_handle *handle, uint32_t fields_present,
579 struct samr_SetUserInfo s;
580 union samr_UserInfo u;
582 DATA_BLOB session_key;
583 DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
584 struct MD5Context ctx;
585 uint8_t confounder[16];
587 struct samr_GetUserPwInfo pwp;
588 int policy_min_pw_len = 0;
589 pwp.in.user_handle = handle;
591 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
592 if (NT_STATUS_IS_OK(status)) {
593 policy_min_pw_len = pwp.out.info.min_password_length;
595 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
597 s.in.user_handle = handle;
603 u.info25.info.fields_present = fields_present;
605 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
607 status = dcerpc_fetch_session_key(p, &session_key);
608 if (!NT_STATUS_IS_OK(status)) {
609 printf("SetUserInfo level %u - no session key - %s\n",
610 s.in.level, nt_errstr(status));
614 generate_random_buffer((uint8_t *)confounder, 16);
617 MD5Update(&ctx, confounder, 16);
618 MD5Update(&ctx, session_key.data, session_key.length);
619 MD5Final(confounded_session_key.data, &ctx);
621 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
622 memcpy(&u.info25.password.data[516], confounder, 16);
624 printf("Testing SetUserInfo level 25 (set password ex)\n");
626 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
627 if (!NT_STATUS_IS_OK(status)) {
628 printf("SetUserInfo level %u failed - %s\n",
629 s.in.level, nt_errstr(status));
638 static BOOL test_SetAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
639 struct policy_handle *handle)
642 struct samr_SetAliasInfo r;
643 struct samr_QueryAliasInfo q;
644 uint16_t levels[] = {2, 3};
648 /* Ignoring switch level 1, as that includes the number of members for the alias
649 * and setting this to a wrong value might have negative consequences
652 for (i=0;i<ARRAY_SIZE(levels);i++) {
653 printf("Testing SetAliasInfo level %u\n", levels[i]);
655 r.in.alias_handle = handle;
656 r.in.level = levels[i];
657 r.in.info = talloc(mem_ctx, union samr_AliasInfo);
658 switch (r.in.level) {
659 case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
660 case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
661 "Test Description, should test I18N as well"); break;
664 status = dcerpc_samr_SetAliasInfo(p, mem_ctx, &r);
665 if (!NT_STATUS_IS_OK(status)) {
666 printf("SetAliasInfo level %u failed - %s\n",
667 levels[i], nt_errstr(status));
671 q.in.alias_handle = handle;
672 q.in.level = levels[i];
674 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &q);
675 if (!NT_STATUS_IS_OK(status)) {
676 printf("QueryAliasInfo level %u failed - %s\n",
677 levels[i], nt_errstr(status));
685 static BOOL test_GetGroupsForUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
686 struct policy_handle *user_handle)
688 struct samr_GetGroupsForUser r;
692 printf("testing GetGroupsForUser\n");
694 r.in.user_handle = user_handle;
696 status = dcerpc_samr_GetGroupsForUser(p, mem_ctx, &r);
697 if (!NT_STATUS_IS_OK(status)) {
698 printf("GetGroupsForUser failed - %s\n",nt_errstr(status));
706 static BOOL test_GetDomPwInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
707 struct lsa_String *domain_name)
710 struct samr_GetDomPwInfo r;
713 r.in.domain_name = domain_name;
714 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
716 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
717 if (!NT_STATUS_IS_OK(status)) {
718 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
722 r.in.domain_name->string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
723 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
725 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
726 if (!NT_STATUS_IS_OK(status)) {
727 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
731 r.in.domain_name->string = "\\\\__NONAME__";
732 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
734 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
735 if (!NT_STATUS_IS_OK(status)) {
736 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
740 r.in.domain_name->string = "\\\\Builtin";
741 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
743 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
744 if (!NT_STATUS_IS_OK(status)) {
745 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
753 static BOOL test_GetUserPwInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
754 struct policy_handle *handle)
757 struct samr_GetUserPwInfo r;
760 printf("Testing GetUserPwInfo\n");
762 r.in.user_handle = handle;
764 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &r);
765 if (!NT_STATUS_IS_OK(status)) {
766 printf("GetUserPwInfo failed - %s\n", nt_errstr(status));
773 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
774 struct policy_handle *domain_handle, const char *name,
778 struct samr_LookupNames n;
779 struct lsa_String sname[2];
781 init_lsa_String(&sname[0], name);
783 n.in.domain_handle = domain_handle;
786 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
787 if (NT_STATUS_IS_OK(status)) {
788 *rid = n.out.rids.ids[0];
793 init_lsa_String(&sname[1], "xxNONAMExx");
795 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
796 if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
797 printf("LookupNames[2] failed - %s\n", nt_errstr(status));
801 init_lsa_String(&sname[1], "xxNONAMExx");
803 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
804 if (!NT_STATUS_IS_OK(status)) {
805 printf("LookupNames[0] failed - %s\n", nt_errstr(status));
811 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
812 struct policy_handle *domain_handle,
813 const char *name, struct policy_handle *user_handle)
816 struct samr_OpenUser r;
819 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
820 if (!NT_STATUS_IS_OK(status)) {
824 r.in.domain_handle = domain_handle;
825 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
827 r.out.user_handle = user_handle;
828 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
829 if (!NT_STATUS_IS_OK(status)) {
830 printf("OpenUser_byname(%s) failed - %s\n", name, nt_errstr(status));
837 static BOOL test_ChangePasswordNT3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
838 struct policy_handle *handle)
841 struct samr_ChangePasswordUser r;
843 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
844 struct policy_handle user_handle;
845 char *oldpass = "test";
846 char *newpass = "test2";
847 uint8_t old_nt_hash[16], new_nt_hash[16];
848 uint8_t old_lm_hash[16], new_lm_hash[16];
850 status = test_OpenUser_byname(p, mem_ctx, handle, "testuser", &user_handle);
851 if (!NT_STATUS_IS_OK(status)) {
855 printf("Testing ChangePasswordUser for user 'testuser'\n");
857 printf("old password: %s\n", oldpass);
858 printf("new password: %s\n", newpass);
860 E_md4hash(oldpass, old_nt_hash);
861 E_md4hash(newpass, new_nt_hash);
862 E_deshash(oldpass, old_lm_hash);
863 E_deshash(newpass, new_lm_hash);
865 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
866 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
867 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
868 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
869 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
870 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
872 r.in.handle = &user_handle;
874 r.in.old_lm_crypted = &hash1;
875 r.in.new_lm_crypted = &hash2;
877 r.in.old_nt_crypted = &hash3;
878 r.in.new_nt_crypted = &hash4;
879 r.in.cross1_present = 1;
880 r.in.nt_cross = &hash5;
881 r.in.cross2_present = 1;
882 r.in.lm_cross = &hash6;
884 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
885 if (!NT_STATUS_IS_OK(status)) {
886 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
890 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
898 static BOOL test_ChangePasswordUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
899 struct policy_handle *handle, char **password)
902 struct samr_ChangePasswordUser r;
904 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
905 struct policy_handle user_handle;
906 char *oldpass = *password;
907 uint8_t old_nt_hash[16], new_nt_hash[16];
908 uint8_t old_lm_hash[16], new_lm_hash[16];
911 struct samr_GetUserPwInfo pwp;
912 int policy_min_pw_len = 0;
914 status = test_OpenUser_byname(p, mem_ctx, handle, TEST_ACCOUNT_NAME, &user_handle);
915 if (!NT_STATUS_IS_OK(status)) {
918 pwp.in.user_handle = &user_handle;
920 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
921 if (NT_STATUS_IS_OK(status)) {
922 policy_min_pw_len = pwp.out.info.min_password_length;
924 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
926 printf("Testing ChangePasswordUser\n");
928 E_md4hash(oldpass, old_nt_hash);
929 E_md4hash(newpass, new_nt_hash);
930 E_deshash(oldpass, old_lm_hash);
931 E_deshash(newpass, new_lm_hash);
933 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
934 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
935 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
936 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
937 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
938 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
940 r.in.user_handle = &user_handle;
942 r.in.old_lm_crypted = &hash1;
943 r.in.new_lm_crypted = &hash2;
945 r.in.old_nt_crypted = &hash3;
946 r.in.new_nt_crypted = &hash4;
947 r.in.cross1_present = 1;
948 r.in.nt_cross = &hash5;
949 r.in.cross2_present = 1;
950 r.in.lm_cross = &hash6;
952 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
953 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
954 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
955 } else if (!NT_STATUS_IS_OK(status)) {
956 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
962 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
970 static BOOL test_OemChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
971 struct policy_handle *handle, char **password)
974 struct samr_OemChangePasswordUser2 r;
976 struct samr_Password lm_verifier;
977 struct samr_CryptPassword lm_pass;
978 struct lsa_AsciiString server, account, account_bad;
979 char *oldpass = *password;
981 uint8_t old_lm_hash[16], new_lm_hash[16];
983 struct samr_GetDomPwInfo dom_pw_info;
984 int policy_min_pw_len = 0;
986 struct lsa_String domain_name;
987 domain_name.string = "";
988 dom_pw_info.in.domain_name = &domain_name;
990 printf("Testing OemChangePasswordUser2\n");
992 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &dom_pw_info);
993 if (NT_STATUS_IS_OK(status)) {
994 policy_min_pw_len = dom_pw_info.out.info.min_password_length;
997 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
999 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1000 account.string = TEST_ACCOUNT_NAME;
1002 E_deshash(oldpass, old_lm_hash);
1003 E_deshash(newpass, new_lm_hash);
1005 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1006 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1007 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1009 r.in.server = &server;
1010 r.in.account = &account;
1011 r.in.password = &lm_pass;
1012 r.in.hash = &lm_verifier;
1014 /* Break the verification */
1015 lm_verifier.hash[0]++;
1017 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1019 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1020 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1021 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1026 /* This shouldn't be a valid name */
1027 account_bad.string = TEST_ACCOUNT_NAME "XX";
1028 r.in.account = &account_bad;
1030 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1032 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1033 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1038 E_deshash(oldpass, old_lm_hash);
1039 E_deshash(newpass, new_lm_hash);
1041 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1042 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1043 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1045 r.in.server = &server;
1046 r.in.account = &account;
1047 r.in.password = &lm_pass;
1048 r.in.hash = &lm_verifier;
1050 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1051 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1052 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1053 } else if (!NT_STATUS_IS_OK(status)) {
1054 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
1057 *password = newpass;
1064 static BOOL test_ChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1065 struct policy_handle *handle, char **password)
1068 struct samr_ChangePasswordUser2 r;
1070 struct lsa_String server, account;
1071 struct samr_CryptPassword nt_pass, lm_pass;
1072 struct samr_Password nt_verifier, lm_verifier;
1073 char *oldpass = *password;
1075 uint8_t old_nt_hash[16], new_nt_hash[16];
1076 uint8_t old_lm_hash[16], new_lm_hash[16];
1078 struct samr_GetDomPwInfo dom_pw_info;
1079 int policy_min_pw_len = 0;
1081 struct lsa_String domain_name;
1082 domain_name.string = "";
1083 dom_pw_info.in.domain_name = &domain_name;
1085 printf("Testing ChangePasswordUser2\n");
1087 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &dom_pw_info);
1088 if (NT_STATUS_IS_OK(status)) {
1089 policy_min_pw_len = dom_pw_info.out.info.min_password_length;
1092 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1094 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1095 init_lsa_String(&account, TEST_ACCOUNT_NAME);
1097 E_md4hash(oldpass, old_nt_hash);
1098 E_md4hash(newpass, new_nt_hash);
1100 E_deshash(oldpass, old_lm_hash);
1101 E_deshash(newpass, new_lm_hash);
1103 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
1104 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1105 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1107 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1108 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1109 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1111 r.in.server = &server;
1112 r.in.account = &account;
1113 r.in.nt_password = &nt_pass;
1114 r.in.nt_verifier = &nt_verifier;
1116 r.in.lm_password = &lm_pass;
1117 r.in.lm_verifier = &lm_verifier;
1119 status = dcerpc_samr_ChangePasswordUser2(p, mem_ctx, &r);
1120 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1121 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1122 } else if (!NT_STATUS_IS_OK(status)) {
1123 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
1126 *password = newpass;
1133 BOOL test_ChangePasswordUser3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1134 const char *account_string,
1135 int policy_min_pw_len,
1139 struct samr_ChangePasswordUser3 r;
1141 struct lsa_String server, account, account_bad;
1142 struct samr_CryptPassword nt_pass, lm_pass;
1143 struct samr_Password nt_verifier, lm_verifier;
1144 char *oldpass = *password;
1145 char *newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1146 uint8_t old_nt_hash[16], new_nt_hash[16];
1147 uint8_t old_lm_hash[16], new_lm_hash[16];
1149 printf("Testing ChangePasswordUser3\n");
1151 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1152 init_lsa_String(&account, account_string);
1154 E_md4hash(oldpass, old_nt_hash);
1155 E_md4hash(newpass, new_nt_hash);
1157 E_deshash(oldpass, old_lm_hash);
1158 E_deshash(newpass, new_lm_hash);
1160 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1161 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1162 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1164 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1165 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1166 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1168 /* Break the verification */
1169 nt_verifier.hash[0]++;
1171 r.in.server = &server;
1172 r.in.account = &account;
1173 r.in.nt_password = &nt_pass;
1174 r.in.nt_verifier = &nt_verifier;
1176 r.in.lm_password = &lm_pass;
1177 r.in.lm_verifier = &lm_verifier;
1178 r.in.password3 = NULL;
1180 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1181 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1182 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1183 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1188 /* This shouldn't be a valid name */
1189 init_lsa_String(&account_bad, talloc_asprintf(mem_ctx, "%sXX", account_string));
1191 r.in.account = &account_bad;
1192 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1193 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1194 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
1199 E_md4hash(oldpass, old_nt_hash);
1200 E_md4hash(newpass, new_nt_hash);
1202 E_deshash(oldpass, old_lm_hash);
1203 E_deshash(newpass, new_lm_hash);
1205 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1206 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1207 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1209 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1210 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1211 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1213 r.in.server = &server;
1214 r.in.account = &account;
1215 r.in.nt_password = &nt_pass;
1216 r.in.nt_verifier = &nt_verifier;
1218 r.in.lm_password = &lm_pass;
1219 r.in.lm_verifier = &lm_verifier;
1220 r.in.password3 = NULL;
1222 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1223 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1224 && !policy_min_pw_len) {
1225 if (r.out.dominfo) {
1226 policy_min_pw_len = r.out.dominfo->min_password_length;
1228 if (policy_min_pw_len) /* try again with the right min password length */ {
1229 ret = test_ChangePasswordUser3(p, mem_ctx, account_string, policy_min_pw_len, password);
1231 printf("ChangePasswordUser3 failed (no min length known) - %s\n", nt_errstr(status));
1234 } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1235 printf("ChangePasswordUser3 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1236 } else if (!NT_STATUS_IS_OK(status)) {
1237 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
1240 *password = newpass;
1247 static BOOL test_GetMembersInAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1248 struct policy_handle *alias_handle)
1250 struct samr_GetMembersInAlias r;
1251 struct lsa_SidArray sids;
1255 printf("Testing GetMembersInAlias\n");
1257 r.in.alias_handle = alias_handle;
1260 status = dcerpc_samr_GetMembersInAlias(p, mem_ctx, &r);
1261 if (!NT_STATUS_IS_OK(status)) {
1262 printf("GetMembersInAlias failed - %s\n",
1270 static BOOL test_AddMemberToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1271 struct policy_handle *alias_handle,
1272 const struct dom_sid *domain_sid)
1274 struct samr_AddAliasMember r;
1275 struct samr_DeleteAliasMember d;
1278 struct dom_sid *sid;
1280 sid = dom_sid_add_rid(mem_ctx, domain_sid, 512);
1282 printf("testing AddAliasMember\n");
1283 r.in.alias_handle = alias_handle;
1286 status = dcerpc_samr_AddAliasMember(p, mem_ctx, &r);
1287 if (!NT_STATUS_IS_OK(status)) {
1288 printf("AddAliasMember failed - %s\n", nt_errstr(status));
1292 d.in.alias_handle = alias_handle;
1295 status = dcerpc_samr_DeleteAliasMember(p, mem_ctx, &d);
1296 if (!NT_STATUS_IS_OK(status)) {
1297 printf("DelAliasMember failed - %s\n", nt_errstr(status));
1304 static BOOL test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1305 struct policy_handle *alias_handle)
1307 struct samr_AddMultipleMembersToAlias a;
1308 struct samr_RemoveMultipleMembersFromAlias r;
1311 struct lsa_SidArray sids;
1313 printf("testing AddMultipleMembersToAlias\n");
1314 a.in.alias_handle = alias_handle;
1318 sids.sids = talloc_array(mem_ctx, struct lsa_SidPtr, 3);
1320 sids.sids[0].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-1");
1321 sids.sids[1].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-2");
1322 sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-3");
1324 status = dcerpc_samr_AddMultipleMembersToAlias(p, mem_ctx, &a);
1325 if (!NT_STATUS_IS_OK(status)) {
1326 printf("AddMultipleMembersToAlias failed - %s\n", nt_errstr(status));
1331 printf("testing RemoveMultipleMembersFromAlias\n");
1332 r.in.alias_handle = alias_handle;
1335 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1336 if (!NT_STATUS_IS_OK(status)) {
1337 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1341 /* strange! removing twice doesn't give any error */
1342 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1343 if (!NT_STATUS_IS_OK(status)) {
1344 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1348 /* but removing an alias that isn't there does */
1349 sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-4");
1351 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1352 if (!NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_NOT_FOUND, status)) {
1353 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1360 static BOOL test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1361 struct policy_handle *user_handle)
1363 struct samr_TestPrivateFunctionsUser r;
1367 printf("Testing TestPrivateFunctionsUser\n");
1369 r.in.user_handle = user_handle;
1371 status = dcerpc_samr_TestPrivateFunctionsUser(p, mem_ctx, &r);
1372 if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
1373 printf("TestPrivateFunctionsUser failed - %s\n", nt_errstr(status));
1381 static BOOL test_user_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1382 struct policy_handle *handle, uint32_t base_acct_flags,
1383 const char *base_acct_name)
1387 if (!test_QuerySecurity(p, mem_ctx, handle)) {
1391 if (!test_QueryUserInfo(p, mem_ctx, handle)) {
1395 if (!test_QueryUserInfo2(p, mem_ctx, handle)) {
1399 if (!test_SetUserInfo(p, mem_ctx, handle, base_acct_flags,
1404 if (!test_GetUserPwInfo(p, mem_ctx, handle)) {
1408 if (!test_TestPrivateFunctionsUser(p, mem_ctx, handle)) {
1415 static BOOL test_alias_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1416 struct policy_handle *alias_handle,
1417 const struct dom_sid *domain_sid)
1421 if (!test_QuerySecurity(p, mem_ctx, alias_handle)) {
1425 if (!test_QueryAliasInfo(p, mem_ctx, alias_handle)) {
1429 if (!test_SetAliasInfo(p, mem_ctx, alias_handle)) {
1433 if (!test_AddMemberToAlias(p, mem_ctx, alias_handle, domain_sid)) {
1437 if (!test_AddMultipleMembersToAlias(p, mem_ctx, alias_handle)) {
1445 BOOL test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1446 struct policy_handle *handle, const char *name)
1449 struct samr_DeleteUser d;
1450 struct policy_handle user_handle;
1453 status = test_LookupName(p, mem_ctx, handle, name, &rid);
1454 if (!NT_STATUS_IS_OK(status)) {
1458 status = test_OpenUser_byname(p, mem_ctx, handle, name, &user_handle);
1459 if (!NT_STATUS_IS_OK(status)) {
1463 d.in.user_handle = &user_handle;
1464 d.out.user_handle = &user_handle;
1465 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
1466 if (!NT_STATUS_IS_OK(status)) {
1473 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
1478 static BOOL test_DeleteGroup_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1479 struct policy_handle *handle, const char *name)
1482 struct samr_OpenGroup r;
1483 struct samr_DeleteDomainGroup d;
1484 struct policy_handle group_handle;
1487 status = test_LookupName(p, mem_ctx, handle, name, &rid);
1488 if (!NT_STATUS_IS_OK(status)) {
1492 r.in.domain_handle = handle;
1493 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1495 r.out.group_handle = &group_handle;
1496 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
1497 if (!NT_STATUS_IS_OK(status)) {
1501 d.in.group_handle = &group_handle;
1502 d.out.group_handle = &group_handle;
1503 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
1504 if (!NT_STATUS_IS_OK(status)) {
1511 printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
1516 static BOOL test_DeleteAlias_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1517 struct policy_handle *domain_handle, const char *name)
1520 struct samr_OpenAlias r;
1521 struct samr_DeleteDomAlias d;
1522 struct policy_handle alias_handle;
1525 printf("testing DeleteAlias_byname\n");
1527 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
1528 if (!NT_STATUS_IS_OK(status)) {
1532 r.in.domain_handle = domain_handle;
1533 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1535 r.out.alias_handle = &alias_handle;
1536 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
1537 if (!NT_STATUS_IS_OK(status)) {
1541 d.in.alias_handle = &alias_handle;
1542 d.out.alias_handle = &alias_handle;
1543 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
1544 if (!NT_STATUS_IS_OK(status)) {
1551 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
1555 static BOOL test_DeleteAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1556 struct policy_handle *alias_handle)
1558 struct samr_DeleteDomAlias d;
1561 printf("Testing DeleteAlias\n");
1563 d.in.alias_handle = alias_handle;
1564 d.out.alias_handle = alias_handle;
1566 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
1567 if (!NT_STATUS_IS_OK(status)) {
1568 printf("DeleteAlias failed - %s\n", nt_errstr(status));
1575 static BOOL test_CreateAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1576 struct policy_handle *domain_handle,
1577 struct policy_handle *alias_handle,
1578 const struct dom_sid *domain_sid)
1581 struct samr_CreateDomAlias r;
1582 struct lsa_String name;
1586 init_lsa_String(&name, TEST_ALIASNAME);
1587 r.in.domain_handle = domain_handle;
1588 r.in.alias_name = &name;
1589 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1590 r.out.alias_handle = alias_handle;
1593 printf("Testing CreateAlias (%s)\n", r.in.alias_name->string);
1595 status = dcerpc_samr_CreateDomAlias(p, mem_ctx, &r);
1597 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1598 printf("Server refused create of '%s'\n", r.in.alias_name->string);
1602 if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
1603 if (!test_DeleteAlias_byname(p, mem_ctx, domain_handle, r.in.alias_name->string)) {
1606 status = dcerpc_samr_CreateDomAlias(p, mem_ctx, &r);
1609 if (!NT_STATUS_IS_OK(status)) {
1610 printf("CreateAlias failed - %s\n", nt_errstr(status));
1614 if (!test_alias_ops(p, mem_ctx, alias_handle, domain_sid)) {
1621 static BOOL test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1622 struct policy_handle *domain_handle, char **password)
1630 if (!test_ChangePasswordUser(p, mem_ctx, domain_handle, password)) {
1634 if (!test_ChangePasswordUser2(p, mem_ctx, domain_handle, password)) {
1638 if (!test_OemChangePasswordUser2(p, mem_ctx, domain_handle, password)) {
1642 /* we change passwords twice - this has the effect of verifying
1643 they were changed correctly for the final call */
1644 if (!test_ChangePasswordUser3(p, mem_ctx, TEST_ACCOUNT_NAME, 0, password)) {
1648 if (!test_ChangePasswordUser3(p, mem_ctx, TEST_ACCOUNT_NAME, 0, password)) {
1655 static BOOL test_CreateUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1656 struct policy_handle *domain_handle, struct policy_handle *user_handle)
1659 struct samr_CreateUser r;
1660 struct samr_QueryUserInfo q;
1662 char *password = NULL;
1665 const uint32_t password_fields[] = {
1666 SAMR_FIELD_PASSWORD,
1667 SAMR_FIELD_PASSWORD2,
1668 SAMR_FIELD_PASSWORD | SAMR_FIELD_PASSWORD2,
1672 TALLOC_CTX *user_ctx;
1674 /* This call creates a 'normal' account - check that it really does */
1675 const uint32_t acct_flags = ACB_NORMAL;
1676 struct lsa_String name;
1679 user_ctx = talloc_named(mem_ctx, 0, "test_CreateUser2 per-user context");
1680 init_lsa_String(&name, TEST_ACCOUNT_NAME);
1682 r.in.domain_handle = domain_handle;
1683 r.in.account_name = &name;
1684 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1685 r.out.user_handle = user_handle;
1688 printf("Testing CreateUser(%s)\n", r.in.account_name->string);
1690 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
1692 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1693 printf("Server refused create of '%s'\n", r.in.account_name->string);
1694 ZERO_STRUCTP(user_handle);
1695 talloc_free(user_ctx);
1699 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
1700 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
1701 talloc_free(user_ctx);
1704 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
1706 if (!NT_STATUS_IS_OK(status)) {
1707 talloc_free(user_ctx);
1708 printf("CreateUser failed - %s\n", nt_errstr(status));
1712 q.in.user_handle = user_handle;
1715 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
1716 if (!NT_STATUS_IS_OK(status)) {
1717 printf("QueryUserInfo level %u failed - %s\n",
1718 q.in.level, nt_errstr(status));
1721 if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
1722 printf("QuerUserInfo level 16 failed, it returned 0x%08x (%u) when we expected flags of 0x%08x (%u)\n",
1723 q.out.info->info16.acct_flags, q.out.info->info16.acct_flags,
1724 acct_flags, acct_flags);
1729 if (!test_user_ops(p, user_ctx, user_handle, acct_flags, name.string)) {
1733 if (!test_SetUserPass(p, user_ctx, user_handle, &password)) {
1737 for (i = 0; password_fields[i]; i++) {
1738 if (!test_SetUserPass_23(p, user_ctx, user_handle, password_fields[i], &password)) {
1742 /* check it was set right */
1743 if (!test_ChangePasswordUser3(p, user_ctx, TEST_ACCOUNT_NAME, 0, &password)) {
1748 for (i = 0; password_fields[i]; i++) {
1749 if (!test_SetUserPass_25(p, user_ctx, user_handle, password_fields[i], &password)) {
1753 /* check it was set right */
1754 if (!test_ChangePasswordUser3(p, user_ctx, TEST_ACCOUNT_NAME, 0, &password)) {
1759 if (!test_SetUserPassEx(p, user_ctx, user_handle, &password)) {
1763 if (!test_ChangePassword(p, user_ctx, domain_handle, &password)) {
1767 talloc_free(user_ctx);
1773 static BOOL test_DeleteUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1774 struct policy_handle *user_handle)
1776 struct samr_DeleteUser d;
1780 printf("Testing DeleteUser\n");
1782 d.in.user_handle = user_handle;
1783 d.out.user_handle = user_handle;
1785 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
1786 if (!NT_STATUS_IS_OK(status)) {
1787 printf("DeleteUser failed - %s\n", nt_errstr(status));
1794 static BOOL test_CreateUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1795 struct policy_handle *handle)
1798 struct samr_CreateUser2 r;
1799 struct samr_QueryUserInfo q;
1800 struct samr_DeleteUser d;
1801 struct policy_handle user_handle;
1803 struct lsa_String name;
1808 uint32_t acct_flags;
1809 const char *account_name;
1811 } account_types[] = {
1812 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
1813 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1814 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1815 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
1816 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1817 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1818 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
1819 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1820 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1821 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
1822 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
1823 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
1824 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1825 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1826 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
1829 for (i = 0; account_types[i].account_name; i++) {
1830 TALLOC_CTX *user_ctx;
1831 uint32_t acct_flags = account_types[i].acct_flags;
1832 uint32_t access_granted;
1833 user_ctx = talloc_named(mem_ctx, 0, "test_CreateUser2 per-user context");
1834 init_lsa_String(&name, account_types[i].account_name);
1836 r.in.domain_handle = handle;
1837 r.in.account_name = &name;
1838 r.in.acct_flags = acct_flags;
1839 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1840 r.out.user_handle = &user_handle;
1841 r.out.access_granted = &access_granted;
1844 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
1846 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
1848 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1849 talloc_free(user_ctx);
1850 printf("Server refused create of '%s'\n", r.in.account_name->string);
1853 } else if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
1854 if (!test_DeleteUser_byname(p, user_ctx, handle, r.in.account_name->string)) {
1855 talloc_free(user_ctx);
1859 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
1862 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
1863 printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
1864 nt_errstr(status), nt_errstr(account_types[i].nt_status));
1868 if (NT_STATUS_IS_OK(status)) {
1869 q.in.user_handle = &user_handle;
1872 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
1873 if (!NT_STATUS_IS_OK(status)) {
1874 printf("QueryUserInfo level %u failed - %s\n",
1875 q.in.level, nt_errstr(status));
1878 if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
1879 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
1880 q.out.info->info16.acct_flags,
1886 if (!test_user_ops(p, user_ctx, &user_handle, acct_flags, name.string)) {
1890 printf("Testing DeleteUser (createuser2 test)\n");
1892 d.in.user_handle = &user_handle;
1893 d.out.user_handle = &user_handle;
1895 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
1896 if (!NT_STATUS_IS_OK(status)) {
1897 printf("DeleteUser failed - %s\n", nt_errstr(status));
1901 talloc_free(user_ctx);
1907 static BOOL test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1908 struct policy_handle *handle)
1911 struct samr_QueryAliasInfo r;
1912 uint16_t levels[] = {1, 2, 3};
1916 for (i=0;i<ARRAY_SIZE(levels);i++) {
1917 printf("Testing QueryAliasInfo level %u\n", levels[i]);
1919 r.in.alias_handle = handle;
1920 r.in.level = levels[i];
1922 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
1923 if (!NT_STATUS_IS_OK(status)) {
1924 printf("QueryAliasInfo level %u failed - %s\n",
1925 levels[i], nt_errstr(status));
1933 static BOOL test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1934 struct policy_handle *handle)
1937 struct samr_QueryGroupInfo r;
1938 uint16_t levels[] = {1, 2, 3, 4, 5};
1942 for (i=0;i<ARRAY_SIZE(levels);i++) {
1943 printf("Testing QueryGroupInfo level %u\n", levels[i]);
1945 r.in.group_handle = handle;
1946 r.in.level = levels[i];
1948 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
1949 if (!NT_STATUS_IS_OK(status)) {
1950 printf("QueryGroupInfo level %u failed - %s\n",
1951 levels[i], nt_errstr(status));
1959 static BOOL test_QueryGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1960 struct policy_handle *handle)
1963 struct samr_QueryGroupMember r;
1966 printf("Testing QueryGroupMember\n");
1968 r.in.group_handle = handle;
1970 status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &r);
1971 if (!NT_STATUS_IS_OK(status)) {
1972 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
1980 static BOOL test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1981 struct policy_handle *handle)
1984 struct samr_QueryGroupInfo r;
1985 struct samr_SetGroupInfo s;
1986 uint16_t levels[] = {1, 2, 3, 4};
1987 uint16_t set_ok[] = {0, 1, 1, 1};
1991 for (i=0;i<ARRAY_SIZE(levels);i++) {
1992 printf("Testing QueryGroupInfo level %u\n", levels[i]);
1994 r.in.group_handle = handle;
1995 r.in.level = levels[i];
1997 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
1998 if (!NT_STATUS_IS_OK(status)) {
1999 printf("QueryGroupInfo level %u failed - %s\n",
2000 levels[i], nt_errstr(status));
2004 printf("Testing SetGroupInfo level %u\n", levels[i]);
2006 s.in.group_handle = handle;
2007 s.in.level = levels[i];
2008 s.in.info = r.out.info;
2011 /* disabled this, as it changes the name only from the point of view of samr,
2012 but leaves the name from the point of view of w2k3 internals (and ldap). This means
2013 the name is still reserved, so creating the old name fails, but deleting by the old name
2015 if (s.in.level == 2) {
2016 init_lsa_String(&s.in.info->string, "NewName");
2020 if (s.in.level == 4) {
2021 init_lsa_String(&s.in.info->description, "test description");
2024 status = dcerpc_samr_SetGroupInfo(p, mem_ctx, &s);
2026 if (!NT_STATUS_IS_OK(status)) {
2027 printf("SetGroupInfo level %u failed - %s\n",
2028 r.in.level, nt_errstr(status));
2033 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
2034 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
2035 r.in.level, nt_errstr(status));
2045 static BOOL test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2046 struct policy_handle *handle)
2049 struct samr_QueryUserInfo r;
2050 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
2051 11, 12, 13, 14, 16, 17, 20, 21};
2055 for (i=0;i<ARRAY_SIZE(levels);i++) {
2056 printf("Testing QueryUserInfo level %u\n", levels[i]);
2058 r.in.user_handle = handle;
2059 r.in.level = levels[i];
2061 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
2062 if (!NT_STATUS_IS_OK(status)) {
2063 printf("QueryUserInfo level %u failed - %s\n",
2064 levels[i], nt_errstr(status));
2072 static BOOL test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2073 struct policy_handle *handle)
2076 struct samr_QueryUserInfo2 r;
2077 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
2078 11, 12, 13, 14, 16, 17, 20, 21};
2082 for (i=0;i<ARRAY_SIZE(levels);i++) {
2083 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
2085 r.in.user_handle = handle;
2086 r.in.level = levels[i];
2088 status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r);
2089 if (!NT_STATUS_IS_OK(status)) {
2090 printf("QueryUserInfo2 level %u failed - %s\n",
2091 levels[i], nt_errstr(status));
2099 static BOOL test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2100 struct policy_handle *handle, uint32_t rid)
2103 struct samr_OpenUser r;
2104 struct policy_handle user_handle;
2107 printf("Testing OpenUser(%u)\n", rid);
2109 r.in.domain_handle = handle;
2110 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2112 r.out.user_handle = &user_handle;
2114 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
2115 if (!NT_STATUS_IS_OK(status)) {
2116 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
2120 if (!test_QuerySecurity(p, mem_ctx, &user_handle)) {
2124 if (!test_QueryUserInfo(p, mem_ctx, &user_handle)) {
2128 if (!test_QueryUserInfo2(p, mem_ctx, &user_handle)) {
2132 if (!test_GetUserPwInfo(p, mem_ctx, &user_handle)) {
2136 if (!test_GetGroupsForUser(p,mem_ctx, &user_handle)) {
2140 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
2147 static BOOL test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2148 struct policy_handle *handle, uint32_t rid)
2151 struct samr_OpenGroup r;
2152 struct policy_handle group_handle;
2155 printf("Testing OpenGroup(%u)\n", rid);
2157 r.in.domain_handle = handle;
2158 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2160 r.out.group_handle = &group_handle;
2162 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
2163 if (!NT_STATUS_IS_OK(status)) {
2164 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
2168 if (!test_QuerySecurity(p, mem_ctx, &group_handle)) {
2172 if (!test_QueryGroupInfo(p, mem_ctx, &group_handle)) {
2176 if (!test_QueryGroupMember(p, mem_ctx, &group_handle)) {
2180 if (!test_samr_handle_Close(p, mem_ctx, &group_handle)) {
2187 static BOOL test_OpenAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2188 struct policy_handle *handle, uint32_t rid)
2191 struct samr_OpenAlias r;
2192 struct policy_handle alias_handle;
2195 printf("Testing OpenAlias(%u)\n", rid);
2197 r.in.domain_handle = handle;
2198 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2200 r.out.alias_handle = &alias_handle;
2202 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
2203 if (!NT_STATUS_IS_OK(status)) {
2204 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
2208 if (!test_QuerySecurity(p, mem_ctx, &alias_handle)) {
2212 if (!test_QueryAliasInfo(p, mem_ctx, &alias_handle)) {
2216 if (!test_GetMembersInAlias(p, mem_ctx, &alias_handle)) {
2220 if (!test_samr_handle_Close(p, mem_ctx, &alias_handle)) {
2227 static BOOL test_EnumDomainUsers(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2228 struct policy_handle *handle)
2231 struct samr_EnumDomainUsers r;
2232 uint32_t resume_handle=0;
2235 struct samr_LookupNames n;
2236 struct samr_LookupRids lr ;
2238 printf("Testing EnumDomainUsers\n");
2240 r.in.domain_handle = handle;
2241 r.in.resume_handle = &resume_handle;
2242 r.in.acct_flags = 0;
2243 r.in.max_size = (uint32_t)-1;
2244 r.out.resume_handle = &resume_handle;
2246 status = dcerpc_samr_EnumDomainUsers(p, mem_ctx, &r);
2247 if (!NT_STATUS_IS_OK(status)) {
2248 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
2256 if (r.out.sam->count == 0) {
2260 for (i=0;i<r.out.sam->count;i++) {
2261 if (!test_OpenUser(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
2266 printf("Testing LookupNames\n");
2267 n.in.domain_handle = handle;
2268 n.in.num_names = r.out.sam->count;
2269 n.in.names = talloc_array(mem_ctx, struct lsa_String, r.out.sam->count);
2270 for (i=0;i<r.out.sam->count;i++) {
2271 n.in.names[i].string = r.out.sam->entries[i].name.string;
2273 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
2274 if (!NT_STATUS_IS_OK(status)) {
2275 printf("LookupNames failed - %s\n", nt_errstr(status));
2280 printf("Testing LookupRids\n");
2281 lr.in.domain_handle = handle;
2282 lr.in.num_rids = r.out.sam->count;
2283 lr.in.rids = talloc_array(mem_ctx, uint32_t, r.out.sam->count);
2284 for (i=0;i<r.out.sam->count;i++) {
2285 lr.in.rids[i] = r.out.sam->entries[i].idx;
2287 status = dcerpc_samr_LookupRids(p, mem_ctx, &lr);
2288 if (!NT_STATUS_IS_OK(status)) {
2289 printf("LookupRids failed - %s\n", nt_errstr(status));
2297 try blasting the server with a bunch of sync requests
2299 static BOOL test_EnumDomainUsers_async(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2300 struct policy_handle *handle)
2303 struct samr_EnumDomainUsers r;
2304 uint32_t resume_handle=0;
2306 #define ASYNC_COUNT 100
2307 struct rpc_request *req[ASYNC_COUNT];
2309 if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
2310 printf("samr async test disabled - enable dangerous tests to use\n");
2314 printf("Testing EnumDomainUsers_async\n");
2316 r.in.domain_handle = handle;
2317 r.in.resume_handle = &resume_handle;
2318 r.in.acct_flags = 0;
2319 r.in.max_size = (uint32_t)-1;
2320 r.out.resume_handle = &resume_handle;
2322 for (i=0;i<ASYNC_COUNT;i++) {
2323 req[i] = dcerpc_samr_EnumDomainUsers_send(p, mem_ctx, &r);
2326 for (i=0;i<ASYNC_COUNT;i++) {
2327 status = dcerpc_ndr_request_recv(req[i]);
2328 if (!NT_STATUS_IS_OK(status)) {
2329 printf("EnumDomainUsers[%d] failed - %s\n",
2330 i, nt_errstr(status));
2335 printf("%d async requests OK\n", i);
2340 static BOOL test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2341 struct policy_handle *handle)
2344 struct samr_EnumDomainGroups r;
2345 uint32_t resume_handle=0;
2349 printf("Testing EnumDomainGroups\n");
2351 r.in.domain_handle = handle;
2352 r.in.resume_handle = &resume_handle;
2353 r.in.max_size = (uint32_t)-1;
2354 r.out.resume_handle = &resume_handle;
2356 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
2357 if (!NT_STATUS_IS_OK(status)) {
2358 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
2366 for (i=0;i<r.out.sam->count;i++) {
2367 if (!test_OpenGroup(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
2375 static BOOL test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2376 struct policy_handle *handle)
2379 struct samr_EnumDomainAliases r;
2380 uint32_t resume_handle=0;
2384 printf("Testing EnumDomainAliases\n");
2386 r.in.domain_handle = handle;
2387 r.in.resume_handle = &resume_handle;
2388 r.in.acct_flags = (uint32_t)-1;
2389 r.out.resume_handle = &resume_handle;
2391 status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
2392 if (!NT_STATUS_IS_OK(status)) {
2393 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
2401 for (i=0;i<r.out.sam->count;i++) {
2402 if (!test_OpenAlias(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
2410 static BOOL test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2411 struct policy_handle *handle)
2414 struct samr_GetDisplayEnumerationIndex r;
2416 uint16_t levels[] = {1, 2, 3, 4, 5};
2417 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
2420 for (i=0;i<ARRAY_SIZE(levels);i++) {
2421 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
2423 r.in.domain_handle = handle;
2424 r.in.level = levels[i];
2425 init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
2427 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
2430 !NT_STATUS_IS_OK(status) &&
2431 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2432 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
2433 levels[i], nt_errstr(status));
2437 init_lsa_String(&r.in.name, "zzzzzzzz");
2439 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
2441 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2442 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
2443 levels[i], nt_errstr(status));
2451 static BOOL test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2452 struct policy_handle *handle)
2455 struct samr_GetDisplayEnumerationIndex2 r;
2457 uint16_t levels[] = {1, 2, 3, 4, 5};
2458 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
2461 for (i=0;i<ARRAY_SIZE(levels);i++) {
2462 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
2464 r.in.domain_handle = handle;
2465 r.in.level = levels[i];
2466 init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
2468 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
2470 !NT_STATUS_IS_OK(status) &&
2471 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2472 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
2473 levels[i], nt_errstr(status));
2477 init_lsa_String(&r.in.name, "zzzzzzzz");
2479 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
2480 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2481 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
2482 levels[i], nt_errstr(status));
2490 static BOOL test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2491 struct policy_handle *handle)
2494 struct samr_QueryDisplayInfo r;
2496 uint16_t levels[] = {1, 2, 3, 4, 5};
2499 for (i=0;i<ARRAY_SIZE(levels);i++) {
2500 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
2502 r.in.domain_handle = handle;
2503 r.in.level = levels[i];
2505 r.in.max_entries = 1000;
2506 r.in.buf_size = (uint32_t)-1;
2508 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
2509 if (!NT_STATUS_IS_OK(status)) {
2510 printf("QueryDisplayInfo level %u failed - %s\n",
2511 levels[i], nt_errstr(status));
2519 static BOOL test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2520 struct policy_handle *handle)
2523 struct samr_QueryDisplayInfo2 r;
2525 uint16_t levels[] = {1, 2, 3, 4, 5};
2528 for (i=0;i<ARRAY_SIZE(levels);i++) {
2529 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
2531 r.in.domain_handle = handle;
2532 r.in.level = levels[i];
2534 r.in.max_entries = 1000;
2535 r.in.buf_size = (uint32_t)-1;
2537 status = dcerpc_samr_QueryDisplayInfo2(p, mem_ctx, &r);
2538 if (!NT_STATUS_IS_OK(status)) {
2539 printf("QueryDisplayInfo2 level %u failed - %s\n",
2540 levels[i], nt_errstr(status));
2548 static BOOL test_QueryDisplayInfo3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2549 struct policy_handle *handle)
2552 struct samr_QueryDisplayInfo3 r;
2554 uint16_t levels[] = {1, 2, 3, 4, 5};
2557 for (i=0;i<ARRAY_SIZE(levels);i++) {
2558 printf("Testing QueryDisplayInfo3 level %u\n", levels[i]);
2560 r.in.domain_handle = handle;
2561 r.in.level = levels[i];
2563 r.in.max_entries = 1000;
2564 r.in.buf_size = (uint32_t)-1;
2566 status = dcerpc_samr_QueryDisplayInfo3(p, mem_ctx, &r);
2567 if (!NT_STATUS_IS_OK(status)) {
2568 printf("QueryDisplayInfo3 level %u failed - %s\n",
2569 levels[i], nt_errstr(status));
2578 static BOOL test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2579 struct policy_handle *handle)
2582 struct samr_QueryDisplayInfo r;
2585 printf("Testing QueryDisplayInfo continuation\n");
2587 r.in.domain_handle = handle;
2590 r.in.max_entries = 1;
2591 r.in.buf_size = (uint32_t)-1;
2594 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
2595 if (NT_STATUS_IS_OK(status) && r.out.returned_size != 0) {
2596 if (r.out.info.info1.entries[0].idx != r.in.start_idx + 1) {
2597 printf("failed: expected idx %d but got %d\n",
2599 r.out.info.info1.entries[0].idx);
2604 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
2605 !NT_STATUS_IS_OK(status)) {
2606 printf("QueryDisplayInfo level %u failed - %s\n",
2607 r.in.level, nt_errstr(status));
2612 } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
2613 NT_STATUS_IS_OK(status)) &&
2614 r.out.returned_size != 0);
2619 static BOOL test_QueryDomainInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2620 struct policy_handle *handle)
2623 struct samr_QueryDomainInfo r;
2624 struct samr_SetDomainInfo s;
2625 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
2626 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
2630 for (i=0;i<ARRAY_SIZE(levels);i++) {
2631 printf("Testing QueryDomainInfo level %u\n", levels[i]);
2633 r.in.domain_handle = handle;
2634 r.in.level = levels[i];
2636 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2637 if (!NT_STATUS_IS_OK(status)) {
2638 printf("QueryDomainInfo level %u failed - %s\n",
2639 r.in.level, nt_errstr(status));
2644 printf("Testing SetDomainInfo level %u\n", levels[i]);
2646 s.in.domain_handle = handle;
2647 s.in.level = levels[i];
2648 s.in.info = r.out.info;
2650 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2652 if (!NT_STATUS_IS_OK(status)) {
2653 printf("SetDomainInfo level %u failed - %s\n",
2654 r.in.level, nt_errstr(status));
2659 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
2660 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
2661 r.in.level, nt_errstr(status));
2667 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2668 if (!NT_STATUS_IS_OK(status)) {
2669 printf("QueryDomainInfo level %u failed - %s\n",
2670 r.in.level, nt_errstr(status));
2680 static BOOL test_QueryDomainInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2681 struct policy_handle *handle)
2684 struct samr_QueryDomainInfo2 r;
2685 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
2689 for (i=0;i<ARRAY_SIZE(levels);i++) {
2690 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
2692 r.in.domain_handle = handle;
2693 r.in.level = levels[i];
2695 status = dcerpc_samr_QueryDomainInfo2(p, mem_ctx, &r);
2696 if (!NT_STATUS_IS_OK(status)) {
2697 printf("QueryDomainInfo2 level %u failed - %s\n",
2698 r.in.level, nt_errstr(status));
2707 /* Test whether querydispinfo level 5 and enumdomgroups return the same
2708 set of group names. */
2709 static BOOL test_GroupList(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2710 struct policy_handle *handle)
2712 struct samr_EnumDomainGroups q1;
2713 struct samr_QueryDisplayInfo q2;
2715 uint32_t resume_handle=0;
2720 const char **names = NULL;
2722 printf("Testing coherency of querydispinfo vs enumdomgroups\n");
2724 q1.in.domain_handle = handle;
2725 q1.in.resume_handle = &resume_handle;
2727 q1.out.resume_handle = &resume_handle;
2729 status = STATUS_MORE_ENTRIES;
2730 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
2731 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &q1);
2733 if (!NT_STATUS_IS_OK(status) &&
2734 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
2737 for (i=0; i<q1.out.num_entries; i++) {
2738 add_string_to_array(mem_ctx,
2739 q1.out.sam->entries[i].name.string,
2740 &names, &num_names);
2744 if (!NT_STATUS_IS_OK(status)) {
2745 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
2753 q2.in.domain_handle = handle;
2755 q2.in.start_idx = 0;
2756 q2.in.max_entries = 5;
2757 q2.in.buf_size = (uint32_t)-1;
2759 status = STATUS_MORE_ENTRIES;
2760 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
2761 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &q2);
2763 if (!NT_STATUS_IS_OK(status) &&
2764 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
2767 for (i=0; i<q2.out.info.info5.count; i++) {
2769 const char *name = q2.out.info.info5.entries[i].account_name.string;
2771 for (j=0; j<num_names; j++) {
2772 if (names[j] == NULL)
2774 /* Hmm. No strequal in samba4 */
2775 if (strequal(names[j], name)) {
2783 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
2788 q2.in.start_idx += q2.out.info.info5.count;
2791 if (!NT_STATUS_IS_OK(status)) {
2792 printf("QueryDisplayInfo level 5 failed - %s\n",
2797 for (i=0; i<num_names; i++) {
2798 if (names[i] != NULL) {
2799 printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
2808 static BOOL test_DeleteDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2809 struct policy_handle *group_handle)
2811 struct samr_DeleteDomainGroup d;
2815 printf("Testing DeleteDomainGroup\n");
2817 d.in.group_handle = group_handle;
2818 d.out.group_handle = group_handle;
2820 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
2821 if (!NT_STATUS_IS_OK(status)) {
2822 printf("DeleteDomainGroup failed - %s\n", nt_errstr(status));
2829 static BOOL test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2830 struct policy_handle *domain_handle)
2832 struct samr_TestPrivateFunctionsDomain r;
2836 printf("Testing TestPrivateFunctionsDomain\n");
2838 r.in.domain_handle = domain_handle;
2840 status = dcerpc_samr_TestPrivateFunctionsDomain(p, mem_ctx, &r);
2841 if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
2842 printf("TestPrivateFunctionsDomain failed - %s\n", nt_errstr(status));
2849 static BOOL test_RidToSid(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2850 struct dom_sid *domain_sid,
2851 struct policy_handle *domain_handle)
2853 struct samr_RidToSid r;
2856 struct dom_sid *calc_sid;
2857 int rids[] = { 0, 42, 512, 10200 };
2860 for (i=0;i<ARRAY_SIZE(rids);i++) {
2862 printf("Testing RidToSid\n");
2864 calc_sid = dom_sid_dup(mem_ctx, domain_sid);
2865 r.in.domain_handle = domain_handle;
2868 status = dcerpc_samr_RidToSid(p, mem_ctx, &r);
2869 if (!NT_STATUS_IS_OK(status)) {
2870 printf("RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
2873 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
2875 if (!dom_sid_equal(calc_sid, r.out.sid)) {
2876 printf("RidToSid for %d failed - got %s, expected %s\n", rids[i],
2877 dom_sid_string(mem_ctx, r.out.sid),
2878 dom_sid_string(mem_ctx, calc_sid));
2887 static BOOL test_GetBootKeyInformation(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2888 struct policy_handle *domain_handle)
2890 struct samr_GetBootKeyInformation r;
2894 printf("Testing GetBootKeyInformation\n");
2896 r.in.domain_handle = domain_handle;
2898 status = dcerpc_samr_GetBootKeyInformation(p, mem_ctx, &r);
2899 if (!NT_STATUS_IS_OK(status)) {
2900 /* w2k3 seems to fail this sometimes and pass it sometimes */
2901 printf("GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
2907 static BOOL test_AddGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2908 struct policy_handle *domain_handle,
2909 struct policy_handle *group_handle)
2912 struct samr_AddGroupMember r;
2913 struct samr_DeleteGroupMember d;
2914 struct samr_QueryGroupMember q;
2915 struct samr_SetMemberAttributesOfGroup s;
2919 status = test_LookupName(p, mem_ctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
2920 if (!NT_STATUS_IS_OK(status)) {
2924 r.in.group_handle = group_handle;
2926 r.in.flags = 0; /* ??? */
2928 printf("Testing AddGroupMember and DeleteGroupMember\n");
2930 d.in.group_handle = group_handle;
2933 status = dcerpc_samr_DeleteGroupMember(p, mem_ctx, &d);
2934 if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_NOT_IN_GROUP, status)) {
2935 printf("DeleteGroupMember gave %s - should be NT_STATUS_MEMBER_NOT_IN_GROUP\n",
2940 status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
2941 if (!NT_STATUS_IS_OK(status)) {
2942 printf("AddGroupMember failed - %s\n", nt_errstr(status));
2946 status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
2947 if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_IN_GROUP, status)) {
2948 printf("AddGroupMember gave %s - should be NT_STATUS_MEMBER_IN_GROUP\n",
2953 /* this one is quite strange. I am using random inputs in the
2954 hope of triggering an error that might give us a clue */
2955 s.in.group_handle = group_handle;
2956 s.in.unknown1 = random();
2957 s.in.unknown2 = random();
2959 status = dcerpc_samr_SetMemberAttributesOfGroup(p, mem_ctx, &s);
2960 if (!NT_STATUS_IS_OK(status)) {
2961 printf("SetMemberAttributesOfGroup failed - %s\n", nt_errstr(status));
2965 q.in.group_handle = group_handle;
2967 status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &q);
2968 if (!NT_STATUS_IS_OK(status)) {
2969 printf("QueryGroupMember failed - %s\n", nt_errstr(status));
2973 status = dcerpc_samr_DeleteGroupMember(p, mem_ctx, &d);
2974 if (!NT_STATUS_IS_OK(status)) {
2975 printf("DeleteGroupMember failed - %s\n", nt_errstr(status));
2979 status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
2980 if (!NT_STATUS_IS_OK(status)) {
2981 printf("AddGroupMember failed - %s\n", nt_errstr(status));
2989 static BOOL test_CreateDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2990 struct policy_handle *domain_handle, struct policy_handle *group_handle)
2993 struct samr_CreateDomainGroup r;
2995 struct lsa_String name;
2998 init_lsa_String(&name, TEST_GROUPNAME);
3000 r.in.domain_handle = domain_handle;
3002 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3003 r.out.group_handle = group_handle;
3006 printf("Testing CreateDomainGroup(%s)\n", r.in.name->string);
3008 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
3010 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
3011 printf("Server refused create of '%s'\n", r.in.name->string);
3012 ZERO_STRUCTP(group_handle);
3016 if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS) ||
3017 NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
3018 if (!test_DeleteGroup_byname(p, mem_ctx, domain_handle, r.in.name->string)) {
3021 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
3023 if (!NT_STATUS_IS_OK(status)) {
3024 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
3028 if (!test_AddGroupMember(p, mem_ctx, domain_handle, group_handle)) {
3032 if (!test_SetGroupInfo(p, mem_ctx, group_handle)) {
3041 its not totally clear what this does. It seems to accept any sid you like.
3043 static BOOL test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p,
3044 TALLOC_CTX *mem_ctx,
3045 struct policy_handle *domain_handle)
3048 struct samr_RemoveMemberFromForeignDomain r;
3050 r.in.domain_handle = domain_handle;
3051 r.in.sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-12-34-56-78");
3053 status = dcerpc_samr_RemoveMemberFromForeignDomain(p, mem_ctx, &r);
3054 if (!NT_STATUS_IS_OK(status)) {
3055 printf("RemoveMemberFromForeignDomain failed - %s\n", nt_errstr(status));
3064 static BOOL test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3065 struct policy_handle *handle);
3067 static BOOL test_OpenDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3068 struct policy_handle *handle, struct dom_sid *sid)
3071 struct samr_OpenDomain r;
3072 struct policy_handle domain_handle;
3073 struct policy_handle user_handle;
3074 struct policy_handle alias_handle;
3075 struct policy_handle group_handle;
3078 ZERO_STRUCT(user_handle);
3079 ZERO_STRUCT(alias_handle);
3080 ZERO_STRUCT(group_handle);
3081 ZERO_STRUCT(domain_handle);
3083 printf("Testing OpenDomain\n");
3085 r.in.connect_handle = handle;
3086 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3088 r.out.domain_handle = &domain_handle;
3090 status = dcerpc_samr_OpenDomain(p, mem_ctx, &r);
3091 if (!NT_STATUS_IS_OK(status)) {
3092 printf("OpenDomain failed - %s\n", nt_errstr(status));
3096 /* run the domain tests with the main handle closed - this tests
3097 the servers reference counting */
3098 ret &= test_samr_handle_Close(p, mem_ctx, handle);
3100 ret &= test_QuerySecurity(p, mem_ctx, &domain_handle);
3101 ret &= test_RemoveMemberFromForeignDomain(p, mem_ctx, &domain_handle);
3102 ret &= test_CreateUser2(p, mem_ctx, &domain_handle);
3103 ret &= test_CreateUser(p, mem_ctx, &domain_handle, &user_handle);
3104 ret &= test_CreateAlias(p, mem_ctx, &domain_handle, &alias_handle, sid);
3105 ret &= test_CreateDomainGroup(p, mem_ctx, &domain_handle, &group_handle);
3106 ret &= test_QueryDomainInfo(p, mem_ctx, &domain_handle);
3107 ret &= test_QueryDomainInfo2(p, mem_ctx, &domain_handle);
3108 ret &= test_EnumDomainUsers(p, mem_ctx, &domain_handle);
3109 ret &= test_EnumDomainUsers_async(p, mem_ctx, &domain_handle);
3110 ret &= test_EnumDomainGroups(p, mem_ctx, &domain_handle);
3111 ret &= test_EnumDomainAliases(p, mem_ctx, &domain_handle);
3112 ret &= test_QueryDisplayInfo(p, mem_ctx, &domain_handle);
3113 ret &= test_QueryDisplayInfo2(p, mem_ctx, &domain_handle);
3114 ret &= test_QueryDisplayInfo3(p, mem_ctx, &domain_handle);
3115 ret &= test_QueryDisplayInfo_continue(p, mem_ctx, &domain_handle);
3116 ret &= test_GetDisplayEnumerationIndex(p, mem_ctx, &domain_handle);
3117 ret &= test_GetDisplayEnumerationIndex2(p, mem_ctx, &domain_handle);
3118 ret &= test_GroupList(p, mem_ctx, &domain_handle);
3119 ret &= test_TestPrivateFunctionsDomain(p, mem_ctx, &domain_handle);
3120 ret &= test_RidToSid(p, mem_ctx, sid, &domain_handle);
3121 ret &= test_GetBootKeyInformation(p, mem_ctx, &domain_handle);
3123 if (!policy_handle_empty(&user_handle) &&
3124 !test_DeleteUser(p, mem_ctx, &user_handle)) {
3128 if (!policy_handle_empty(&alias_handle) &&
3129 !test_DeleteAlias(p, mem_ctx, &alias_handle)) {
3133 if (!policy_handle_empty(&group_handle) &&
3134 !test_DeleteDomainGroup(p, mem_ctx, &group_handle)) {
3138 ret &= test_samr_handle_Close(p, mem_ctx, &domain_handle);
3140 /* reconnect the main handle */
3141 ret &= test_Connect(p, mem_ctx, handle);
3146 static BOOL test_LookupDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3147 struct policy_handle *handle, struct lsa_String *domain)
3150 struct samr_LookupDomain r;
3151 struct lsa_String n2;
3154 printf("Testing LookupDomain(%s)\n", domain->string);
3156 /* check for correct error codes */
3157 r.in.connect_handle = handle;
3158 r.in.domain_name = &n2;
3161 status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
3162 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_PARAMETER, status)) {
3163 printf("failed: LookupDomain expected NT_STATUS_INVALID_PARAMETER - %s\n", nt_errstr(status));
3167 n2.string = "xxNODOMAINxx";
3169 status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
3170 if (!NT_STATUS_EQUAL(NT_STATUS_NO_SUCH_DOMAIN, status)) {
3171 printf("failed: LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN - %s\n", nt_errstr(status));
3175 r.in.connect_handle = handle;
3176 r.in.domain_name = domain;
3178 status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
3179 if (!NT_STATUS_IS_OK(status)) {
3180 printf("LookupDomain failed - %s\n", nt_errstr(status));
3184 if (!test_GetDomPwInfo(p, mem_ctx, domain)) {
3188 if (!test_OpenDomain(p, mem_ctx, handle, r.out.sid)) {
3196 static BOOL test_EnumDomains(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3197 struct policy_handle *handle)
3200 struct samr_EnumDomains r;
3201 uint32_t resume_handle = 0;
3205 r.in.connect_handle = handle;
3206 r.in.resume_handle = &resume_handle;
3207 r.in.buf_size = (uint32_t)-1;
3208 r.out.resume_handle = &resume_handle;
3210 status = dcerpc_samr_EnumDomains(p, mem_ctx, &r);
3211 if (!NT_STATUS_IS_OK(status)) {
3212 printf("EnumDomains failed - %s\n", nt_errstr(status));
3220 for (i=0;i<r.out.sam->count;i++) {
3221 if (!test_LookupDomain(p, mem_ctx, handle,
3222 &r.out.sam->entries[i].name)) {
3227 status = dcerpc_samr_EnumDomains(p, mem_ctx, &r);
3228 if (!NT_STATUS_IS_OK(status)) {
3229 printf("EnumDomains failed - %s\n", nt_errstr(status));
3237 static BOOL test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3238 struct policy_handle *handle)
3241 struct samr_Connect r;
3242 struct samr_Connect2 r2;
3243 struct samr_Connect3 r3;
3244 struct samr_Connect4 r4;
3245 struct samr_Connect5 r5;
3246 union samr_ConnectInfo info;
3247 struct policy_handle h;
3248 BOOL ret = True, got_handle = False;
3250 printf("testing samr_Connect\n");
3252 r.in.system_name = 0;
3253 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3254 r.out.connect_handle = &h;
3256 status = dcerpc_samr_Connect(p, mem_ctx, &r);
3257 if (!NT_STATUS_IS_OK(status)) {
3258 printf("Connect failed - %s\n", nt_errstr(status));
3265 printf("testing samr_Connect2\n");
3267 r2.in.system_name = NULL;
3268 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3269 r2.out.connect_handle = &h;
3271 status = dcerpc_samr_Connect2(p, mem_ctx, &r2);
3272 if (!NT_STATUS_IS_OK(status)) {
3273 printf("Connect2 failed - %s\n", nt_errstr(status));
3277 test_samr_handle_Close(p, mem_ctx, handle);
3283 printf("testing samr_Connect3\n");
3285 r3.in.system_name = NULL;
3287 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3288 r3.out.connect_handle = &h;
3290 status = dcerpc_samr_Connect3(p, mem_ctx, &r3);
3291 if (!NT_STATUS_IS_OK(status)) {
3292 printf("Connect3 failed - %s\n", nt_errstr(status));
3296 test_samr_handle_Close(p, mem_ctx, handle);
3302 printf("testing samr_Connect4\n");
3304 r4.in.system_name = "";
3306 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3307 r4.out.connect_handle = &h;
3309 status = dcerpc_samr_Connect4(p, mem_ctx, &r4);
3310 if (!NT_STATUS_IS_OK(status)) {
3311 printf("Connect4 failed - %s\n", nt_errstr(status));
3315 test_samr_handle_Close(p, mem_ctx, handle);
3321 printf("testing samr_Connect5\n");
3323 info.info1.unknown1 = 0;
3324 info.info1.unknown2 = 0;
3326 r5.in.system_name = "";
3327 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3330 r5.out.info = &info;
3331 r5.out.connect_handle = &h;
3333 status = dcerpc_samr_Connect5(p, mem_ctx, &r5);
3334 if (!NT_STATUS_IS_OK(status)) {
3335 printf("Connect5 failed - %s\n", nt_errstr(status));
3339 test_samr_handle_Close(p, mem_ctx, handle);
3349 BOOL torture_rpc_samr(void)
3352 struct dcerpc_pipe *p;
3353 TALLOC_CTX *mem_ctx;
3355 struct policy_handle handle;
3357 mem_ctx = talloc_init("torture_rpc_samr");
3359 status = torture_rpc_connection(mem_ctx, &p, &dcerpc_table_samr);
3360 if (!NT_STATUS_IS_OK(status)) {
3361 talloc_free(mem_ctx);
3365 if (!test_Connect(p, mem_ctx, &handle)) {
3369 if (!test_QuerySecurity(p, mem_ctx, &handle)) {
3373 if (!test_EnumDomains(p, mem_ctx, &handle)) {
3377 if (!test_SetDsrmPassword(p, mem_ctx, &handle)) {
3381 if (!test_Shutdown(p, mem_ctx, &handle)) {
3385 if (!test_samr_handle_Close(p, mem_ctx, &handle)) {
3389 talloc_free(mem_ctx);