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"
28 #include "lib/crypto/crypto.h"
29 #include "auth/credentials/credentials.h"
30 #include "libcli/auth/proto.h"
31 #include "libcli/security/proto.h"
33 #define TEST_ACCOUNT_NAME "samrtorturetest"
34 #define TEST_ALIASNAME "samrtorturetestalias"
35 #define TEST_GROUPNAME "samrtorturetestgroup"
36 #define TEST_MACHINENAME "samrtestmach$"
37 #define TEST_DOMAINNAME "samrtestdom$"
40 static BOOL test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
41 struct policy_handle *handle);
43 static BOOL test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
44 struct policy_handle *handle);
46 static BOOL test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
47 struct policy_handle *handle);
49 static void init_lsa_String(struct lsa_String *string, const char *s)
54 BOOL test_samr_handle_Close(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
55 struct policy_handle *handle)
61 r.out.handle = handle;
63 status = dcerpc_samr_Close(p, mem_ctx, &r);
64 if (!NT_STATUS_IS_OK(status)) {
65 printf("Close handle failed - %s\n", nt_errstr(status));
72 static BOOL test_Shutdown(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
73 struct policy_handle *handle)
76 struct samr_Shutdown r;
78 if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
79 printf("samr_Shutdown disabled - enable dangerous tests to use\n");
83 r.in.connect_handle = handle;
85 printf("testing samr_Shutdown\n");
87 status = dcerpc_samr_Shutdown(p, mem_ctx, &r);
88 if (!NT_STATUS_IS_OK(status)) {
89 printf("samr_Shutdown failed - %s\n", nt_errstr(status));
96 static BOOL test_SetDsrmPassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
97 struct policy_handle *handle)
100 struct samr_SetDsrmPassword r;
101 struct lsa_String string;
102 struct samr_Password hash;
104 if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
105 printf("samr_SetDsrmPassword disabled - enable dangerous tests to use\n");
109 E_md4hash("TeSTDSRM123", hash.hash);
111 init_lsa_String(&string, "Administrator");
117 printf("testing samr_SetDsrmPassword\n");
119 status = dcerpc_samr_SetDsrmPassword(p, mem_ctx, &r);
120 if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
121 printf("samr_SetDsrmPassword failed - %s\n", nt_errstr(status));
129 static BOOL test_QuerySecurity(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
130 struct policy_handle *handle)
133 struct samr_QuerySecurity r;
134 struct samr_SetSecurity s;
136 r.in.handle = handle;
139 status = dcerpc_samr_QuerySecurity(p, mem_ctx, &r);
140 if (!NT_STATUS_IS_OK(status)) {
141 printf("QuerySecurity failed - %s\n", nt_errstr(status));
145 if (r.out.sdbuf == NULL) {
149 s.in.handle = handle;
151 s.in.sdbuf = r.out.sdbuf;
153 status = dcerpc_samr_SetSecurity(p, mem_ctx, &s);
154 if (!NT_STATUS_IS_OK(status)) {
155 printf("SetSecurity failed - %s\n", nt_errstr(status));
159 status = dcerpc_samr_QuerySecurity(p, mem_ctx, &r);
160 if (!NT_STATUS_IS_OK(status)) {
161 printf("QuerySecurity failed - %s\n", nt_errstr(status));
169 static BOOL test_SetUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
170 struct policy_handle *handle, uint32_t base_acct_flags,
171 const char *base_account_name)
174 struct samr_SetUserInfo s;
175 struct samr_SetUserInfo2 s2;
176 struct samr_QueryUserInfo q;
177 struct samr_QueryUserInfo q0;
178 union samr_UserInfo u;
180 const char *test_account_name;
182 uint32_t user_extra_flags = 0;
183 if (base_acct_flags == ACB_NORMAL) {
184 /* When created, accounts are expired by default */
185 user_extra_flags = ACB_PW_EXPIRED;
188 s.in.user_handle = handle;
191 s2.in.user_handle = handle;
194 q.in.user_handle = handle;
198 #define TESTCALL(call, r) \
199 status = dcerpc_samr_ ##call(p, mem_ctx, &r); \
200 if (!NT_STATUS_IS_OK(status)) { \
201 printf(#call " level %u failed - %s (%s)\n", \
202 r.in.level, nt_errstr(status), __location__); \
207 #define STRING_EQUAL(s1, s2, field) \
208 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
209 printf("Failed to set %s to '%s' (%s)\n", \
210 #field, s2, __location__); \
215 #define INT_EQUAL(i1, i2, field) \
217 printf("Failed to set %s to 0x%x - got 0x%x (%s)\n", \
218 #field, i2, i1, __location__); \
223 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
224 printf("field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
226 TESTCALL(QueryUserInfo, q) \
228 s2.in.level = lvl1; \
231 ZERO_STRUCT(u.info21); \
232 u.info21.fields_present = fpval; \
234 init_lsa_String(&u.info ## lvl1.field1, value); \
235 TESTCALL(SetUserInfo, s) \
236 TESTCALL(SetUserInfo2, s2) \
237 init_lsa_String(&u.info ## lvl1.field1, ""); \
238 TESTCALL(QueryUserInfo, q); \
240 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
242 TESTCALL(QueryUserInfo, q) \
244 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
247 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
248 printf("field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
250 TESTCALL(QueryUserInfo, q) \
252 s2.in.level = lvl1; \
255 uint8_t *bits = u.info21.logon_hours.bits; \
256 ZERO_STRUCT(u.info21); \
257 if (fpval == SAMR_FIELD_LOGON_HOURS) { \
258 u.info21.logon_hours.units_per_week = 168; \
259 u.info21.logon_hours.bits = bits; \
261 u.info21.fields_present = fpval; \
263 u.info ## lvl1.field1 = value; \
264 TESTCALL(SetUserInfo, s) \
265 TESTCALL(SetUserInfo2, s2) \
266 u.info ## lvl1.field1 = 0; \
267 TESTCALL(QueryUserInfo, q); \
269 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
271 TESTCALL(QueryUserInfo, q) \
273 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
276 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
277 TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
281 do { TESTCALL(QueryUserInfo, q0) } while (0);
283 TEST_USERINFO_STRING(2, comment, 1, comment, "xx2-1 comment", 0);
284 TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
285 TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment",
288 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-1", base_account_name);
289 TEST_USERINFO_STRING(7, account_name, 1, account_name, base_account_name, 0);
290 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-3", base_account_name);
291 TEST_USERINFO_STRING(7, account_name, 3, account_name, base_account_name, 0);
292 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-5", base_account_name);
293 TEST_USERINFO_STRING(7, account_name, 5, account_name, base_account_name, 0);
294 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-6", base_account_name);
295 TEST_USERINFO_STRING(7, account_name, 6, account_name, base_account_name, 0);
296 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-7", base_account_name);
297 TEST_USERINFO_STRING(7, account_name, 7, account_name, base_account_name, 0);
298 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-21", base_account_name);
299 TEST_USERINFO_STRING(7, account_name, 21, account_name, base_account_name, 0);
300 test_account_name = base_account_name;
301 TEST_USERINFO_STRING(21, account_name, 21, account_name, base_account_name,
302 SAMR_FIELD_ACCOUNT_NAME);
304 TEST_USERINFO_STRING(6, full_name, 1, full_name, "xx6-1 full_name", 0);
305 TEST_USERINFO_STRING(6, full_name, 3, full_name, "xx6-3 full_name", 0);
306 TEST_USERINFO_STRING(6, full_name, 5, full_name, "xx6-5 full_name", 0);
307 TEST_USERINFO_STRING(6, full_name, 6, full_name, "xx6-6 full_name", 0);
308 TEST_USERINFO_STRING(6, full_name, 8, full_name, "xx6-8 full_name", 0);
309 TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
310 TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
311 TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name",
312 SAMR_FIELD_FULL_NAME);
314 TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
315 TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
316 TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
317 TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script",
318 SAMR_FIELD_LOGON_SCRIPT);
320 TEST_USERINFO_STRING(12, profile_path, 3, profile_path, "xx12-3 profile_path", 0);
321 TEST_USERINFO_STRING(12, profile_path, 5, profile_path, "xx12-5 profile_path", 0);
322 TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
323 TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path",
324 SAMR_FIELD_PROFILE_PATH);
326 TEST_USERINFO_STRING(13, description, 1, description, "xx13-1 description", 0);
327 TEST_USERINFO_STRING(13, description, 5, description, "xx13-5 description", 0);
328 TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
329 TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description",
330 SAMR_FIELD_DESCRIPTION);
332 TEST_USERINFO_STRING(14, workstations, 3, workstations, "14workstation3", 0);
333 TEST_USERINFO_STRING(14, workstations, 5, workstations, "14workstation4", 0);
334 TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
335 TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21",
336 SAMR_FIELD_WORKSTATIONS);
338 TEST_USERINFO_STRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
339 TEST_USERINFO_STRING(21, parameters, 21, parameters, "xx21-21 parameters",
340 SAMR_FIELD_PARAMETERS);
342 TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
343 TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__,
344 SAMR_FIELD_COUNTRY_CODE);
346 TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
347 TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__,
348 SAMR_FIELD_CODE_PAGE);
350 TEST_USERINFO_INT(4, logon_hours.bits[3], 3, logon_hours.bits[3], 1, 0);
351 TEST_USERINFO_INT(4, logon_hours.bits[3], 5, logon_hours.bits[3], 2, 0);
352 TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
353 TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4,
354 SAMR_FIELD_LOGON_HOURS);
356 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
357 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
358 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
360 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
361 (base_acct_flags | ACB_DISABLED),
362 (base_acct_flags | ACB_DISABLED | user_extra_flags),
365 /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
366 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
367 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
368 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
370 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
371 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
372 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
375 /* The 'autolock' flag doesn't stick - check this */
376 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
377 (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK),
378 (base_acct_flags | ACB_DISABLED | user_extra_flags),
380 TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags,
381 (base_acct_flags | ACB_DISABLED),
382 (base_acct_flags | ACB_DISABLED | user_extra_flags),
383 SAMR_FIELD_ACCT_FLAGS);
386 /* these fail with win2003 - it appears you can't set the primary gid?
387 the set succeeds, but the gid isn't changed. Very weird! */
388 TEST_USERINFO_INT(9, primary_gid, 1, primary_gid, 513);
389 TEST_USERINFO_INT(9, primary_gid, 3, primary_gid, 513);
390 TEST_USERINFO_INT(9, primary_gid, 5, primary_gid, 513);
391 TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
398 generate a random password for password change tests
400 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
402 size_t len = MAX(8, min_len) + (random() % 6);
403 char *s = generate_random_str(mem_ctx, len);
404 printf("Generated password '%s'\n", s);
408 static BOOL test_SetUserPass(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
409 struct policy_handle *handle, char **password)
412 struct samr_SetUserInfo s;
413 union samr_UserInfo u;
415 DATA_BLOB session_key;
417 struct samr_GetUserPwInfo pwp;
418 int policy_min_pw_len = 0;
419 pwp.in.user_handle = handle;
421 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
422 if (NT_STATUS_IS_OK(status)) {
423 policy_min_pw_len = pwp.out.info.min_password_length;
425 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
427 s.in.user_handle = handle;
431 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
432 /* w2k3 ignores this length */
433 u.info24.pw_len = strlen_m(newpass) * 2;
435 status = dcerpc_fetch_session_key(p, &session_key);
436 if (!NT_STATUS_IS_OK(status)) {
437 printf("SetUserInfo level %u - no session key - %s\n",
438 s.in.level, nt_errstr(status));
442 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
444 printf("Testing SetUserInfo level 24 (set password)\n");
446 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
447 if (!NT_STATUS_IS_OK(status)) {
448 printf("SetUserInfo level %u failed - %s\n",
449 s.in.level, nt_errstr(status));
459 static BOOL test_SetUserPass_23(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
460 struct policy_handle *handle, uint32_t fields_present,
464 struct samr_SetUserInfo s;
465 union samr_UserInfo u;
467 DATA_BLOB session_key;
469 struct samr_GetUserPwInfo pwp;
470 int policy_min_pw_len = 0;
471 pwp.in.user_handle = handle;
473 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
474 if (NT_STATUS_IS_OK(status)) {
475 policy_min_pw_len = pwp.out.info.min_password_length;
477 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
479 s.in.user_handle = handle;
485 u.info23.info.fields_present = fields_present;
487 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
489 status = dcerpc_fetch_session_key(p, &session_key);
490 if (!NT_STATUS_IS_OK(status)) {
491 printf("SetUserInfo level %u - no session key - %s\n",
492 s.in.level, nt_errstr(status));
496 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
498 printf("Testing SetUserInfo level 23 (set password)\n");
500 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
501 if (!NT_STATUS_IS_OK(status)) {
502 printf("SetUserInfo level %u failed - %s\n",
503 s.in.level, nt_errstr(status));
513 static BOOL test_SetUserPassEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
514 struct policy_handle *handle, char **password)
517 struct samr_SetUserInfo s;
518 union samr_UserInfo u;
520 DATA_BLOB session_key;
521 DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
522 uint8_t confounder[16];
524 struct MD5Context ctx;
525 struct samr_GetUserPwInfo pwp;
526 int policy_min_pw_len = 0;
527 pwp.in.user_handle = handle;
529 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
530 if (NT_STATUS_IS_OK(status)) {
531 policy_min_pw_len = pwp.out.info.min_password_length;
533 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
535 s.in.user_handle = handle;
539 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
540 u.info26.pw_len = strlen(newpass);
542 status = dcerpc_fetch_session_key(p, &session_key);
543 if (!NT_STATUS_IS_OK(status)) {
544 printf("SetUserInfo level %u - no session key - %s\n",
545 s.in.level, nt_errstr(status));
549 generate_random_buffer((uint8_t *)confounder, 16);
552 MD5Update(&ctx, confounder, 16);
553 MD5Update(&ctx, session_key.data, session_key.length);
554 MD5Final(confounded_session_key.data, &ctx);
556 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
557 memcpy(&u.info26.password.data[516], confounder, 16);
559 printf("Testing SetUserInfo level 26 (set password ex)\n");
561 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
562 if (!NT_STATUS_IS_OK(status)) {
563 printf("SetUserInfo level %u failed - %s\n",
564 s.in.level, nt_errstr(status));
573 static BOOL test_SetUserPass_25(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
574 struct policy_handle *handle, uint32_t fields_present,
578 struct samr_SetUserInfo s;
579 union samr_UserInfo u;
581 DATA_BLOB session_key;
582 DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
583 struct MD5Context ctx;
584 uint8_t confounder[16];
586 struct samr_GetUserPwInfo pwp;
587 int policy_min_pw_len = 0;
588 pwp.in.user_handle = handle;
590 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
591 if (NT_STATUS_IS_OK(status)) {
592 policy_min_pw_len = pwp.out.info.min_password_length;
594 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
596 s.in.user_handle = handle;
602 u.info25.info.fields_present = fields_present;
604 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
606 status = dcerpc_fetch_session_key(p, &session_key);
607 if (!NT_STATUS_IS_OK(status)) {
608 printf("SetUserInfo level %u - no session key - %s\n",
609 s.in.level, nt_errstr(status));
613 generate_random_buffer((uint8_t *)confounder, 16);
616 MD5Update(&ctx, confounder, 16);
617 MD5Update(&ctx, session_key.data, session_key.length);
618 MD5Final(confounded_session_key.data, &ctx);
620 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
621 memcpy(&u.info25.password.data[516], confounder, 16);
623 printf("Testing SetUserInfo level 25 (set password ex)\n");
625 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
626 if (!NT_STATUS_IS_OK(status)) {
627 printf("SetUserInfo level %u failed - %s\n",
628 s.in.level, nt_errstr(status));
637 static BOOL test_SetAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
638 struct policy_handle *handle)
641 struct samr_SetAliasInfo r;
642 struct samr_QueryAliasInfo q;
643 uint16_t levels[] = {2, 3};
647 /* Ignoring switch level 1, as that includes the number of members for the alias
648 * and setting this to a wrong value might have negative consequences
651 for (i=0;i<ARRAY_SIZE(levels);i++) {
652 printf("Testing SetAliasInfo level %u\n", levels[i]);
654 r.in.alias_handle = handle;
655 r.in.level = levels[i];
656 r.in.info = talloc(mem_ctx, union samr_AliasInfo);
657 switch (r.in.level) {
658 case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
659 case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
660 "Test Description, should test I18N as well"); break;
663 status = dcerpc_samr_SetAliasInfo(p, mem_ctx, &r);
664 if (!NT_STATUS_IS_OK(status)) {
665 printf("SetAliasInfo level %u failed - %s\n",
666 levels[i], nt_errstr(status));
670 q.in.alias_handle = handle;
671 q.in.level = levels[i];
673 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &q);
674 if (!NT_STATUS_IS_OK(status)) {
675 printf("QueryAliasInfo level %u failed - %s\n",
676 levels[i], nt_errstr(status));
684 static BOOL test_GetGroupsForUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
685 struct policy_handle *user_handle)
687 struct samr_GetGroupsForUser r;
691 printf("testing GetGroupsForUser\n");
693 r.in.user_handle = user_handle;
695 status = dcerpc_samr_GetGroupsForUser(p, mem_ctx, &r);
696 if (!NT_STATUS_IS_OK(status)) {
697 printf("GetGroupsForUser failed - %s\n",nt_errstr(status));
705 static BOOL test_GetDomPwInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
706 struct lsa_String *domain_name)
709 struct samr_GetDomPwInfo r;
712 r.in.domain_name = domain_name;
713 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
715 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
716 if (!NT_STATUS_IS_OK(status)) {
717 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
721 r.in.domain_name->string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
722 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
724 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
725 if (!NT_STATUS_IS_OK(status)) {
726 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
730 r.in.domain_name->string = "\\\\__NONAME__";
731 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
733 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
734 if (!NT_STATUS_IS_OK(status)) {
735 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
739 r.in.domain_name->string = "\\\\Builtin";
740 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
742 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
743 if (!NT_STATUS_IS_OK(status)) {
744 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
752 static BOOL test_GetUserPwInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
753 struct policy_handle *handle)
756 struct samr_GetUserPwInfo r;
759 printf("Testing GetUserPwInfo\n");
761 r.in.user_handle = handle;
763 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &r);
764 if (!NT_STATUS_IS_OK(status)) {
765 printf("GetUserPwInfo failed - %s\n", nt_errstr(status));
772 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
773 struct policy_handle *domain_handle, const char *name,
777 struct samr_LookupNames n;
778 struct lsa_String sname[2];
780 init_lsa_String(&sname[0], name);
782 n.in.domain_handle = domain_handle;
785 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
786 if (NT_STATUS_IS_OK(status)) {
787 *rid = n.out.rids.ids[0];
792 init_lsa_String(&sname[1], "xxNONAMExx");
794 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
795 if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
796 printf("LookupNames[2] failed - %s\n", nt_errstr(status));
800 init_lsa_String(&sname[1], "xxNONAMExx");
802 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
803 if (!NT_STATUS_IS_OK(status)) {
804 printf("LookupNames[0] failed - %s\n", nt_errstr(status));
810 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
811 struct policy_handle *domain_handle,
812 const char *name, struct policy_handle *user_handle)
815 struct samr_OpenUser r;
818 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
819 if (!NT_STATUS_IS_OK(status)) {
823 r.in.domain_handle = domain_handle;
824 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
826 r.out.user_handle = user_handle;
827 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
828 if (!NT_STATUS_IS_OK(status)) {
829 printf("OpenUser_byname(%s) failed - %s\n", name, nt_errstr(status));
836 static BOOL test_ChangePasswordNT3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
837 struct policy_handle *handle)
840 struct samr_ChangePasswordUser r;
842 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
843 struct policy_handle user_handle;
844 char *oldpass = "test";
845 char *newpass = "test2";
846 uint8_t old_nt_hash[16], new_nt_hash[16];
847 uint8_t old_lm_hash[16], new_lm_hash[16];
849 status = test_OpenUser_byname(p, mem_ctx, handle, "testuser", &user_handle);
850 if (!NT_STATUS_IS_OK(status)) {
854 printf("Testing ChangePasswordUser for user 'testuser'\n");
856 printf("old password: %s\n", oldpass);
857 printf("new password: %s\n", newpass);
859 E_md4hash(oldpass, old_nt_hash);
860 E_md4hash(newpass, new_nt_hash);
861 E_deshash(oldpass, old_lm_hash);
862 E_deshash(newpass, new_lm_hash);
864 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
865 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
866 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
867 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
868 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
869 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
871 r.in.handle = &user_handle;
873 r.in.old_lm_crypted = &hash1;
874 r.in.new_lm_crypted = &hash2;
876 r.in.old_nt_crypted = &hash3;
877 r.in.new_nt_crypted = &hash4;
878 r.in.cross1_present = 1;
879 r.in.nt_cross = &hash5;
880 r.in.cross2_present = 1;
881 r.in.lm_cross = &hash6;
883 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
884 if (!NT_STATUS_IS_OK(status)) {
885 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
889 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
897 static BOOL test_ChangePasswordUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
898 struct policy_handle *handle, char **password)
901 struct samr_ChangePasswordUser r;
903 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
904 struct policy_handle user_handle;
905 char *oldpass = *password;
906 uint8_t old_nt_hash[16], new_nt_hash[16];
907 uint8_t old_lm_hash[16], new_lm_hash[16];
910 struct samr_GetUserPwInfo pwp;
911 int policy_min_pw_len = 0;
913 status = test_OpenUser_byname(p, mem_ctx, handle, TEST_ACCOUNT_NAME, &user_handle);
914 if (!NT_STATUS_IS_OK(status)) {
917 pwp.in.user_handle = &user_handle;
919 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
920 if (NT_STATUS_IS_OK(status)) {
921 policy_min_pw_len = pwp.out.info.min_password_length;
923 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
925 printf("Testing ChangePasswordUser\n");
927 E_md4hash(oldpass, old_nt_hash);
928 E_md4hash(newpass, new_nt_hash);
929 E_deshash(oldpass, old_lm_hash);
930 E_deshash(newpass, new_lm_hash);
932 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
933 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
934 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
935 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
936 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
937 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
939 r.in.user_handle = &user_handle;
941 r.in.old_lm_crypted = &hash1;
942 r.in.new_lm_crypted = &hash2;
944 r.in.old_nt_crypted = &hash3;
945 r.in.new_nt_crypted = &hash4;
946 r.in.cross1_present = 1;
947 r.in.nt_cross = &hash5;
948 r.in.cross2_present = 1;
949 r.in.lm_cross = &hash6;
951 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
952 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
953 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
954 } else if (!NT_STATUS_IS_OK(status)) {
955 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
961 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
969 static BOOL test_OemChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
970 struct policy_handle *handle, char **password)
973 struct samr_OemChangePasswordUser2 r;
975 struct samr_Password lm_verifier;
976 struct samr_CryptPassword lm_pass;
977 struct lsa_AsciiString server, account, account_bad;
978 char *oldpass = *password;
980 uint8_t old_lm_hash[16], new_lm_hash[16];
982 struct samr_GetDomPwInfo dom_pw_info;
983 int policy_min_pw_len = 0;
985 struct lsa_String domain_name;
986 domain_name.string = "";
987 dom_pw_info.in.domain_name = &domain_name;
989 printf("Testing OemChangePasswordUser2\n");
991 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &dom_pw_info);
992 if (NT_STATUS_IS_OK(status)) {
993 policy_min_pw_len = dom_pw_info.out.info.min_password_length;
996 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
998 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
999 account.string = TEST_ACCOUNT_NAME;
1001 E_deshash(oldpass, old_lm_hash);
1002 E_deshash(newpass, new_lm_hash);
1004 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1005 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1006 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1008 r.in.server = &server;
1009 r.in.account = &account;
1010 r.in.password = &lm_pass;
1011 r.in.hash = &lm_verifier;
1013 /* Break the verification */
1014 lm_verifier.hash[0]++;
1016 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1018 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1019 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1020 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1025 /* This shouldn't be a valid name */
1026 account_bad.string = TEST_ACCOUNT_NAME "XX";
1027 r.in.account = &account_bad;
1029 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1031 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1032 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1037 E_deshash(oldpass, old_lm_hash);
1038 E_deshash(newpass, new_lm_hash);
1040 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1041 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1042 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1044 r.in.server = &server;
1045 r.in.account = &account;
1046 r.in.password = &lm_pass;
1047 r.in.hash = &lm_verifier;
1049 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1050 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1051 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1052 } else if (!NT_STATUS_IS_OK(status)) {
1053 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
1056 *password = newpass;
1063 static BOOL test_ChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1064 struct policy_handle *handle, char **password)
1067 struct samr_ChangePasswordUser2 r;
1069 struct lsa_String server, account;
1070 struct samr_CryptPassword nt_pass, lm_pass;
1071 struct samr_Password nt_verifier, lm_verifier;
1072 char *oldpass = *password;
1074 uint8_t old_nt_hash[16], new_nt_hash[16];
1075 uint8_t old_lm_hash[16], new_lm_hash[16];
1077 struct samr_GetDomPwInfo dom_pw_info;
1078 int policy_min_pw_len = 0;
1080 struct lsa_String domain_name;
1081 domain_name.string = "";
1082 dom_pw_info.in.domain_name = &domain_name;
1084 printf("Testing ChangePasswordUser2\n");
1086 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &dom_pw_info);
1087 if (NT_STATUS_IS_OK(status)) {
1088 policy_min_pw_len = dom_pw_info.out.info.min_password_length;
1091 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1093 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1094 init_lsa_String(&account, TEST_ACCOUNT_NAME);
1096 E_md4hash(oldpass, old_nt_hash);
1097 E_md4hash(newpass, new_nt_hash);
1099 E_deshash(oldpass, old_lm_hash);
1100 E_deshash(newpass, new_lm_hash);
1102 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
1103 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1104 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1106 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1107 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1108 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1110 r.in.server = &server;
1111 r.in.account = &account;
1112 r.in.nt_password = &nt_pass;
1113 r.in.nt_verifier = &nt_verifier;
1115 r.in.lm_password = &lm_pass;
1116 r.in.lm_verifier = &lm_verifier;
1118 status = dcerpc_samr_ChangePasswordUser2(p, mem_ctx, &r);
1119 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1120 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1121 } else if (!NT_STATUS_IS_OK(status)) {
1122 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
1125 *password = newpass;
1132 BOOL test_ChangePasswordUser3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1133 const char *account_string,
1134 int policy_min_pw_len,
1138 struct samr_ChangePasswordUser3 r;
1140 struct lsa_String server, account, account_bad;
1141 struct samr_CryptPassword nt_pass, lm_pass;
1142 struct samr_Password nt_verifier, lm_verifier;
1143 char *oldpass = *password;
1144 char *newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1145 uint8_t old_nt_hash[16], new_nt_hash[16];
1146 uint8_t old_lm_hash[16], new_lm_hash[16];
1148 printf("Testing ChangePasswordUser3\n");
1150 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1151 init_lsa_String(&account, account_string);
1153 E_md4hash(oldpass, old_nt_hash);
1154 E_md4hash(newpass, new_nt_hash);
1156 E_deshash(oldpass, old_lm_hash);
1157 E_deshash(newpass, new_lm_hash);
1159 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1160 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1161 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1163 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1164 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1165 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1167 /* Break the verification */
1168 nt_verifier.hash[0]++;
1170 r.in.server = &server;
1171 r.in.account = &account;
1172 r.in.nt_password = &nt_pass;
1173 r.in.nt_verifier = &nt_verifier;
1175 r.in.lm_password = &lm_pass;
1176 r.in.lm_verifier = &lm_verifier;
1177 r.in.password3 = NULL;
1179 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1180 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1181 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1182 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1187 /* This shouldn't be a valid name */
1188 init_lsa_String(&account_bad, talloc_asprintf(mem_ctx, "%sXX", account_string));
1190 r.in.account = &account_bad;
1191 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1192 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1193 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
1198 E_md4hash(oldpass, old_nt_hash);
1199 E_md4hash(newpass, new_nt_hash);
1201 E_deshash(oldpass, old_lm_hash);
1202 E_deshash(newpass, new_lm_hash);
1204 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1205 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1206 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1208 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1209 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1210 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1212 r.in.server = &server;
1213 r.in.account = &account;
1214 r.in.nt_password = &nt_pass;
1215 r.in.nt_verifier = &nt_verifier;
1217 r.in.lm_password = &lm_pass;
1218 r.in.lm_verifier = &lm_verifier;
1219 r.in.password3 = NULL;
1221 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1222 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1223 && !policy_min_pw_len) {
1224 if (r.out.dominfo) {
1225 policy_min_pw_len = r.out.dominfo->min_password_length;
1227 if (policy_min_pw_len) /* try again with the right min password length */ {
1228 ret = test_ChangePasswordUser3(p, mem_ctx, account_string, policy_min_pw_len, password);
1230 printf("ChangePasswordUser3 failed (no min length known) - %s\n", nt_errstr(status));
1233 } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1234 printf("ChangePasswordUser3 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1235 } else if (!NT_STATUS_IS_OK(status)) {
1236 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
1239 *password = newpass;
1246 static BOOL test_GetMembersInAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1247 struct policy_handle *alias_handle)
1249 struct samr_GetMembersInAlias r;
1250 struct lsa_SidArray sids;
1254 printf("Testing GetMembersInAlias\n");
1256 r.in.alias_handle = alias_handle;
1259 status = dcerpc_samr_GetMembersInAlias(p, mem_ctx, &r);
1260 if (!NT_STATUS_IS_OK(status)) {
1261 printf("GetMembersInAlias failed - %s\n",
1269 static BOOL test_AddMemberToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1270 struct policy_handle *alias_handle,
1271 const struct dom_sid *domain_sid)
1273 struct samr_AddAliasMember r;
1274 struct samr_DeleteAliasMember d;
1277 struct dom_sid *sid;
1279 sid = dom_sid_add_rid(mem_ctx, domain_sid, 512);
1281 printf("testing AddAliasMember\n");
1282 r.in.alias_handle = alias_handle;
1285 status = dcerpc_samr_AddAliasMember(p, mem_ctx, &r);
1286 if (!NT_STATUS_IS_OK(status)) {
1287 printf("AddAliasMember failed - %s\n", nt_errstr(status));
1291 d.in.alias_handle = alias_handle;
1294 status = dcerpc_samr_DeleteAliasMember(p, mem_ctx, &d);
1295 if (!NT_STATUS_IS_OK(status)) {
1296 printf("DelAliasMember failed - %s\n", nt_errstr(status));
1303 static BOOL test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1304 struct policy_handle *alias_handle)
1306 struct samr_AddMultipleMembersToAlias a;
1307 struct samr_RemoveMultipleMembersFromAlias r;
1310 struct lsa_SidArray sids;
1312 printf("testing AddMultipleMembersToAlias\n");
1313 a.in.alias_handle = alias_handle;
1317 sids.sids = talloc_array(mem_ctx, struct lsa_SidPtr, 3);
1319 sids.sids[0].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-1");
1320 sids.sids[1].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-2");
1321 sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-3");
1323 status = dcerpc_samr_AddMultipleMembersToAlias(p, mem_ctx, &a);
1324 if (!NT_STATUS_IS_OK(status)) {
1325 printf("AddMultipleMembersToAlias failed - %s\n", nt_errstr(status));
1330 printf("testing RemoveMultipleMembersFromAlias\n");
1331 r.in.alias_handle = alias_handle;
1334 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1335 if (!NT_STATUS_IS_OK(status)) {
1336 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1340 /* strange! removing twice doesn't give any error */
1341 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1342 if (!NT_STATUS_IS_OK(status)) {
1343 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1347 /* but removing an alias that isn't there does */
1348 sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-4");
1350 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1351 if (!NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_NOT_FOUND, status)) {
1352 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1359 static BOOL test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1360 struct policy_handle *user_handle)
1362 struct samr_TestPrivateFunctionsUser r;
1366 printf("Testing TestPrivateFunctionsUser\n");
1368 r.in.user_handle = user_handle;
1370 status = dcerpc_samr_TestPrivateFunctionsUser(p, mem_ctx, &r);
1371 if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
1372 printf("TestPrivateFunctionsUser failed - %s\n", nt_errstr(status));
1380 static BOOL test_user_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1381 struct policy_handle *handle, uint32_t base_acct_flags,
1382 const char *base_acct_name)
1386 if (!test_QuerySecurity(p, mem_ctx, handle)) {
1390 if (!test_QueryUserInfo(p, mem_ctx, handle)) {
1394 if (!test_QueryUserInfo2(p, mem_ctx, handle)) {
1398 if (!test_SetUserInfo(p, mem_ctx, handle, base_acct_flags,
1403 if (!test_GetUserPwInfo(p, mem_ctx, handle)) {
1407 if (!test_TestPrivateFunctionsUser(p, mem_ctx, handle)) {
1414 static BOOL test_alias_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1415 struct policy_handle *alias_handle,
1416 const struct dom_sid *domain_sid)
1420 if (!test_QuerySecurity(p, mem_ctx, alias_handle)) {
1424 if (!test_QueryAliasInfo(p, mem_ctx, alias_handle)) {
1428 if (!test_SetAliasInfo(p, mem_ctx, alias_handle)) {
1432 if (!test_AddMemberToAlias(p, mem_ctx, alias_handle, domain_sid)) {
1436 if (!test_AddMultipleMembersToAlias(p, mem_ctx, alias_handle)) {
1444 BOOL test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1445 struct policy_handle *handle, const char *name)
1448 struct samr_DeleteUser d;
1449 struct policy_handle user_handle;
1452 status = test_LookupName(p, mem_ctx, handle, name, &rid);
1453 if (!NT_STATUS_IS_OK(status)) {
1457 status = test_OpenUser_byname(p, mem_ctx, handle, name, &user_handle);
1458 if (!NT_STATUS_IS_OK(status)) {
1462 d.in.user_handle = &user_handle;
1463 d.out.user_handle = &user_handle;
1464 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
1465 if (!NT_STATUS_IS_OK(status)) {
1472 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
1477 static BOOL test_DeleteGroup_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1478 struct policy_handle *handle, const char *name)
1481 struct samr_OpenGroup r;
1482 struct samr_DeleteDomainGroup d;
1483 struct policy_handle group_handle;
1486 status = test_LookupName(p, mem_ctx, handle, name, &rid);
1487 if (!NT_STATUS_IS_OK(status)) {
1491 r.in.domain_handle = handle;
1492 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1494 r.out.group_handle = &group_handle;
1495 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
1496 if (!NT_STATUS_IS_OK(status)) {
1500 d.in.group_handle = &group_handle;
1501 d.out.group_handle = &group_handle;
1502 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
1503 if (!NT_STATUS_IS_OK(status)) {
1510 printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
1515 static BOOL test_DeleteAlias_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1516 struct policy_handle *domain_handle, const char *name)
1519 struct samr_OpenAlias r;
1520 struct samr_DeleteDomAlias d;
1521 struct policy_handle alias_handle;
1524 printf("testing DeleteAlias_byname\n");
1526 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
1527 if (!NT_STATUS_IS_OK(status)) {
1531 r.in.domain_handle = domain_handle;
1532 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1534 r.out.alias_handle = &alias_handle;
1535 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
1536 if (!NT_STATUS_IS_OK(status)) {
1540 d.in.alias_handle = &alias_handle;
1541 d.out.alias_handle = &alias_handle;
1542 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
1543 if (!NT_STATUS_IS_OK(status)) {
1550 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
1554 static BOOL test_DeleteAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1555 struct policy_handle *alias_handle)
1557 struct samr_DeleteDomAlias d;
1560 printf("Testing DeleteAlias\n");
1562 d.in.alias_handle = alias_handle;
1563 d.out.alias_handle = alias_handle;
1565 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
1566 if (!NT_STATUS_IS_OK(status)) {
1567 printf("DeleteAlias failed - %s\n", nt_errstr(status));
1574 static BOOL test_CreateAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1575 struct policy_handle *domain_handle,
1576 struct policy_handle *alias_handle,
1577 const struct dom_sid *domain_sid)
1580 struct samr_CreateDomAlias r;
1581 struct lsa_String name;
1585 init_lsa_String(&name, TEST_ALIASNAME);
1586 r.in.domain_handle = domain_handle;
1587 r.in.alias_name = &name;
1588 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1589 r.out.alias_handle = alias_handle;
1592 printf("Testing CreateAlias (%s)\n", r.in.alias_name->string);
1594 status = dcerpc_samr_CreateDomAlias(p, mem_ctx, &r);
1596 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1597 printf("Server refused create of '%s'\n", r.in.alias_name->string);
1601 if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
1602 if (!test_DeleteAlias_byname(p, mem_ctx, domain_handle, r.in.alias_name->string)) {
1605 status = dcerpc_samr_CreateDomAlias(p, mem_ctx, &r);
1608 if (!NT_STATUS_IS_OK(status)) {
1609 printf("CreateAlias failed - %s\n", nt_errstr(status));
1613 if (!test_alias_ops(p, mem_ctx, alias_handle, domain_sid)) {
1620 static BOOL test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1621 struct policy_handle *domain_handle, char **password)
1629 if (!test_ChangePasswordUser(p, mem_ctx, domain_handle, password)) {
1633 if (!test_ChangePasswordUser2(p, mem_ctx, domain_handle, password)) {
1637 if (!test_OemChangePasswordUser2(p, mem_ctx, domain_handle, password)) {
1641 /* we change passwords twice - this has the effect of verifying
1642 they were changed correctly for the final call */
1643 if (!test_ChangePasswordUser3(p, mem_ctx, TEST_ACCOUNT_NAME, 0, password)) {
1647 if (!test_ChangePasswordUser3(p, mem_ctx, TEST_ACCOUNT_NAME, 0, password)) {
1654 static BOOL test_CreateUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1655 struct policy_handle *domain_handle, struct policy_handle *user_handle)
1658 struct samr_CreateUser r;
1659 struct samr_QueryUserInfo q;
1661 char *password = NULL;
1664 const uint32_t password_fields[] = {
1665 SAMR_FIELD_PASSWORD,
1666 SAMR_FIELD_PASSWORD2,
1667 SAMR_FIELD_PASSWORD | SAMR_FIELD_PASSWORD2,
1671 TALLOC_CTX *user_ctx;
1673 /* This call creates a 'normal' account - check that it really does */
1674 const uint32_t acct_flags = ACB_NORMAL;
1675 struct lsa_String name;
1678 user_ctx = talloc_named(mem_ctx, 0, "test_CreateUser2 per-user context");
1679 init_lsa_String(&name, TEST_ACCOUNT_NAME);
1681 r.in.domain_handle = domain_handle;
1682 r.in.account_name = &name;
1683 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1684 r.out.user_handle = user_handle;
1687 printf("Testing CreateUser(%s)\n", r.in.account_name->string);
1689 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
1691 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1692 printf("Server refused create of '%s'\n", r.in.account_name->string);
1693 ZERO_STRUCTP(user_handle);
1694 talloc_free(user_ctx);
1698 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
1699 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
1700 talloc_free(user_ctx);
1703 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
1705 if (!NT_STATUS_IS_OK(status)) {
1706 talloc_free(user_ctx);
1707 printf("CreateUser failed - %s\n", nt_errstr(status));
1711 q.in.user_handle = user_handle;
1714 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
1715 if (!NT_STATUS_IS_OK(status)) {
1716 printf("QueryUserInfo level %u failed - %s\n",
1717 q.in.level, nt_errstr(status));
1720 if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
1721 printf("QuerUserInfo level 16 failed, it returned 0x%08x (%u) when we expected flags of 0x%08x (%u)\n",
1722 q.out.info->info16.acct_flags, q.out.info->info16.acct_flags,
1723 acct_flags, acct_flags);
1728 if (!test_user_ops(p, user_ctx, user_handle, acct_flags, name.string)) {
1732 if (!test_SetUserPass(p, user_ctx, user_handle, &password)) {
1736 for (i = 0; password_fields[i]; i++) {
1737 if (!test_SetUserPass_23(p, user_ctx, user_handle, password_fields[i], &password)) {
1741 /* check it was set right */
1742 if (!test_ChangePasswordUser3(p, user_ctx, TEST_ACCOUNT_NAME, 0, &password)) {
1747 for (i = 0; password_fields[i]; i++) {
1748 if (!test_SetUserPass_25(p, user_ctx, user_handle, password_fields[i], &password)) {
1752 /* check it was set right */
1753 if (!test_ChangePasswordUser3(p, user_ctx, TEST_ACCOUNT_NAME, 0, &password)) {
1758 if (!test_SetUserPassEx(p, user_ctx, user_handle, &password)) {
1762 if (!test_ChangePassword(p, user_ctx, domain_handle, &password)) {
1766 talloc_free(user_ctx);
1772 static BOOL test_DeleteUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1773 struct policy_handle *user_handle)
1775 struct samr_DeleteUser d;
1779 printf("Testing DeleteUser\n");
1781 d.in.user_handle = user_handle;
1782 d.out.user_handle = user_handle;
1784 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
1785 if (!NT_STATUS_IS_OK(status)) {
1786 printf("DeleteUser failed - %s\n", nt_errstr(status));
1793 static BOOL test_CreateUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1794 struct policy_handle *handle)
1797 struct samr_CreateUser2 r;
1798 struct samr_QueryUserInfo q;
1799 struct samr_DeleteUser d;
1800 struct policy_handle user_handle;
1802 struct lsa_String name;
1807 uint32_t acct_flags;
1808 const char *account_name;
1810 } account_types[] = {
1811 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
1812 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1813 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1814 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
1815 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1816 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1817 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
1818 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1819 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1820 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
1821 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
1822 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
1823 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1824 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1825 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
1828 for (i = 0; account_types[i].account_name; i++) {
1829 TALLOC_CTX *user_ctx;
1830 uint32_t acct_flags = account_types[i].acct_flags;
1831 uint32_t access_granted;
1832 user_ctx = talloc_named(mem_ctx, 0, "test_CreateUser2 per-user context");
1833 init_lsa_String(&name, account_types[i].account_name);
1835 r.in.domain_handle = handle;
1836 r.in.account_name = &name;
1837 r.in.acct_flags = acct_flags;
1838 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1839 r.out.user_handle = &user_handle;
1840 r.out.access_granted = &access_granted;
1843 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
1845 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
1847 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1848 talloc_free(user_ctx);
1849 printf("Server refused create of '%s'\n", r.in.account_name->string);
1852 } else if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
1853 if (!test_DeleteUser_byname(p, user_ctx, handle, r.in.account_name->string)) {
1854 talloc_free(user_ctx);
1858 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
1861 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
1862 printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
1863 nt_errstr(status), nt_errstr(account_types[i].nt_status));
1867 if (NT_STATUS_IS_OK(status)) {
1868 q.in.user_handle = &user_handle;
1871 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
1872 if (!NT_STATUS_IS_OK(status)) {
1873 printf("QueryUserInfo level %u failed - %s\n",
1874 q.in.level, nt_errstr(status));
1877 if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
1878 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
1879 q.out.info->info16.acct_flags,
1885 if (!test_user_ops(p, user_ctx, &user_handle, acct_flags, name.string)) {
1889 printf("Testing DeleteUser (createuser2 test)\n");
1891 d.in.user_handle = &user_handle;
1892 d.out.user_handle = &user_handle;
1894 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
1895 if (!NT_STATUS_IS_OK(status)) {
1896 printf("DeleteUser failed - %s\n", nt_errstr(status));
1900 talloc_free(user_ctx);
1906 static BOOL test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1907 struct policy_handle *handle)
1910 struct samr_QueryAliasInfo r;
1911 uint16_t levels[] = {1, 2, 3};
1915 for (i=0;i<ARRAY_SIZE(levels);i++) {
1916 printf("Testing QueryAliasInfo level %u\n", levels[i]);
1918 r.in.alias_handle = handle;
1919 r.in.level = levels[i];
1921 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
1922 if (!NT_STATUS_IS_OK(status)) {
1923 printf("QueryAliasInfo level %u failed - %s\n",
1924 levels[i], nt_errstr(status));
1932 static BOOL test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1933 struct policy_handle *handle)
1936 struct samr_QueryGroupInfo r;
1937 uint16_t levels[] = {1, 2, 3, 4, 5};
1941 for (i=0;i<ARRAY_SIZE(levels);i++) {
1942 printf("Testing QueryGroupInfo level %u\n", levels[i]);
1944 r.in.group_handle = handle;
1945 r.in.level = levels[i];
1947 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
1948 if (!NT_STATUS_IS_OK(status)) {
1949 printf("QueryGroupInfo level %u failed - %s\n",
1950 levels[i], nt_errstr(status));
1958 static BOOL test_QueryGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1959 struct policy_handle *handle)
1962 struct samr_QueryGroupMember r;
1965 printf("Testing QueryGroupMember\n");
1967 r.in.group_handle = handle;
1969 status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &r);
1970 if (!NT_STATUS_IS_OK(status)) {
1971 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
1979 static BOOL test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1980 struct policy_handle *handle)
1983 struct samr_QueryGroupInfo r;
1984 struct samr_SetGroupInfo s;
1985 uint16_t levels[] = {1, 2, 3, 4};
1986 uint16_t set_ok[] = {0, 1, 1, 1};
1990 for (i=0;i<ARRAY_SIZE(levels);i++) {
1991 printf("Testing QueryGroupInfo level %u\n", levels[i]);
1993 r.in.group_handle = handle;
1994 r.in.level = levels[i];
1996 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
1997 if (!NT_STATUS_IS_OK(status)) {
1998 printf("QueryGroupInfo level %u failed - %s\n",
1999 levels[i], nt_errstr(status));
2003 printf("Testing SetGroupInfo level %u\n", levels[i]);
2005 s.in.group_handle = handle;
2006 s.in.level = levels[i];
2007 s.in.info = r.out.info;
2010 /* disabled this, as it changes the name only from the point of view of samr,
2011 but leaves the name from the point of view of w2k3 internals (and ldap). This means
2012 the name is still reserved, so creating the old name fails, but deleting by the old name
2014 if (s.in.level == 2) {
2015 init_lsa_String(&s.in.info->string, "NewName");
2019 if (s.in.level == 4) {
2020 init_lsa_String(&s.in.info->description, "test description");
2023 status = dcerpc_samr_SetGroupInfo(p, mem_ctx, &s);
2025 if (!NT_STATUS_IS_OK(status)) {
2026 printf("SetGroupInfo level %u failed - %s\n",
2027 r.in.level, nt_errstr(status));
2032 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
2033 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
2034 r.in.level, nt_errstr(status));
2044 static BOOL test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2045 struct policy_handle *handle)
2048 struct samr_QueryUserInfo r;
2049 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
2050 11, 12, 13, 14, 16, 17, 20, 21};
2054 for (i=0;i<ARRAY_SIZE(levels);i++) {
2055 printf("Testing QueryUserInfo level %u\n", levels[i]);
2057 r.in.user_handle = handle;
2058 r.in.level = levels[i];
2060 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
2061 if (!NT_STATUS_IS_OK(status)) {
2062 printf("QueryUserInfo level %u failed - %s\n",
2063 levels[i], nt_errstr(status));
2071 static BOOL test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2072 struct policy_handle *handle)
2075 struct samr_QueryUserInfo2 r;
2076 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
2077 11, 12, 13, 14, 16, 17, 20, 21};
2081 for (i=0;i<ARRAY_SIZE(levels);i++) {
2082 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
2084 r.in.user_handle = handle;
2085 r.in.level = levels[i];
2087 status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r);
2088 if (!NT_STATUS_IS_OK(status)) {
2089 printf("QueryUserInfo2 level %u failed - %s\n",
2090 levels[i], nt_errstr(status));
2098 static BOOL test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2099 struct policy_handle *handle, uint32_t rid)
2102 struct samr_OpenUser r;
2103 struct policy_handle user_handle;
2106 printf("Testing OpenUser(%u)\n", rid);
2108 r.in.domain_handle = handle;
2109 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2111 r.out.user_handle = &user_handle;
2113 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
2114 if (!NT_STATUS_IS_OK(status)) {
2115 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
2119 if (!test_QuerySecurity(p, mem_ctx, &user_handle)) {
2123 if (!test_QueryUserInfo(p, mem_ctx, &user_handle)) {
2127 if (!test_QueryUserInfo2(p, mem_ctx, &user_handle)) {
2131 if (!test_GetUserPwInfo(p, mem_ctx, &user_handle)) {
2135 if (!test_GetGroupsForUser(p,mem_ctx, &user_handle)) {
2139 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
2146 static BOOL test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2147 struct policy_handle *handle, uint32_t rid)
2150 struct samr_OpenGroup r;
2151 struct policy_handle group_handle;
2154 printf("Testing OpenGroup(%u)\n", rid);
2156 r.in.domain_handle = handle;
2157 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2159 r.out.group_handle = &group_handle;
2161 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
2162 if (!NT_STATUS_IS_OK(status)) {
2163 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
2167 if (!test_QuerySecurity(p, mem_ctx, &group_handle)) {
2171 if (!test_QueryGroupInfo(p, mem_ctx, &group_handle)) {
2175 if (!test_QueryGroupMember(p, mem_ctx, &group_handle)) {
2179 if (!test_samr_handle_Close(p, mem_ctx, &group_handle)) {
2186 static BOOL test_OpenAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2187 struct policy_handle *handle, uint32_t rid)
2190 struct samr_OpenAlias r;
2191 struct policy_handle alias_handle;
2194 printf("Testing OpenAlias(%u)\n", rid);
2196 r.in.domain_handle = handle;
2197 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2199 r.out.alias_handle = &alias_handle;
2201 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
2202 if (!NT_STATUS_IS_OK(status)) {
2203 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
2207 if (!test_QuerySecurity(p, mem_ctx, &alias_handle)) {
2211 if (!test_QueryAliasInfo(p, mem_ctx, &alias_handle)) {
2215 if (!test_GetMembersInAlias(p, mem_ctx, &alias_handle)) {
2219 if (!test_samr_handle_Close(p, mem_ctx, &alias_handle)) {
2226 static BOOL test_EnumDomainUsers(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2227 struct policy_handle *handle)
2230 struct samr_EnumDomainUsers r;
2231 uint32_t resume_handle=0;
2234 struct samr_LookupNames n;
2235 struct samr_LookupRids lr ;
2237 printf("Testing EnumDomainUsers\n");
2239 r.in.domain_handle = handle;
2240 r.in.resume_handle = &resume_handle;
2241 r.in.acct_flags = 0;
2242 r.in.max_size = (uint32_t)-1;
2243 r.out.resume_handle = &resume_handle;
2245 status = dcerpc_samr_EnumDomainUsers(p, mem_ctx, &r);
2246 if (!NT_STATUS_IS_OK(status)) {
2247 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
2255 if (r.out.sam->count == 0) {
2259 for (i=0;i<r.out.sam->count;i++) {
2260 if (!test_OpenUser(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
2265 printf("Testing LookupNames\n");
2266 n.in.domain_handle = handle;
2267 n.in.num_names = r.out.sam->count;
2268 n.in.names = talloc_array(mem_ctx, struct lsa_String, r.out.sam->count);
2269 for (i=0;i<r.out.sam->count;i++) {
2270 n.in.names[i].string = r.out.sam->entries[i].name.string;
2272 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
2273 if (!NT_STATUS_IS_OK(status)) {
2274 printf("LookupNames failed - %s\n", nt_errstr(status));
2279 printf("Testing LookupRids\n");
2280 lr.in.domain_handle = handle;
2281 lr.in.num_rids = r.out.sam->count;
2282 lr.in.rids = talloc_array(mem_ctx, uint32_t, r.out.sam->count);
2283 for (i=0;i<r.out.sam->count;i++) {
2284 lr.in.rids[i] = r.out.sam->entries[i].idx;
2286 status = dcerpc_samr_LookupRids(p, mem_ctx, &lr);
2287 if (!NT_STATUS_IS_OK(status)) {
2288 printf("LookupRids failed - %s\n", nt_errstr(status));
2296 try blasting the server with a bunch of sync requests
2298 static BOOL test_EnumDomainUsers_async(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2299 struct policy_handle *handle)
2302 struct samr_EnumDomainUsers r;
2303 uint32_t resume_handle=0;
2305 #define ASYNC_COUNT 100
2306 struct rpc_request *req[ASYNC_COUNT];
2308 if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
2309 printf("samr async test disabled - enable dangerous tests to use\n");
2313 printf("Testing EnumDomainUsers_async\n");
2315 r.in.domain_handle = handle;
2316 r.in.resume_handle = &resume_handle;
2317 r.in.acct_flags = 0;
2318 r.in.max_size = (uint32_t)-1;
2319 r.out.resume_handle = &resume_handle;
2321 for (i=0;i<ASYNC_COUNT;i++) {
2322 req[i] = dcerpc_samr_EnumDomainUsers_send(p, mem_ctx, &r);
2325 for (i=0;i<ASYNC_COUNT;i++) {
2326 status = dcerpc_ndr_request_recv(req[i]);
2327 if (!NT_STATUS_IS_OK(status)) {
2328 printf("EnumDomainUsers[%d] failed - %s\n",
2329 i, nt_errstr(status));
2334 printf("%d async requests OK\n", i);
2339 static BOOL test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2340 struct policy_handle *handle)
2343 struct samr_EnumDomainGroups r;
2344 uint32_t resume_handle=0;
2348 printf("Testing EnumDomainGroups\n");
2350 r.in.domain_handle = handle;
2351 r.in.resume_handle = &resume_handle;
2352 r.in.max_size = (uint32_t)-1;
2353 r.out.resume_handle = &resume_handle;
2355 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
2356 if (!NT_STATUS_IS_OK(status)) {
2357 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
2365 for (i=0;i<r.out.sam->count;i++) {
2366 if (!test_OpenGroup(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
2374 static BOOL test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2375 struct policy_handle *handle)
2378 struct samr_EnumDomainAliases r;
2379 uint32_t resume_handle=0;
2383 printf("Testing EnumDomainAliases\n");
2385 r.in.domain_handle = handle;
2386 r.in.resume_handle = &resume_handle;
2387 r.in.acct_flags = (uint32_t)-1;
2388 r.out.resume_handle = &resume_handle;
2390 status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
2391 if (!NT_STATUS_IS_OK(status)) {
2392 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
2400 for (i=0;i<r.out.sam->count;i++) {
2401 if (!test_OpenAlias(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
2409 static BOOL test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2410 struct policy_handle *handle)
2413 struct samr_GetDisplayEnumerationIndex r;
2415 uint16_t levels[] = {1, 2, 3, 4, 5};
2416 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
2419 for (i=0;i<ARRAY_SIZE(levels);i++) {
2420 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
2422 r.in.domain_handle = handle;
2423 r.in.level = levels[i];
2424 init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
2426 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
2429 !NT_STATUS_IS_OK(status) &&
2430 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2431 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
2432 levels[i], nt_errstr(status));
2436 init_lsa_String(&r.in.name, "zzzzzzzz");
2438 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
2440 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2441 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
2442 levels[i], nt_errstr(status));
2450 static BOOL test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2451 struct policy_handle *handle)
2454 struct samr_GetDisplayEnumerationIndex2 r;
2456 uint16_t levels[] = {1, 2, 3, 4, 5};
2457 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
2460 for (i=0;i<ARRAY_SIZE(levels);i++) {
2461 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
2463 r.in.domain_handle = handle;
2464 r.in.level = levels[i];
2465 init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
2467 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
2469 !NT_STATUS_IS_OK(status) &&
2470 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2471 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
2472 levels[i], nt_errstr(status));
2476 init_lsa_String(&r.in.name, "zzzzzzzz");
2478 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
2479 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2480 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
2481 levels[i], nt_errstr(status));
2489 static BOOL test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2490 struct policy_handle *handle)
2493 struct samr_QueryDisplayInfo r;
2495 uint16_t levels[] = {1, 2, 3, 4, 5};
2498 for (i=0;i<ARRAY_SIZE(levels);i++) {
2499 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
2501 r.in.domain_handle = handle;
2502 r.in.level = levels[i];
2504 r.in.max_entries = 1000;
2505 r.in.buf_size = (uint32_t)-1;
2507 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
2508 if (!NT_STATUS_IS_OK(status)) {
2509 printf("QueryDisplayInfo level %u failed - %s\n",
2510 levels[i], nt_errstr(status));
2518 static BOOL test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2519 struct policy_handle *handle)
2522 struct samr_QueryDisplayInfo2 r;
2524 uint16_t levels[] = {1, 2, 3, 4, 5};
2527 for (i=0;i<ARRAY_SIZE(levels);i++) {
2528 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
2530 r.in.domain_handle = handle;
2531 r.in.level = levels[i];
2533 r.in.max_entries = 1000;
2534 r.in.buf_size = (uint32_t)-1;
2536 status = dcerpc_samr_QueryDisplayInfo2(p, mem_ctx, &r);
2537 if (!NT_STATUS_IS_OK(status)) {
2538 printf("QueryDisplayInfo2 level %u failed - %s\n",
2539 levels[i], nt_errstr(status));
2547 static BOOL test_QueryDisplayInfo3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2548 struct policy_handle *handle)
2551 struct samr_QueryDisplayInfo3 r;
2553 uint16_t levels[] = {1, 2, 3, 4, 5};
2556 for (i=0;i<ARRAY_SIZE(levels);i++) {
2557 printf("Testing QueryDisplayInfo3 level %u\n", levels[i]);
2559 r.in.domain_handle = handle;
2560 r.in.level = levels[i];
2562 r.in.max_entries = 1000;
2563 r.in.buf_size = (uint32_t)-1;
2565 status = dcerpc_samr_QueryDisplayInfo3(p, mem_ctx, &r);
2566 if (!NT_STATUS_IS_OK(status)) {
2567 printf("QueryDisplayInfo3 level %u failed - %s\n",
2568 levels[i], nt_errstr(status));
2577 static BOOL test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2578 struct policy_handle *handle)
2581 struct samr_QueryDisplayInfo r;
2584 printf("Testing QueryDisplayInfo continuation\n");
2586 r.in.domain_handle = handle;
2589 r.in.max_entries = 1;
2590 r.in.buf_size = (uint32_t)-1;
2593 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
2594 if (NT_STATUS_IS_OK(status) && r.out.returned_size != 0) {
2595 if (r.out.info.info1.entries[0].idx != r.in.start_idx + 1) {
2596 printf("failed: expected idx %d but got %d\n",
2598 r.out.info.info1.entries[0].idx);
2603 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
2604 !NT_STATUS_IS_OK(status)) {
2605 printf("QueryDisplayInfo level %u failed - %s\n",
2606 r.in.level, nt_errstr(status));
2611 } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
2612 NT_STATUS_IS_OK(status)) &&
2613 r.out.returned_size != 0);
2618 static BOOL test_QueryDomainInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2619 struct policy_handle *handle)
2622 struct samr_QueryDomainInfo r;
2623 struct samr_SetDomainInfo s;
2624 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
2625 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
2629 for (i=0;i<ARRAY_SIZE(levels);i++) {
2630 printf("Testing QueryDomainInfo level %u\n", levels[i]);
2632 r.in.domain_handle = handle;
2633 r.in.level = levels[i];
2635 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2636 if (!NT_STATUS_IS_OK(status)) {
2637 printf("QueryDomainInfo level %u failed - %s\n",
2638 r.in.level, nt_errstr(status));
2643 printf("Testing SetDomainInfo level %u\n", levels[i]);
2645 s.in.domain_handle = handle;
2646 s.in.level = levels[i];
2647 s.in.info = r.out.info;
2649 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2651 if (!NT_STATUS_IS_OK(status)) {
2652 printf("SetDomainInfo level %u failed - %s\n",
2653 r.in.level, nt_errstr(status));
2658 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
2659 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
2660 r.in.level, nt_errstr(status));
2666 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2667 if (!NT_STATUS_IS_OK(status)) {
2668 printf("QueryDomainInfo level %u failed - %s\n",
2669 r.in.level, nt_errstr(status));
2679 static BOOL test_QueryDomainInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2680 struct policy_handle *handle)
2683 struct samr_QueryDomainInfo2 r;
2684 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
2688 for (i=0;i<ARRAY_SIZE(levels);i++) {
2689 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
2691 r.in.domain_handle = handle;
2692 r.in.level = levels[i];
2694 status = dcerpc_samr_QueryDomainInfo2(p, mem_ctx, &r);
2695 if (!NT_STATUS_IS_OK(status)) {
2696 printf("QueryDomainInfo2 level %u failed - %s\n",
2697 r.in.level, nt_errstr(status));
2706 /* Test whether querydispinfo level 5 and enumdomgroups return the same
2707 set of group names. */
2708 static BOOL test_GroupList(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2709 struct policy_handle *handle)
2711 struct samr_EnumDomainGroups q1;
2712 struct samr_QueryDisplayInfo q2;
2714 uint32_t resume_handle=0;
2719 const char **names = NULL;
2721 printf("Testing coherency of querydispinfo vs enumdomgroups\n");
2723 q1.in.domain_handle = handle;
2724 q1.in.resume_handle = &resume_handle;
2726 q1.out.resume_handle = &resume_handle;
2728 status = STATUS_MORE_ENTRIES;
2729 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
2730 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &q1);
2732 if (!NT_STATUS_IS_OK(status) &&
2733 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
2736 for (i=0; i<q1.out.num_entries; i++) {
2737 add_string_to_array(mem_ctx,
2738 q1.out.sam->entries[i].name.string,
2739 &names, &num_names);
2743 if (!NT_STATUS_IS_OK(status)) {
2744 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
2752 q2.in.domain_handle = handle;
2754 q2.in.start_idx = 0;
2755 q2.in.max_entries = 5;
2756 q2.in.buf_size = (uint32_t)-1;
2758 status = STATUS_MORE_ENTRIES;
2759 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
2760 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &q2);
2762 if (!NT_STATUS_IS_OK(status) &&
2763 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
2766 for (i=0; i<q2.out.info.info5.count; i++) {
2768 const char *name = q2.out.info.info5.entries[i].account_name.string;
2770 for (j=0; j<num_names; j++) {
2771 if (names[j] == NULL)
2773 /* Hmm. No strequal in samba4 */
2774 if (strequal(names[j], name)) {
2782 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
2787 q2.in.start_idx += q2.out.info.info5.count;
2790 if (!NT_STATUS_IS_OK(status)) {
2791 printf("QueryDisplayInfo level 5 failed - %s\n",
2796 for (i=0; i<num_names; i++) {
2797 if (names[i] != NULL) {
2798 printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
2807 static BOOL test_DeleteDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2808 struct policy_handle *group_handle)
2810 struct samr_DeleteDomainGroup d;
2814 printf("Testing DeleteDomainGroup\n");
2816 d.in.group_handle = group_handle;
2817 d.out.group_handle = group_handle;
2819 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
2820 if (!NT_STATUS_IS_OK(status)) {
2821 printf("DeleteDomainGroup failed - %s\n", nt_errstr(status));
2828 static BOOL test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2829 struct policy_handle *domain_handle)
2831 struct samr_TestPrivateFunctionsDomain r;
2835 printf("Testing TestPrivateFunctionsDomain\n");
2837 r.in.domain_handle = domain_handle;
2839 status = dcerpc_samr_TestPrivateFunctionsDomain(p, mem_ctx, &r);
2840 if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
2841 printf("TestPrivateFunctionsDomain failed - %s\n", nt_errstr(status));
2848 static BOOL test_RidToSid(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2849 struct dom_sid *domain_sid,
2850 struct policy_handle *domain_handle)
2852 struct samr_RidToSid r;
2855 struct dom_sid *calc_sid;
2856 int rids[] = { 0, 42, 512, 10200 };
2859 for (i=0;i<ARRAY_SIZE(rids);i++) {
2861 printf("Testing RidToSid\n");
2863 calc_sid = dom_sid_dup(mem_ctx, domain_sid);
2864 r.in.domain_handle = domain_handle;
2867 status = dcerpc_samr_RidToSid(p, mem_ctx, &r);
2868 if (!NT_STATUS_IS_OK(status)) {
2869 printf("RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
2872 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
2874 if (!dom_sid_equal(calc_sid, r.out.sid)) {
2875 printf("RidToSid for %d failed - got %s, expected %s\n", rids[i],
2876 dom_sid_string(mem_ctx, r.out.sid),
2877 dom_sid_string(mem_ctx, calc_sid));
2886 static BOOL test_GetBootKeyInformation(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2887 struct policy_handle *domain_handle)
2889 struct samr_GetBootKeyInformation r;
2893 printf("Testing GetBootKeyInformation\n");
2895 r.in.domain_handle = domain_handle;
2897 status = dcerpc_samr_GetBootKeyInformation(p, mem_ctx, &r);
2898 if (!NT_STATUS_IS_OK(status)) {
2899 /* w2k3 seems to fail this sometimes and pass it sometimes */
2900 printf("GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
2906 static BOOL test_AddGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2907 struct policy_handle *domain_handle,
2908 struct policy_handle *group_handle)
2911 struct samr_AddGroupMember r;
2912 struct samr_DeleteGroupMember d;
2913 struct samr_QueryGroupMember q;
2914 struct samr_SetMemberAttributesOfGroup s;
2918 status = test_LookupName(p, mem_ctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
2919 if (!NT_STATUS_IS_OK(status)) {
2923 r.in.group_handle = group_handle;
2925 r.in.flags = 0; /* ??? */
2927 printf("Testing AddGroupMember and DeleteGroupMember\n");
2929 d.in.group_handle = group_handle;
2932 status = dcerpc_samr_DeleteGroupMember(p, mem_ctx, &d);
2933 if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_NOT_IN_GROUP, status)) {
2934 printf("DeleteGroupMember gave %s - should be NT_STATUS_MEMBER_NOT_IN_GROUP\n",
2939 status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
2940 if (!NT_STATUS_IS_OK(status)) {
2941 printf("AddGroupMember failed - %s\n", nt_errstr(status));
2945 status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
2946 if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_IN_GROUP, status)) {
2947 printf("AddGroupMember gave %s - should be NT_STATUS_MEMBER_IN_GROUP\n",
2952 /* this one is quite strange. I am using random inputs in the
2953 hope of triggering an error that might give us a clue */
2954 s.in.group_handle = group_handle;
2955 s.in.unknown1 = random();
2956 s.in.unknown2 = random();
2958 status = dcerpc_samr_SetMemberAttributesOfGroup(p, mem_ctx, &s);
2959 if (!NT_STATUS_IS_OK(status)) {
2960 printf("SetMemberAttributesOfGroup failed - %s\n", nt_errstr(status));
2964 q.in.group_handle = group_handle;
2966 status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &q);
2967 if (!NT_STATUS_IS_OK(status)) {
2968 printf("QueryGroupMember failed - %s\n", nt_errstr(status));
2972 status = dcerpc_samr_DeleteGroupMember(p, mem_ctx, &d);
2973 if (!NT_STATUS_IS_OK(status)) {
2974 printf("DeleteGroupMember failed - %s\n", nt_errstr(status));
2978 status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
2979 if (!NT_STATUS_IS_OK(status)) {
2980 printf("AddGroupMember failed - %s\n", nt_errstr(status));
2988 static BOOL test_CreateDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2989 struct policy_handle *domain_handle, struct policy_handle *group_handle)
2992 struct samr_CreateDomainGroup r;
2994 struct lsa_String name;
2997 init_lsa_String(&name, TEST_GROUPNAME);
2999 r.in.domain_handle = domain_handle;
3001 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3002 r.out.group_handle = group_handle;
3005 printf("Testing CreateDomainGroup(%s)\n", r.in.name->string);
3007 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
3009 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
3010 printf("Server refused create of '%s'\n", r.in.name->string);
3011 ZERO_STRUCTP(group_handle);
3015 if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS) ||
3016 NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
3017 if (!test_DeleteGroup_byname(p, mem_ctx, domain_handle, r.in.name->string)) {
3020 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
3022 if (!NT_STATUS_IS_OK(status)) {
3023 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
3027 if (!test_AddGroupMember(p, mem_ctx, domain_handle, group_handle)) {
3031 if (!test_SetGroupInfo(p, mem_ctx, group_handle)) {
3040 its not totally clear what this does. It seems to accept any sid you like.
3042 static BOOL test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p,
3043 TALLOC_CTX *mem_ctx,
3044 struct policy_handle *domain_handle)
3047 struct samr_RemoveMemberFromForeignDomain r;
3049 r.in.domain_handle = domain_handle;
3050 r.in.sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-12-34-56-78");
3052 status = dcerpc_samr_RemoveMemberFromForeignDomain(p, mem_ctx, &r);
3053 if (!NT_STATUS_IS_OK(status)) {
3054 printf("RemoveMemberFromForeignDomain failed - %s\n", nt_errstr(status));
3063 static BOOL test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3064 struct policy_handle *handle);
3066 static BOOL test_OpenDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3067 struct policy_handle *handle, struct dom_sid *sid)
3070 struct samr_OpenDomain r;
3071 struct policy_handle domain_handle;
3072 struct policy_handle user_handle;
3073 struct policy_handle alias_handle;
3074 struct policy_handle group_handle;
3077 ZERO_STRUCT(user_handle);
3078 ZERO_STRUCT(alias_handle);
3079 ZERO_STRUCT(group_handle);
3080 ZERO_STRUCT(domain_handle);
3082 printf("Testing OpenDomain\n");
3084 r.in.connect_handle = handle;
3085 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3087 r.out.domain_handle = &domain_handle;
3089 status = dcerpc_samr_OpenDomain(p, mem_ctx, &r);
3090 if (!NT_STATUS_IS_OK(status)) {
3091 printf("OpenDomain failed - %s\n", nt_errstr(status));
3095 /* run the domain tests with the main handle closed - this tests
3096 the servers reference counting */
3097 ret &= test_samr_handle_Close(p, mem_ctx, handle);
3099 ret &= test_QuerySecurity(p, mem_ctx, &domain_handle);
3100 ret &= test_RemoveMemberFromForeignDomain(p, mem_ctx, &domain_handle);
3101 ret &= test_CreateUser2(p, mem_ctx, &domain_handle);
3102 ret &= test_CreateUser(p, mem_ctx, &domain_handle, &user_handle);
3103 ret &= test_CreateAlias(p, mem_ctx, &domain_handle, &alias_handle, sid);
3104 ret &= test_CreateDomainGroup(p, mem_ctx, &domain_handle, &group_handle);
3105 ret &= test_QueryDomainInfo(p, mem_ctx, &domain_handle);
3106 ret &= test_QueryDomainInfo2(p, mem_ctx, &domain_handle);
3107 ret &= test_EnumDomainUsers(p, mem_ctx, &domain_handle);
3108 ret &= test_EnumDomainUsers_async(p, mem_ctx, &domain_handle);
3109 ret &= test_EnumDomainGroups(p, mem_ctx, &domain_handle);
3110 ret &= test_EnumDomainAliases(p, mem_ctx, &domain_handle);
3111 ret &= test_QueryDisplayInfo(p, mem_ctx, &domain_handle);
3112 ret &= test_QueryDisplayInfo2(p, mem_ctx, &domain_handle);
3113 ret &= test_QueryDisplayInfo3(p, mem_ctx, &domain_handle);
3114 ret &= test_QueryDisplayInfo_continue(p, mem_ctx, &domain_handle);
3115 ret &= test_GetDisplayEnumerationIndex(p, mem_ctx, &domain_handle);
3116 ret &= test_GetDisplayEnumerationIndex2(p, mem_ctx, &domain_handle);
3117 ret &= test_GroupList(p, mem_ctx, &domain_handle);
3118 ret &= test_TestPrivateFunctionsDomain(p, mem_ctx, &domain_handle);
3119 ret &= test_RidToSid(p, mem_ctx, sid, &domain_handle);
3120 ret &= test_GetBootKeyInformation(p, mem_ctx, &domain_handle);
3122 if (!policy_handle_empty(&user_handle) &&
3123 !test_DeleteUser(p, mem_ctx, &user_handle)) {
3127 if (!policy_handle_empty(&alias_handle) &&
3128 !test_DeleteAlias(p, mem_ctx, &alias_handle)) {
3132 if (!policy_handle_empty(&group_handle) &&
3133 !test_DeleteDomainGroup(p, mem_ctx, &group_handle)) {
3137 ret &= test_samr_handle_Close(p, mem_ctx, &domain_handle);
3139 /* reconnect the main handle */
3140 ret &= test_Connect(p, mem_ctx, handle);
3145 static BOOL test_LookupDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3146 struct policy_handle *handle, struct lsa_String *domain)
3149 struct samr_LookupDomain r;
3150 struct lsa_String n2;
3153 printf("Testing LookupDomain(%s)\n", domain->string);
3155 /* check for correct error codes */
3156 r.in.connect_handle = handle;
3157 r.in.domain_name = &n2;
3160 status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
3161 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_PARAMETER, status)) {
3162 printf("failed: LookupDomain expected NT_STATUS_INVALID_PARAMETER - %s\n", nt_errstr(status));
3166 n2.string = "xxNODOMAINxx";
3168 status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
3169 if (!NT_STATUS_EQUAL(NT_STATUS_NO_SUCH_DOMAIN, status)) {
3170 printf("failed: LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN - %s\n", nt_errstr(status));
3174 r.in.connect_handle = handle;
3175 r.in.domain_name = domain;
3177 status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
3178 if (!NT_STATUS_IS_OK(status)) {
3179 printf("LookupDomain failed - %s\n", nt_errstr(status));
3183 if (!test_GetDomPwInfo(p, mem_ctx, domain)) {
3187 if (!test_OpenDomain(p, mem_ctx, handle, r.out.sid)) {
3195 static BOOL test_EnumDomains(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3196 struct policy_handle *handle)
3199 struct samr_EnumDomains r;
3200 uint32_t resume_handle = 0;
3204 r.in.connect_handle = handle;
3205 r.in.resume_handle = &resume_handle;
3206 r.in.buf_size = (uint32_t)-1;
3207 r.out.resume_handle = &resume_handle;
3209 status = dcerpc_samr_EnumDomains(p, mem_ctx, &r);
3210 if (!NT_STATUS_IS_OK(status)) {
3211 printf("EnumDomains failed - %s\n", nt_errstr(status));
3219 for (i=0;i<r.out.sam->count;i++) {
3220 if (!test_LookupDomain(p, mem_ctx, handle,
3221 &r.out.sam->entries[i].name)) {
3226 status = dcerpc_samr_EnumDomains(p, mem_ctx, &r);
3227 if (!NT_STATUS_IS_OK(status)) {
3228 printf("EnumDomains failed - %s\n", nt_errstr(status));
3236 static BOOL test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3237 struct policy_handle *handle)
3240 struct samr_Connect r;
3241 struct samr_Connect2 r2;
3242 struct samr_Connect3 r3;
3243 struct samr_Connect4 r4;
3244 struct samr_Connect5 r5;
3245 union samr_ConnectInfo info;
3246 struct policy_handle h;
3247 BOOL ret = True, got_handle = False;
3249 printf("testing samr_Connect\n");
3251 r.in.system_name = 0;
3252 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3253 r.out.connect_handle = &h;
3255 status = dcerpc_samr_Connect(p, mem_ctx, &r);
3256 if (!NT_STATUS_IS_OK(status)) {
3257 printf("Connect failed - %s\n", nt_errstr(status));
3264 printf("testing samr_Connect2\n");
3266 r2.in.system_name = NULL;
3267 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3268 r2.out.connect_handle = &h;
3270 status = dcerpc_samr_Connect2(p, mem_ctx, &r2);
3271 if (!NT_STATUS_IS_OK(status)) {
3272 printf("Connect2 failed - %s\n", nt_errstr(status));
3276 test_samr_handle_Close(p, mem_ctx, handle);
3282 printf("testing samr_Connect3\n");
3284 r3.in.system_name = NULL;
3286 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3287 r3.out.connect_handle = &h;
3289 status = dcerpc_samr_Connect3(p, mem_ctx, &r3);
3290 if (!NT_STATUS_IS_OK(status)) {
3291 printf("Connect3 failed - %s\n", nt_errstr(status));
3295 test_samr_handle_Close(p, mem_ctx, handle);
3301 printf("testing samr_Connect4\n");
3303 r4.in.system_name = "";
3305 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3306 r4.out.connect_handle = &h;
3308 status = dcerpc_samr_Connect4(p, mem_ctx, &r4);
3309 if (!NT_STATUS_IS_OK(status)) {
3310 printf("Connect4 failed - %s\n", nt_errstr(status));
3314 test_samr_handle_Close(p, mem_ctx, handle);
3320 printf("testing samr_Connect5\n");
3322 info.info1.unknown1 = 0;
3323 info.info1.unknown2 = 0;
3325 r5.in.system_name = "";
3326 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3329 r5.out.info = &info;
3330 r5.out.connect_handle = &h;
3332 status = dcerpc_samr_Connect5(p, mem_ctx, &r5);
3333 if (!NT_STATUS_IS_OK(status)) {
3334 printf("Connect5 failed - %s\n", nt_errstr(status));
3338 test_samr_handle_Close(p, mem_ctx, handle);
3348 BOOL torture_rpc_samr(void)
3351 struct dcerpc_pipe *p;
3352 TALLOC_CTX *mem_ctx;
3354 struct policy_handle handle;
3356 mem_ctx = talloc_init("torture_rpc_samr");
3358 status = torture_rpc_connection(mem_ctx, &p, &dcerpc_table_samr);
3359 if (!NT_STATUS_IS_OK(status)) {
3360 talloc_free(mem_ctx);
3364 if (!test_Connect(p, mem_ctx, &handle)) {
3368 if (!test_QuerySecurity(p, mem_ctx, &handle)) {
3372 if (!test_EnumDomains(p, mem_ctx, &handle)) {
3376 if (!test_SetDsrmPassword(p, mem_ctx, &handle)) {
3380 if (!test_Shutdown(p, mem_ctx, &handle)) {
3384 if (!test_samr_handle_Close(p, mem_ctx, &handle)) {
3388 talloc_free(mem_ctx);