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 "librpc/gen_ndr/ndr_lsa.h"
25 #include "librpc/gen_ndr/ndr_samr.h"
26 #include "lib/crypto/crypto.h"
28 #define TEST_ACCOUNT_NAME "samrtorturetest"
29 #define TEST_ALIASNAME "samrtorturetestalias"
30 #define TEST_GROUPNAME "samrtorturetestgroup"
31 #define TEST_MACHINENAME "samrtestmach$"
32 #define TEST_DOMAINNAME "samrtestdom$"
35 static BOOL test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
36 struct policy_handle *handle);
38 static BOOL test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
39 struct policy_handle *handle);
41 static BOOL test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
42 struct policy_handle *handle);
44 static void init_lsa_String(struct lsa_String *string, const char *s)
49 BOOL test_samr_handle_Close(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
50 struct policy_handle *handle)
56 r.out.handle = handle;
58 status = dcerpc_samr_Close(p, mem_ctx, &r);
59 if (!NT_STATUS_IS_OK(status)) {
60 printf("Close handle failed - %s\n", nt_errstr(status));
67 static BOOL test_Shutdown(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
68 struct policy_handle *handle)
71 struct samr_Shutdown r;
73 if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
74 printf("samr_Shutdown disabled - enable dangerous tests to use\n");
78 r.in.connect_handle = handle;
80 printf("testing samr_Shutdown\n");
82 status = dcerpc_samr_Shutdown(p, mem_ctx, &r);
83 if (!NT_STATUS_IS_OK(status)) {
84 printf("samr_Shutdown failed - %s\n", nt_errstr(status));
91 static BOOL test_SetDsrmPassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
92 struct policy_handle *handle)
95 struct samr_SetDsrmPassword r;
96 struct lsa_String string;
97 struct samr_Password hash;
99 if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
100 printf("samr_SetDsrmPassword disabled - enable dangerous tests to use\n");
104 E_md4hash("TeSTDSRM123", hash.hash);
106 init_lsa_String(&string, "Administrator");
112 printf("testing samr_SetDsrmPassword\n");
114 status = dcerpc_samr_SetDsrmPassword(p, mem_ctx, &r);
115 if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
116 printf("samr_SetDsrmPassword failed - %s\n", nt_errstr(status));
124 static BOOL test_QuerySecurity(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
125 struct policy_handle *handle)
128 struct samr_QuerySecurity r;
129 struct samr_SetSecurity s;
131 r.in.handle = handle;
134 status = dcerpc_samr_QuerySecurity(p, mem_ctx, &r);
135 if (!NT_STATUS_IS_OK(status)) {
136 printf("QuerySecurity failed - %s\n", nt_errstr(status));
140 if (r.out.sdbuf == NULL) {
144 s.in.handle = handle;
146 s.in.sdbuf = r.out.sdbuf;
148 status = dcerpc_samr_SetSecurity(p, mem_ctx, &s);
149 if (!NT_STATUS_IS_OK(status)) {
150 printf("SetSecurity failed - %s\n", nt_errstr(status));
154 status = dcerpc_samr_QuerySecurity(p, mem_ctx, &r);
155 if (!NT_STATUS_IS_OK(status)) {
156 printf("QuerySecurity failed - %s\n", nt_errstr(status));
164 static BOOL test_SetUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
165 struct policy_handle *handle, uint32_t base_acct_flags,
166 const char *base_account_name)
169 struct samr_SetUserInfo s;
170 struct samr_SetUserInfo2 s2;
171 struct samr_QueryUserInfo q;
172 struct samr_QueryUserInfo q0;
173 union samr_UserInfo u;
175 const char *test_account_name;
177 uint32_t user_extra_flags = 0;
178 if (base_acct_flags == ACB_NORMAL) {
179 /* Don't know what this is, but it is always here for users - you can't get rid of it */
180 user_extra_flags = 0x20000;
183 s.in.user_handle = handle;
186 s2.in.user_handle = handle;
189 q.in.user_handle = handle;
193 #define TESTCALL(call, r) \
194 status = dcerpc_samr_ ##call(p, mem_ctx, &r); \
195 if (!NT_STATUS_IS_OK(status)) { \
196 printf(#call " level %u failed - %s (%s)\n", \
197 r.in.level, nt_errstr(status), __location__); \
202 #define STRING_EQUAL(s1, s2, field) \
203 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
204 printf("Failed to set %s to '%s' (%s)\n", \
205 #field, s2, __location__); \
210 #define INT_EQUAL(i1, i2, field) \
212 printf("Failed to set %s to 0x%x - got 0x%x (%s)\n", \
213 #field, i2, i1, __location__); \
218 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
219 printf("field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
221 TESTCALL(QueryUserInfo, q) \
223 s2.in.level = lvl1; \
226 ZERO_STRUCT(u.info21); \
227 u.info21.fields_present = fpval; \
229 init_lsa_String(&u.info ## lvl1.field1, value); \
230 TESTCALL(SetUserInfo, s) \
231 TESTCALL(SetUserInfo2, s2) \
232 init_lsa_String(&u.info ## lvl1.field1, ""); \
233 TESTCALL(QueryUserInfo, q); \
235 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
237 TESTCALL(QueryUserInfo, q) \
239 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
242 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
243 printf("field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
245 TESTCALL(QueryUserInfo, q) \
247 s2.in.level = lvl1; \
250 uint8_t *bits = u.info21.logon_hours.bits; \
251 ZERO_STRUCT(u.info21); \
252 if (fpval == SAMR_FIELD_LOGON_HOURS) { \
253 u.info21.logon_hours.units_per_week = 168; \
254 u.info21.logon_hours.bits = bits; \
256 u.info21.fields_present = fpval; \
258 u.info ## lvl1.field1 = value; \
259 TESTCALL(SetUserInfo, s) \
260 TESTCALL(SetUserInfo2, s2) \
261 u.info ## lvl1.field1 = 0; \
262 TESTCALL(QueryUserInfo, q); \
264 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
266 TESTCALL(QueryUserInfo, q) \
268 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
271 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
272 TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
276 do { TESTCALL(QueryUserInfo, q0) } while (0);
278 TEST_USERINFO_STRING(2, comment, 1, comment, "xx2-1 comment", 0);
279 TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
280 TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment",
283 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-1", base_account_name);
284 TEST_USERINFO_STRING(7, account_name, 1, account_name, base_account_name, 0);
285 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-3", base_account_name);
286 TEST_USERINFO_STRING(7, account_name, 3, account_name, base_account_name, 0);
287 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-5", base_account_name);
288 TEST_USERINFO_STRING(7, account_name, 5, account_name, base_account_name, 0);
289 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-6", base_account_name);
290 TEST_USERINFO_STRING(7, account_name, 6, account_name, base_account_name, 0);
291 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-7", base_account_name);
292 TEST_USERINFO_STRING(7, account_name, 7, account_name, base_account_name, 0);
293 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-21", base_account_name);
294 TEST_USERINFO_STRING(7, account_name, 21, account_name, base_account_name, 0);
295 test_account_name = base_account_name;
296 TEST_USERINFO_STRING(21, account_name, 21, account_name, base_account_name,
297 SAMR_FIELD_ACCOUNT_NAME);
299 TEST_USERINFO_STRING(6, full_name, 1, full_name, "xx6-1 full_name", 0);
300 TEST_USERINFO_STRING(6, full_name, 3, full_name, "xx6-3 full_name", 0);
301 TEST_USERINFO_STRING(6, full_name, 5, full_name, "xx6-5 full_name", 0);
302 TEST_USERINFO_STRING(6, full_name, 6, full_name, "xx6-6 full_name", 0);
303 TEST_USERINFO_STRING(6, full_name, 8, full_name, "xx6-8 full_name", 0);
304 TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
305 TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
306 TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name",
307 SAMR_FIELD_FULL_NAME);
309 TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
310 TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
311 TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
312 TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script",
313 SAMR_FIELD_LOGON_SCRIPT);
315 TEST_USERINFO_STRING(12, profile_path, 3, profile_path, "xx12-3 profile_path", 0);
316 TEST_USERINFO_STRING(12, profile_path, 5, profile_path, "xx12-5 profile_path", 0);
317 TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
318 TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path",
319 SAMR_FIELD_PROFILE_PATH);
321 TEST_USERINFO_STRING(13, description, 1, description, "xx13-1 description", 0);
322 TEST_USERINFO_STRING(13, description, 5, description, "xx13-5 description", 0);
323 TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
324 TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description",
325 SAMR_FIELD_DESCRIPTION);
327 TEST_USERINFO_STRING(14, workstations, 3, workstations, "14workstation3", 0);
328 TEST_USERINFO_STRING(14, workstations, 5, workstations, "14workstation4", 0);
329 TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
330 TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21",
331 SAMR_FIELD_WORKSTATIONS);
333 TEST_USERINFO_STRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
334 TEST_USERINFO_STRING(21, parameters, 21, parameters, "xx21-21 parameters",
335 SAMR_FIELD_PARAMETERS);
337 TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
338 TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__,
339 SAMR_FIELD_COUNTRY_CODE);
341 TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
342 TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__,
343 SAMR_FIELD_CODE_PAGE);
345 TEST_USERINFO_INT(4, logon_hours.bits[3], 3, logon_hours.bits[3], 1, 0);
346 TEST_USERINFO_INT(4, logon_hours.bits[3], 5, logon_hours.bits[3], 2, 0);
347 TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
348 TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4,
349 SAMR_FIELD_LOGON_HOURS);
351 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
352 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
353 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
355 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
356 (base_acct_flags | ACB_DISABLED),
357 (base_acct_flags | ACB_DISABLED | user_extra_flags),
360 /* Setting PWNOEXP clears the magic 0x20000 flag */
361 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
362 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
363 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
365 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
366 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
367 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
370 /* The 'autolock' flag doesn't stick - check this */
371 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
372 (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK),
373 (base_acct_flags | ACB_DISABLED | user_extra_flags),
375 TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags,
376 (base_acct_flags | ACB_DISABLED),
377 (base_acct_flags | ACB_DISABLED | user_extra_flags),
378 SAMR_FIELD_ACCT_FLAGS);
381 /* these fail with win2003 - it appears you can't set the primary gid?
382 the set succeeds, but the gid isn't changed. Very weird! */
383 TEST_USERINFO_INT(9, primary_gid, 1, primary_gid, 513);
384 TEST_USERINFO_INT(9, primary_gid, 3, primary_gid, 513);
385 TEST_USERINFO_INT(9, primary_gid, 5, primary_gid, 513);
386 TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
393 generate a random password for password change tests
395 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
397 size_t len = MAX(8, min_len) + (random() % 6);
398 char *s = generate_random_str(mem_ctx, len);
399 printf("Generated password '%s'\n", s);
403 static BOOL test_SetUserPass(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
404 struct policy_handle *handle, char **password)
407 struct samr_SetUserInfo s;
408 union samr_UserInfo u;
410 DATA_BLOB session_key;
412 struct samr_GetUserPwInfo pwp;
413 int policy_min_pw_len = 0;
414 pwp.in.user_handle = handle;
416 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
417 if (NT_STATUS_IS_OK(status)) {
418 policy_min_pw_len = pwp.out.info.min_password_length;
420 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
422 s.in.user_handle = handle;
426 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
427 /* w2k3 ignores this length */
428 u.info24.pw_len = strlen_m(newpass) * 2;
430 status = dcerpc_fetch_session_key(p, &session_key);
431 if (!NT_STATUS_IS_OK(status)) {
432 printf("SetUserInfo level %u - no session key - %s\n",
433 s.in.level, nt_errstr(status));
437 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
439 printf("Testing SetUserInfo level 24 (set password)\n");
441 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
442 if (!NT_STATUS_IS_OK(status)) {
443 printf("SetUserInfo level %u failed - %s\n",
444 s.in.level, nt_errstr(status));
454 static BOOL test_SetUserPass_23(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
455 struct policy_handle *handle, uint32_t fields_present,
459 struct samr_SetUserInfo s;
460 union samr_UserInfo u;
462 DATA_BLOB session_key;
464 struct samr_GetUserPwInfo pwp;
465 int policy_min_pw_len = 0;
466 pwp.in.user_handle = handle;
468 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
469 if (NT_STATUS_IS_OK(status)) {
470 policy_min_pw_len = pwp.out.info.min_password_length;
472 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
474 s.in.user_handle = handle;
480 u.info23.info.fields_present = fields_present;
482 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
484 status = dcerpc_fetch_session_key(p, &session_key);
485 if (!NT_STATUS_IS_OK(status)) {
486 printf("SetUserInfo level %u - no session key - %s\n",
487 s.in.level, nt_errstr(status));
491 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
493 printf("Testing SetUserInfo level 23 (set password)\n");
495 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
496 if (!NT_STATUS_IS_OK(status)) {
497 printf("SetUserInfo level %u failed - %s\n",
498 s.in.level, nt_errstr(status));
508 static BOOL test_SetUserPassEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
509 struct policy_handle *handle, char **password)
512 struct samr_SetUserInfo s;
513 union samr_UserInfo u;
515 DATA_BLOB session_key;
516 DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
517 uint8_t confounder[16];
519 struct MD5Context ctx;
520 struct samr_GetUserPwInfo pwp;
521 int policy_min_pw_len = 0;
522 pwp.in.user_handle = handle;
524 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
525 if (NT_STATUS_IS_OK(status)) {
526 policy_min_pw_len = pwp.out.info.min_password_length;
528 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
530 s.in.user_handle = handle;
534 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
535 u.info26.pw_len = strlen(newpass);
537 status = dcerpc_fetch_session_key(p, &session_key);
538 if (!NT_STATUS_IS_OK(status)) {
539 printf("SetUserInfo level %u - no session key - %s\n",
540 s.in.level, nt_errstr(status));
544 generate_random_buffer((uint8_t *)confounder, 16);
547 MD5Update(&ctx, confounder, 16);
548 MD5Update(&ctx, session_key.data, session_key.length);
549 MD5Final(confounded_session_key.data, &ctx);
551 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
552 memcpy(&u.info26.password.data[516], confounder, 16);
554 printf("Testing SetUserInfo level 26 (set password ex)\n");
556 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
557 if (!NT_STATUS_IS_OK(status)) {
558 printf("SetUserInfo level %u failed - %s\n",
559 s.in.level, nt_errstr(status));
568 static BOOL test_SetUserPass_25(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
569 struct policy_handle *handle, uint32_t fields_present,
573 struct samr_SetUserInfo s;
574 union samr_UserInfo u;
576 DATA_BLOB session_key;
577 DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
578 struct MD5Context ctx;
579 uint8_t confounder[16];
581 struct samr_GetUserPwInfo pwp;
582 int policy_min_pw_len = 0;
583 pwp.in.user_handle = handle;
585 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
586 if (NT_STATUS_IS_OK(status)) {
587 policy_min_pw_len = pwp.out.info.min_password_length;
589 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
591 s.in.user_handle = handle;
597 u.info25.info.fields_present = fields_present;
599 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
601 status = dcerpc_fetch_session_key(p, &session_key);
602 if (!NT_STATUS_IS_OK(status)) {
603 printf("SetUserInfo level %u - no session key - %s\n",
604 s.in.level, nt_errstr(status));
608 generate_random_buffer((uint8_t *)confounder, 16);
611 MD5Update(&ctx, confounder, 16);
612 MD5Update(&ctx, session_key.data, session_key.length);
613 MD5Final(confounded_session_key.data, &ctx);
615 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
616 memcpy(&u.info25.password.data[516], confounder, 16);
618 printf("Testing SetUserInfo level 25 (set password ex)\n");
620 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
621 if (!NT_STATUS_IS_OK(status)) {
622 printf("SetUserInfo level %u failed - %s\n",
623 s.in.level, nt_errstr(status));
632 static BOOL test_SetAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
633 struct policy_handle *handle)
636 struct samr_SetAliasInfo r;
637 struct samr_QueryAliasInfo q;
638 uint16_t levels[] = {2, 3};
642 /* Ignoring switch level 1, as that includes the number of members for the alias
643 * and setting this to a wrong value might have negative consequences
646 for (i=0;i<ARRAY_SIZE(levels);i++) {
647 printf("Testing SetAliasInfo level %u\n", levels[i]);
649 r.in.alias_handle = handle;
650 r.in.level = levels[i];
651 r.in.info = talloc(mem_ctx, union samr_AliasInfo);
652 switch (r.in.level) {
653 case 2 : init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
654 case 3 : init_lsa_String(&r.in.info->description,
655 "Test Description, should test I18N as well"); break;
658 status = dcerpc_samr_SetAliasInfo(p, mem_ctx, &r);
659 if (!NT_STATUS_IS_OK(status)) {
660 printf("SetAliasInfo level %u failed - %s\n",
661 levels[i], nt_errstr(status));
665 q.in.alias_handle = handle;
666 q.in.level = levels[i];
668 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &q);
669 if (!NT_STATUS_IS_OK(status)) {
670 printf("QueryAliasInfo level %u failed - %s\n",
671 levels[i], nt_errstr(status));
679 static BOOL test_GetGroupsForUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
680 struct policy_handle *user_handle)
682 struct samr_GetGroupsForUser r;
686 printf("testing GetGroupsForUser\n");
688 r.in.user_handle = user_handle;
690 status = dcerpc_samr_GetGroupsForUser(p, mem_ctx, &r);
691 if (!NT_STATUS_IS_OK(status)) {
692 printf("GetGroupsForUser failed - %s\n",nt_errstr(status));
700 static BOOL test_GetDomPwInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
701 struct lsa_String *domain_name)
704 struct samr_GetDomPwInfo r;
707 r.in.domain_name = domain_name;
708 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
710 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
711 if (!NT_STATUS_IS_OK(status)) {
712 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
716 r.in.domain_name->string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
717 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
719 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
720 if (!NT_STATUS_IS_OK(status)) {
721 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
725 r.in.domain_name->string = "\\\\__NONAME__";
726 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
728 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
729 if (!NT_STATUS_IS_OK(status)) {
730 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
734 r.in.domain_name->string = "\\\\Builtin";
735 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
737 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
738 if (!NT_STATUS_IS_OK(status)) {
739 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
747 static BOOL test_GetUserPwInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
748 struct policy_handle *handle)
751 struct samr_GetUserPwInfo r;
754 printf("Testing GetUserPwInfo\n");
756 r.in.user_handle = handle;
758 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &r);
759 if (!NT_STATUS_IS_OK(status)) {
760 printf("GetUserPwInfo failed - %s\n", nt_errstr(status));
767 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
768 struct policy_handle *domain_handle, const char *name,
772 struct samr_LookupNames n;
773 struct lsa_String sname[2];
775 init_lsa_String(&sname[0], name);
777 n.in.domain_handle = domain_handle;
780 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
781 if (NT_STATUS_IS_OK(status)) {
782 *rid = n.out.rids.ids[0];
787 init_lsa_String(&sname[1], "xxNONAMExx");
789 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
790 if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
791 printf("LookupNames[2] failed - %s\n", nt_errstr(status));
795 init_lsa_String(&sname[1], "xxNONAMExx");
797 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
798 if (!NT_STATUS_IS_OK(status)) {
799 printf("LookupNames[0] failed - %s\n", nt_errstr(status));
805 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
806 struct policy_handle *domain_handle,
807 const char *name, struct policy_handle *user_handle)
810 struct samr_OpenUser r;
813 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
814 if (!NT_STATUS_IS_OK(status)) {
818 r.in.domain_handle = domain_handle;
819 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
821 r.out.user_handle = user_handle;
822 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
823 if (!NT_STATUS_IS_OK(status)) {
824 printf("OpenUser_byname(%s) failed - %s\n", name, nt_errstr(status));
831 static BOOL test_ChangePasswordNT3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
832 struct policy_handle *handle)
835 struct samr_ChangePasswordUser r;
837 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
838 struct policy_handle user_handle;
839 char *oldpass = "test";
840 char *newpass = "test2";
841 uint8_t old_nt_hash[16], new_nt_hash[16];
842 uint8_t old_lm_hash[16], new_lm_hash[16];
844 status = test_OpenUser_byname(p, mem_ctx, handle, "testuser", &user_handle);
845 if (!NT_STATUS_IS_OK(status)) {
849 printf("Testing ChangePasswordUser for user 'testuser'\n");
851 printf("old password: %s\n", oldpass);
852 printf("new password: %s\n", newpass);
854 E_md4hash(oldpass, old_nt_hash);
855 E_md4hash(newpass, new_nt_hash);
856 E_deshash(oldpass, old_lm_hash);
857 E_deshash(newpass, new_lm_hash);
859 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
860 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
861 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
862 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
863 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
864 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
866 r.in.handle = &user_handle;
868 r.in.old_lm_crypted = &hash1;
869 r.in.new_lm_crypted = &hash2;
871 r.in.old_nt_crypted = &hash3;
872 r.in.new_nt_crypted = &hash4;
873 r.in.cross1_present = 1;
874 r.in.nt_cross = &hash5;
875 r.in.cross2_present = 1;
876 r.in.lm_cross = &hash6;
878 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
879 if (!NT_STATUS_IS_OK(status)) {
880 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
884 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
892 static BOOL test_ChangePasswordUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
893 struct policy_handle *handle, char **password)
896 struct samr_ChangePasswordUser r;
898 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
899 struct policy_handle user_handle;
900 char *oldpass = *password;
901 uint8_t old_nt_hash[16], new_nt_hash[16];
902 uint8_t old_lm_hash[16], new_lm_hash[16];
905 struct samr_GetUserPwInfo pwp;
906 int policy_min_pw_len = 0;
908 status = test_OpenUser_byname(p, mem_ctx, handle, TEST_ACCOUNT_NAME, &user_handle);
909 if (!NT_STATUS_IS_OK(status)) {
912 pwp.in.user_handle = &user_handle;
914 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
915 if (NT_STATUS_IS_OK(status)) {
916 policy_min_pw_len = pwp.out.info.min_password_length;
918 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
920 printf("Testing ChangePasswordUser\n");
922 E_md4hash(oldpass, old_nt_hash);
923 E_md4hash(newpass, new_nt_hash);
924 E_deshash(oldpass, old_lm_hash);
925 E_deshash(newpass, new_lm_hash);
927 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
928 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
929 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
930 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
931 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
932 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
934 r.in.user_handle = &user_handle;
936 r.in.old_lm_crypted = &hash1;
937 r.in.new_lm_crypted = &hash2;
939 r.in.old_nt_crypted = &hash3;
940 r.in.new_nt_crypted = &hash4;
941 r.in.cross1_present = 1;
942 r.in.nt_cross = &hash5;
943 r.in.cross2_present = 1;
944 r.in.lm_cross = &hash6;
946 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
947 if (!NT_STATUS_IS_OK(status)) {
948 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
954 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
962 static BOOL test_OemChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
963 struct policy_handle *handle, char **password)
966 struct samr_OemChangePasswordUser2 r;
968 struct samr_Password lm_verifier;
969 struct samr_CryptPassword lm_pass;
970 struct samr_AsciiName server, account;
971 char *oldpass = *password;
973 uint8_t old_lm_hash[16], new_lm_hash[16];
975 struct samr_GetDomPwInfo dom_pw_info;
976 int policy_min_pw_len = 0;
978 struct lsa_String domain_name;
979 domain_name.string = "";
980 dom_pw_info.in.domain_name = &domain_name;
982 printf("Testing OemChangePasswordUser2\n");
984 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &dom_pw_info);
985 if (NT_STATUS_IS_OK(status)) {
986 policy_min_pw_len = dom_pw_info.out.info.min_password_length;
989 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
991 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
992 account.string = TEST_ACCOUNT_NAME;
994 E_deshash(oldpass, old_lm_hash);
995 E_deshash(newpass, new_lm_hash);
997 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
998 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
999 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1001 r.in.server = &server;
1002 r.in.account = &account;
1003 r.in.password = &lm_pass;
1004 r.in.hash = &lm_verifier;
1006 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1007 if (!NT_STATUS_IS_OK(status)) {
1008 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
1011 *password = newpass;
1018 static BOOL test_ChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1019 struct policy_handle *handle, char **password)
1022 struct samr_ChangePasswordUser2 r;
1024 struct lsa_String server, account;
1025 struct samr_CryptPassword nt_pass, lm_pass;
1026 struct samr_Password nt_verifier, lm_verifier;
1027 char *oldpass = *password;
1029 uint8_t old_nt_hash[16], new_nt_hash[16];
1030 uint8_t old_lm_hash[16], new_lm_hash[16];
1032 struct samr_GetDomPwInfo dom_pw_info;
1033 int policy_min_pw_len = 0;
1035 struct lsa_String domain_name;
1036 domain_name.string = "";
1037 dom_pw_info.in.domain_name = &domain_name;
1039 printf("Testing ChangePasswordUser2\n");
1041 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &dom_pw_info);
1042 if (NT_STATUS_IS_OK(status)) {
1043 policy_min_pw_len = dom_pw_info.out.info.min_password_length;
1046 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1048 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1049 init_lsa_String(&account, TEST_ACCOUNT_NAME);
1051 E_md4hash(oldpass, old_nt_hash);
1052 E_md4hash(newpass, new_nt_hash);
1054 E_deshash(oldpass, old_lm_hash);
1055 E_deshash(newpass, new_lm_hash);
1057 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
1058 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1059 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1061 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1062 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1063 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1065 r.in.server = &server;
1066 r.in.account = &account;
1067 r.in.nt_password = &nt_pass;
1068 r.in.nt_verifier = &nt_verifier;
1070 r.in.lm_password = &lm_pass;
1071 r.in.lm_verifier = &lm_verifier;
1073 status = dcerpc_samr_ChangePasswordUser2(p, mem_ctx, &r);
1074 if (!NT_STATUS_IS_OK(status)) {
1075 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
1078 *password = newpass;
1085 static BOOL test_ChangePasswordUser3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1086 struct policy_handle *handle,
1087 int policy_min_pw_len,
1091 struct samr_ChangePasswordUser3 r;
1093 struct lsa_String server, account;
1094 struct samr_CryptPassword nt_pass, lm_pass;
1095 struct samr_Password nt_verifier, lm_verifier;
1096 char *oldpass = *password;
1097 char *newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1098 uint8_t old_nt_hash[16], new_nt_hash[16];
1099 uint8_t old_lm_hash[16], new_lm_hash[16];
1101 printf("Testing ChangePasswordUser3\n");
1103 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1104 init_lsa_String(&account, TEST_ACCOUNT_NAME);
1106 E_md4hash(oldpass, old_nt_hash);
1107 E_md4hash(newpass, new_nt_hash);
1109 E_deshash(oldpass, old_lm_hash);
1110 E_deshash(newpass, new_lm_hash);
1112 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1113 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1114 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1116 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1117 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1118 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1120 r.in.server = &server;
1121 r.in.account = &account;
1122 r.in.nt_password = &nt_pass;
1123 r.in.nt_verifier = &nt_verifier;
1125 r.in.lm_password = &lm_pass;
1126 r.in.lm_verifier = &lm_verifier;
1127 r.in.password3 = NULL;
1129 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1130 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1131 && !policy_min_pw_len) {
1132 if (r.out.dominfo) {
1133 policy_min_pw_len = r.out.dominfo->min_password_length;
1135 if (policy_min_pw_len) /* try again with the right min password length */ {
1136 ret = test_ChangePasswordUser3(p, mem_ctx, handle, policy_min_pw_len, password);
1138 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
1141 } else if (!NT_STATUS_IS_OK(status)) {
1142 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
1145 *password = newpass;
1152 static BOOL test_GetMembersInAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1153 struct policy_handle *alias_handle)
1155 struct samr_GetMembersInAlias r;
1156 struct lsa_SidArray sids;
1160 printf("Testing GetMembersInAlias\n");
1162 r.in.alias_handle = alias_handle;
1165 status = dcerpc_samr_GetMembersInAlias(p, mem_ctx, &r);
1166 if (!NT_STATUS_IS_OK(status)) {
1167 printf("GetMembersInAlias failed - %s\n",
1175 static BOOL test_AddMemberToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1176 struct policy_handle *alias_handle,
1177 const struct dom_sid *domain_sid)
1179 struct samr_AddAliasMember r;
1180 struct samr_DeleteAliasMember d;
1183 struct dom_sid *sid;
1185 sid = dom_sid_add_rid(mem_ctx, domain_sid, 512);
1187 printf("testing AddAliasMember\n");
1188 r.in.alias_handle = alias_handle;
1191 status = dcerpc_samr_AddAliasMember(p, mem_ctx, &r);
1192 if (!NT_STATUS_IS_OK(status)) {
1193 printf("AddAliasMember failed - %s\n", nt_errstr(status));
1197 d.in.alias_handle = alias_handle;
1200 status = dcerpc_samr_DeleteAliasMember(p, mem_ctx, &d);
1201 if (!NT_STATUS_IS_OK(status)) {
1202 printf("DelAliasMember failed - %s\n", nt_errstr(status));
1209 static BOOL test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1210 struct policy_handle *alias_handle)
1212 struct samr_AddMultipleMembersToAlias a;
1213 struct samr_RemoveMultipleMembersFromAlias r;
1216 struct lsa_SidArray sids;
1218 printf("testing AddMultipleMembersToAlias\n");
1219 a.in.alias_handle = alias_handle;
1223 sids.sids = talloc_array(mem_ctx, struct lsa_SidPtr, 3);
1225 sids.sids[0].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-1");
1226 sids.sids[1].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-2");
1227 sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-3");
1229 status = dcerpc_samr_AddMultipleMembersToAlias(p, mem_ctx, &a);
1230 if (!NT_STATUS_IS_OK(status)) {
1231 printf("AddMultipleMembersToAlias failed - %s\n", nt_errstr(status));
1236 printf("testing RemoveMultipleMembersFromAlias\n");
1237 r.in.alias_handle = alias_handle;
1240 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1241 if (!NT_STATUS_IS_OK(status)) {
1242 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1246 /* strange! removing twice doesn't give any error */
1247 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1248 if (!NT_STATUS_IS_OK(status)) {
1249 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1253 /* but removing an alias that isn't there does */
1254 sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-4");
1256 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1257 if (!NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_NOT_FOUND, status)) {
1258 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1265 static BOOL test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1266 struct policy_handle *user_handle)
1268 struct samr_TestPrivateFunctionsUser r;
1272 printf("Testing TestPrivateFunctionsUser\n");
1274 r.in.user_handle = user_handle;
1276 status = dcerpc_samr_TestPrivateFunctionsUser(p, mem_ctx, &r);
1277 if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
1278 printf("TestPrivateFunctionsUser failed - %s\n", nt_errstr(status));
1286 static BOOL test_user_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1287 struct policy_handle *handle, uint32_t base_acct_flags,
1288 const char *base_acct_name)
1292 if (!test_QuerySecurity(p, mem_ctx, handle)) {
1296 if (!test_QueryUserInfo(p, mem_ctx, handle)) {
1300 if (!test_QueryUserInfo2(p, mem_ctx, handle)) {
1304 if (!test_SetUserInfo(p, mem_ctx, handle, base_acct_flags,
1309 if (!test_GetUserPwInfo(p, mem_ctx, handle)) {
1313 if (!test_TestPrivateFunctionsUser(p, mem_ctx, handle)) {
1320 static BOOL test_alias_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1321 struct policy_handle *alias_handle,
1322 const struct dom_sid *domain_sid)
1326 if (!test_QuerySecurity(p, mem_ctx, alias_handle)) {
1330 if (!test_QueryAliasInfo(p, mem_ctx, alias_handle)) {
1334 if (!test_SetAliasInfo(p, mem_ctx, alias_handle)) {
1338 if (!test_AddMemberToAlias(p, mem_ctx, alias_handle, domain_sid)) {
1342 if (!test_AddMultipleMembersToAlias(p, mem_ctx, alias_handle)) {
1350 BOOL test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1351 struct policy_handle *handle, const char *name)
1354 struct samr_DeleteUser d;
1355 struct policy_handle user_handle;
1358 status = test_LookupName(p, mem_ctx, handle, name, &rid);
1359 if (!NT_STATUS_IS_OK(status)) {
1363 status = test_OpenUser_byname(p, mem_ctx, handle, name, &user_handle);
1364 if (!NT_STATUS_IS_OK(status)) {
1368 d.in.user_handle = &user_handle;
1369 d.out.user_handle = &user_handle;
1370 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
1371 if (!NT_STATUS_IS_OK(status)) {
1378 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
1383 static BOOL test_DeleteGroup_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1384 struct policy_handle *handle, const char *name)
1387 struct samr_OpenGroup r;
1388 struct samr_DeleteDomainGroup d;
1389 struct policy_handle group_handle;
1392 status = test_LookupName(p, mem_ctx, handle, name, &rid);
1393 if (!NT_STATUS_IS_OK(status)) {
1397 r.in.domain_handle = handle;
1398 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1400 r.out.group_handle = &group_handle;
1401 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
1402 if (!NT_STATUS_IS_OK(status)) {
1406 d.in.group_handle = &group_handle;
1407 d.out.group_handle = &group_handle;
1408 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
1409 if (!NT_STATUS_IS_OK(status)) {
1416 printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
1421 static BOOL test_DeleteAlias_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1422 struct policy_handle *domain_handle, const char *name)
1425 struct samr_OpenAlias r;
1426 struct samr_DeleteDomAlias d;
1427 struct policy_handle alias_handle;
1430 printf("testing DeleteAlias_byname\n");
1432 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
1433 if (!NT_STATUS_IS_OK(status)) {
1437 r.in.domain_handle = domain_handle;
1438 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1440 r.out.alias_handle = &alias_handle;
1441 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
1442 if (!NT_STATUS_IS_OK(status)) {
1446 d.in.alias_handle = &alias_handle;
1447 d.out.alias_handle = &alias_handle;
1448 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
1449 if (!NT_STATUS_IS_OK(status)) {
1456 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
1460 static BOOL test_DeleteAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1461 struct policy_handle *alias_handle)
1463 struct samr_DeleteDomAlias d;
1466 printf("Testing DeleteAlias\n");
1468 d.in.alias_handle = alias_handle;
1469 d.out.alias_handle = alias_handle;
1471 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
1472 if (!NT_STATUS_IS_OK(status)) {
1473 printf("DeleteAlias failed - %s\n", nt_errstr(status));
1480 static BOOL test_CreateAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1481 struct policy_handle *domain_handle,
1482 struct policy_handle *alias_handle,
1483 const struct dom_sid *domain_sid)
1486 struct samr_CreateDomAlias r;
1487 struct lsa_String name;
1491 init_lsa_String(&name, TEST_ALIASNAME);
1492 r.in.domain_handle = domain_handle;
1493 r.in.alias_name = &name;
1494 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1495 r.out.alias_handle = alias_handle;
1498 printf("Testing CreateAlias (%s)\n", r.in.alias_name->string);
1500 status = dcerpc_samr_CreateDomAlias(p, mem_ctx, &r);
1502 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1503 printf("Server refused create of '%s'\n", r.in.alias_name->string);
1507 if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
1508 if (!test_DeleteAlias_byname(p, mem_ctx, domain_handle, r.in.alias_name->string)) {
1511 status = dcerpc_samr_CreateDomAlias(p, mem_ctx, &r);
1514 if (!NT_STATUS_IS_OK(status)) {
1515 printf("CreateAlias failed - %s\n", nt_errstr(status));
1519 if (!test_alias_ops(p, mem_ctx, alias_handle, domain_sid)) {
1526 static BOOL test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1527 struct policy_handle *domain_handle, char **password)
1535 if (!test_ChangePasswordUser(p, mem_ctx, domain_handle, password)) {
1539 if (!test_ChangePasswordUser2(p, mem_ctx, domain_handle, password)) {
1543 if (!test_OemChangePasswordUser2(p, mem_ctx, domain_handle, password)) {
1547 /* we change passwords twice - this has the effect of verifying
1548 they were changed correctly for the final call */
1549 if (!test_ChangePasswordUser3(p, mem_ctx, domain_handle, 0, password)) {
1553 if (!test_ChangePasswordUser3(p, mem_ctx, domain_handle, 0, password)) {
1560 static BOOL test_CreateUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1561 struct policy_handle *domain_handle, struct policy_handle *user_handle)
1564 struct samr_CreateUser r;
1565 struct samr_QueryUserInfo q;
1567 char *password = NULL;
1570 const uint32_t password_fields[] = {
1571 SAMR_FIELD_PASSWORD,
1572 SAMR_FIELD_PASSWORD2,
1573 SAMR_FIELD_PASSWORD | SAMR_FIELD_PASSWORD2,
1577 TALLOC_CTX *user_ctx;
1579 /* This call creates a 'normal' account - check that it really does */
1580 const uint32_t acct_flags = ACB_NORMAL;
1581 struct lsa_String name;
1584 user_ctx = talloc_named(mem_ctx, 0, "test_CreateUser2 per-user context");
1585 init_lsa_String(&name, TEST_ACCOUNT_NAME);
1587 r.in.domain_handle = domain_handle;
1588 r.in.account_name = &name;
1589 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1590 r.out.user_handle = user_handle;
1593 printf("Testing CreateUser(%s)\n", r.in.account_name->string);
1595 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
1597 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1598 printf("Server refused create of '%s'\n", r.in.account_name->string);
1599 ZERO_STRUCTP(user_handle);
1600 talloc_free(user_ctx);
1604 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
1605 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
1606 talloc_free(user_ctx);
1609 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
1611 if (!NT_STATUS_IS_OK(status)) {
1612 talloc_free(user_ctx);
1613 printf("CreateUser failed - %s\n", nt_errstr(status));
1617 q.in.user_handle = user_handle;
1620 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
1621 if (!NT_STATUS_IS_OK(status)) {
1622 printf("QueryUserInfo level %u failed - %s\n",
1623 q.in.level, nt_errstr(status));
1626 if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
1627 printf("QuerUserInfo level 16 failed, it returned 0x%08x (%u) when we expected flags of 0x%08x (%u)\n",
1628 q.out.info->info16.acct_flags, q.out.info->info16.acct_flags,
1629 acct_flags, acct_flags);
1634 if (!test_user_ops(p, user_ctx, user_handle, acct_flags, name.string)) {
1638 if (!test_SetUserPass(p, user_ctx, user_handle, &password)) {
1642 for (i = 0; password_fields[i]; i++) {
1643 if (!test_SetUserPass_23(p, user_ctx, user_handle, password_fields[i], &password)) {
1647 /* check it was set right */
1648 if (!test_ChangePasswordUser3(p, user_ctx, domain_handle, 0, &password)) {
1653 for (i = 0; password_fields[i]; i++) {
1654 if (!test_SetUserPass_25(p, user_ctx, user_handle, password_fields[i], &password)) {
1658 /* check it was set right */
1659 if (!test_ChangePasswordUser3(p, user_ctx, domain_handle, 0, &password)) {
1664 if (!test_SetUserPassEx(p, user_ctx, user_handle, &password)) {
1668 if (!test_ChangePassword(p, user_ctx, domain_handle, &password)) {
1672 talloc_free(user_ctx);
1678 static BOOL test_DeleteUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1679 struct policy_handle *user_handle)
1681 struct samr_DeleteUser d;
1685 printf("Testing DeleteUser\n");
1687 d.in.user_handle = user_handle;
1688 d.out.user_handle = user_handle;
1690 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
1691 if (!NT_STATUS_IS_OK(status)) {
1692 printf("DeleteUser failed - %s\n", nt_errstr(status));
1699 static BOOL test_CreateUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1700 struct policy_handle *handle)
1703 struct samr_CreateUser2 r;
1704 struct samr_QueryUserInfo q;
1705 struct samr_DeleteUser d;
1706 struct policy_handle user_handle;
1708 struct lsa_String name;
1713 uint32_t acct_flags;
1714 const char *account_name;
1716 } account_types[] = {
1717 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
1718 { ACB_NORMAL, TEST_ACCOUNT_NAME "&" , NT_STATUS_INVALID_ACCOUNT_NAME },
1719 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1720 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1721 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
1722 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1723 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1724 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
1725 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1726 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1727 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
1728 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
1729 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
1730 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1731 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1732 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
1735 for (i = 0; account_types[i].account_name; i++) {
1736 TALLOC_CTX *user_ctx;
1737 uint32_t acct_flags = account_types[i].acct_flags;
1738 uint32_t access_granted;
1739 user_ctx = talloc_named(mem_ctx, 0, "test_CreateUser2 per-user context");
1740 init_lsa_String(&name, account_types[i].account_name);
1742 r.in.domain_handle = handle;
1743 r.in.account_name = &name;
1744 r.in.acct_flags = acct_flags;
1745 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1746 r.out.user_handle = &user_handle;
1747 r.out.access_granted = &access_granted;
1750 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
1752 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
1754 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1755 talloc_free(user_ctx);
1756 printf("Server refused create of '%s'\n", r.in.account_name->string);
1759 } else if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
1760 if (!test_DeleteUser_byname(p, user_ctx, handle, r.in.account_name->string)) {
1761 talloc_free(user_ctx);
1765 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
1768 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
1769 printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
1770 nt_errstr(status), nt_errstr(account_types[i].nt_status));
1774 if (NT_STATUS_IS_OK(status)) {
1775 q.in.user_handle = &user_handle;
1778 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
1779 if (!NT_STATUS_IS_OK(status)) {
1780 printf("QueryUserInfo level %u failed - %s\n",
1781 q.in.level, nt_errstr(status));
1784 if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
1785 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
1786 q.out.info->info16.acct_flags,
1792 if (!test_user_ops(p, user_ctx, &user_handle, acct_flags, name.string)) {
1796 printf("Testing DeleteUser (createuser2 test)\n");
1798 d.in.user_handle = &user_handle;
1799 d.out.user_handle = &user_handle;
1801 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
1802 if (!NT_STATUS_IS_OK(status)) {
1803 printf("DeleteUser failed - %s\n", nt_errstr(status));
1807 talloc_free(user_ctx);
1813 static BOOL test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1814 struct policy_handle *handle)
1817 struct samr_QueryAliasInfo r;
1818 uint16_t levels[] = {1, 2, 3};
1822 for (i=0;i<ARRAY_SIZE(levels);i++) {
1823 printf("Testing QueryAliasInfo level %u\n", levels[i]);
1825 r.in.alias_handle = handle;
1826 r.in.level = levels[i];
1828 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
1829 if (!NT_STATUS_IS_OK(status)) {
1830 printf("QueryAliasInfo level %u failed - %s\n",
1831 levels[i], nt_errstr(status));
1839 static BOOL test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1840 struct policy_handle *handle)
1843 struct samr_QueryGroupInfo r;
1844 uint16_t levels[] = {1, 2, 3, 4, 5};
1848 for (i=0;i<ARRAY_SIZE(levels);i++) {
1849 printf("Testing QueryGroupInfo level %u\n", levels[i]);
1851 r.in.group_handle = handle;
1852 r.in.level = levels[i];
1854 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
1855 if (!NT_STATUS_IS_OK(status)) {
1856 printf("QueryGroupInfo level %u failed - %s\n",
1857 levels[i], nt_errstr(status));
1865 static BOOL test_QueryGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1866 struct policy_handle *handle)
1869 struct samr_QueryGroupMember r;
1872 printf("Testing QueryGroupMember\n");
1874 r.in.group_handle = handle;
1876 status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &r);
1877 if (!NT_STATUS_IS_OK(status)) {
1878 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
1886 static BOOL test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1887 struct policy_handle *handle)
1890 struct samr_QueryGroupInfo r;
1891 struct samr_SetGroupInfo s;
1892 uint16_t levels[] = {1, 2, 3, 4};
1893 uint16_t set_ok[] = {0, 1, 1, 1};
1897 for (i=0;i<ARRAY_SIZE(levels);i++) {
1898 printf("Testing QueryGroupInfo level %u\n", levels[i]);
1900 r.in.group_handle = handle;
1901 r.in.level = levels[i];
1903 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
1904 if (!NT_STATUS_IS_OK(status)) {
1905 printf("QueryGroupInfo level %u failed - %s\n",
1906 levels[i], nt_errstr(status));
1910 printf("Testing SetGroupInfo level %u\n", levels[i]);
1912 s.in.group_handle = handle;
1913 s.in.level = levels[i];
1914 s.in.info = r.out.info;
1917 /* disabled this, as it changes the name only from the point of view of samr,
1918 but leaves the name from the point of view of w2k3 internals (and ldap). This means
1919 the name is still reserved, so creating the old name fails, but deleting by the old name
1921 if (s.in.level == 2) {
1922 init_lsa_String(&s.in.info->string, "NewName");
1926 if (s.in.level == 4) {
1927 init_lsa_String(&s.in.info->description, "test description");
1930 status = dcerpc_samr_SetGroupInfo(p, mem_ctx, &s);
1932 if (!NT_STATUS_IS_OK(status)) {
1933 printf("SetGroupInfo level %u failed - %s\n",
1934 r.in.level, nt_errstr(status));
1939 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
1940 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
1941 r.in.level, nt_errstr(status));
1951 static BOOL test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1952 struct policy_handle *handle)
1955 struct samr_QueryUserInfo r;
1956 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
1957 11, 12, 13, 14, 16, 17, 20, 21};
1961 for (i=0;i<ARRAY_SIZE(levels);i++) {
1962 printf("Testing QueryUserInfo level %u\n", levels[i]);
1964 r.in.user_handle = handle;
1965 r.in.level = levels[i];
1967 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
1968 if (!NT_STATUS_IS_OK(status)) {
1969 printf("QueryUserInfo level %u failed - %s\n",
1970 levels[i], nt_errstr(status));
1978 static BOOL test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1979 struct policy_handle *handle)
1982 struct samr_QueryUserInfo2 r;
1983 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
1984 11, 12, 13, 14, 16, 17, 20, 21};
1988 for (i=0;i<ARRAY_SIZE(levels);i++) {
1989 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
1991 r.in.user_handle = handle;
1992 r.in.level = levels[i];
1994 status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r);
1995 if (!NT_STATUS_IS_OK(status)) {
1996 printf("QueryUserInfo2 level %u failed - %s\n",
1997 levels[i], nt_errstr(status));
2005 static BOOL test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2006 struct policy_handle *handle, uint32_t rid)
2009 struct samr_OpenUser r;
2010 struct policy_handle user_handle;
2013 printf("Testing OpenUser(%u)\n", rid);
2015 r.in.domain_handle = handle;
2016 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2018 r.out.user_handle = &user_handle;
2020 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
2021 if (!NT_STATUS_IS_OK(status)) {
2022 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
2026 if (!test_QuerySecurity(p, mem_ctx, &user_handle)) {
2030 if (!test_QueryUserInfo(p, mem_ctx, &user_handle)) {
2034 if (!test_QueryUserInfo2(p, mem_ctx, &user_handle)) {
2038 if (!test_GetUserPwInfo(p, mem_ctx, &user_handle)) {
2042 if (!test_GetGroupsForUser(p,mem_ctx, &user_handle)) {
2046 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
2053 static BOOL test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2054 struct policy_handle *handle, uint32_t rid)
2057 struct samr_OpenGroup r;
2058 struct policy_handle group_handle;
2061 printf("Testing OpenGroup(%u)\n", rid);
2063 r.in.domain_handle = handle;
2064 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2066 r.out.group_handle = &group_handle;
2068 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
2069 if (!NT_STATUS_IS_OK(status)) {
2070 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
2074 if (!test_QuerySecurity(p, mem_ctx, &group_handle)) {
2078 if (!test_QueryGroupInfo(p, mem_ctx, &group_handle)) {
2082 if (!test_QueryGroupMember(p, mem_ctx, &group_handle)) {
2086 if (!test_samr_handle_Close(p, mem_ctx, &group_handle)) {
2093 static BOOL test_OpenAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2094 struct policy_handle *handle, uint32_t rid)
2097 struct samr_OpenAlias r;
2098 struct policy_handle alias_handle;
2101 printf("Testing OpenAlias(%u)\n", rid);
2103 r.in.domain_handle = handle;
2104 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2106 r.out.alias_handle = &alias_handle;
2108 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
2109 if (!NT_STATUS_IS_OK(status)) {
2110 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
2114 if (!test_QuerySecurity(p, mem_ctx, &alias_handle)) {
2118 if (!test_QueryAliasInfo(p, mem_ctx, &alias_handle)) {
2122 if (!test_GetMembersInAlias(p, mem_ctx, &alias_handle)) {
2126 if (!test_samr_handle_Close(p, mem_ctx, &alias_handle)) {
2133 static BOOL test_EnumDomainUsers(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2134 struct policy_handle *handle)
2137 struct samr_EnumDomainUsers r;
2138 uint32_t resume_handle=0;
2141 struct samr_LookupNames n;
2142 struct samr_LookupRids lr ;
2144 printf("Testing EnumDomainUsers\n");
2146 r.in.domain_handle = handle;
2147 r.in.resume_handle = &resume_handle;
2148 r.in.acct_flags = 0;
2149 r.in.max_size = (uint32_t)-1;
2150 r.out.resume_handle = &resume_handle;
2152 status = dcerpc_samr_EnumDomainUsers(p, mem_ctx, &r);
2153 if (!NT_STATUS_IS_OK(status)) {
2154 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
2162 if (r.out.sam->count == 0) {
2166 for (i=0;i<r.out.sam->count;i++) {
2167 if (!test_OpenUser(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
2172 printf("Testing LookupNames\n");
2173 n.in.domain_handle = handle;
2174 n.in.num_names = r.out.sam->count;
2175 n.in.names = talloc_array(mem_ctx, struct lsa_String, r.out.sam->count);
2176 for (i=0;i<r.out.sam->count;i++) {
2177 n.in.names[i] = r.out.sam->entries[i].name;
2179 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
2180 if (!NT_STATUS_IS_OK(status)) {
2181 printf("LookupNames failed - %s\n", nt_errstr(status));
2186 printf("Testing LookupRids\n");
2187 lr.in.domain_handle = handle;
2188 lr.in.num_rids = r.out.sam->count;
2189 lr.in.rids = talloc_array(mem_ctx, uint32_t, r.out.sam->count);
2190 for (i=0;i<r.out.sam->count;i++) {
2191 lr.in.rids[i] = r.out.sam->entries[i].idx;
2193 status = dcerpc_samr_LookupRids(p, mem_ctx, &lr);
2194 if (!NT_STATUS_IS_OK(status)) {
2195 printf("LookupRids failed - %s\n", nt_errstr(status));
2203 try blasting the server with a bunch of sync requests
2205 static BOOL test_EnumDomainUsers_async(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2206 struct policy_handle *handle)
2209 struct samr_EnumDomainUsers r;
2210 uint32_t resume_handle=0;
2212 #define ASYNC_COUNT 100
2213 struct rpc_request *req[ASYNC_COUNT];
2215 if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
2216 printf("samr async test disabled - enable dangerous tests to use\n");
2220 printf("Testing EnumDomainUsers_async\n");
2222 r.in.domain_handle = handle;
2223 r.in.resume_handle = &resume_handle;
2224 r.in.acct_flags = 0;
2225 r.in.max_size = (uint32_t)-1;
2226 r.out.resume_handle = &resume_handle;
2228 for (i=0;i<ASYNC_COUNT;i++) {
2229 req[i] = dcerpc_samr_EnumDomainUsers_send(p, mem_ctx, &r);
2232 for (i=0;i<ASYNC_COUNT;i++) {
2233 status = dcerpc_ndr_request_recv(req[i]);
2234 if (!NT_STATUS_IS_OK(status)) {
2235 printf("EnumDomainUsers[%d] failed - %s\n",
2236 i, nt_errstr(status));
2241 printf("%d async requests OK\n", i);
2246 static BOOL test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2247 struct policy_handle *handle)
2250 struct samr_EnumDomainGroups r;
2251 uint32_t resume_handle=0;
2255 printf("Testing EnumDomainGroups\n");
2257 r.in.domain_handle = handle;
2258 r.in.resume_handle = &resume_handle;
2259 r.in.max_size = (uint32_t)-1;
2260 r.out.resume_handle = &resume_handle;
2262 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
2263 if (!NT_STATUS_IS_OK(status)) {
2264 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
2272 for (i=0;i<r.out.sam->count;i++) {
2273 if (!test_OpenGroup(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
2281 static BOOL test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2282 struct policy_handle *handle)
2285 struct samr_EnumDomainAliases r;
2286 uint32_t resume_handle=0;
2290 printf("Testing EnumDomainAliases\n");
2292 r.in.domain_handle = handle;
2293 r.in.resume_handle = &resume_handle;
2294 r.in.acct_flags = (uint32_t)-1;
2295 r.out.resume_handle = &resume_handle;
2297 status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
2298 if (!NT_STATUS_IS_OK(status)) {
2299 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
2307 for (i=0;i<r.out.sam->count;i++) {
2308 if (!test_OpenAlias(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
2316 static BOOL test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2317 struct policy_handle *handle)
2320 struct samr_GetDisplayEnumerationIndex r;
2322 uint16_t levels[] = {1, 2, 3, 4, 5};
2323 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
2326 for (i=0;i<ARRAY_SIZE(levels);i++) {
2327 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
2329 r.in.domain_handle = handle;
2330 r.in.level = levels[i];
2331 init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
2333 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
2336 !NT_STATUS_IS_OK(status) &&
2337 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2338 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
2339 levels[i], nt_errstr(status));
2343 init_lsa_String(&r.in.name, "zzzzzzzz");
2345 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
2347 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2348 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
2349 levels[i], nt_errstr(status));
2357 static BOOL test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2358 struct policy_handle *handle)
2361 struct samr_GetDisplayEnumerationIndex2 r;
2363 uint16_t levels[] = {1, 2, 3, 4, 5};
2364 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
2367 for (i=0;i<ARRAY_SIZE(levels);i++) {
2368 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
2370 r.in.domain_handle = handle;
2371 r.in.level = levels[i];
2372 init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
2374 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
2376 !NT_STATUS_IS_OK(status) &&
2377 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2378 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
2379 levels[i], nt_errstr(status));
2383 init_lsa_String(&r.in.name, "zzzzzzzz");
2385 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
2386 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2387 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
2388 levels[i], nt_errstr(status));
2396 static BOOL test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2397 struct policy_handle *handle)
2400 struct samr_QueryDisplayInfo r;
2402 uint16_t levels[] = {1, 2, 3, 4, 5};
2405 for (i=0;i<ARRAY_SIZE(levels);i++) {
2406 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
2408 r.in.domain_handle = handle;
2409 r.in.level = levels[i];
2411 r.in.max_entries = 1000;
2412 r.in.buf_size = (uint32_t)-1;
2414 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
2415 if (!NT_STATUS_IS_OK(status)) {
2416 printf("QueryDisplayInfo level %u failed - %s\n",
2417 levels[i], nt_errstr(status));
2425 static BOOL test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2426 struct policy_handle *handle)
2429 struct samr_QueryDisplayInfo2 r;
2431 uint16_t levels[] = {1, 2, 3, 4, 5};
2434 for (i=0;i<ARRAY_SIZE(levels);i++) {
2435 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
2437 r.in.domain_handle = handle;
2438 r.in.level = levels[i];
2440 r.in.max_entries = 1000;
2441 r.in.buf_size = (uint32_t)-1;
2443 status = dcerpc_samr_QueryDisplayInfo2(p, mem_ctx, &r);
2444 if (!NT_STATUS_IS_OK(status)) {
2445 printf("QueryDisplayInfo2 level %u failed - %s\n",
2446 levels[i], nt_errstr(status));
2454 static BOOL test_QueryDisplayInfo3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2455 struct policy_handle *handle)
2458 struct samr_QueryDisplayInfo3 r;
2460 uint16_t levels[] = {1, 2, 3, 4, 5};
2463 for (i=0;i<ARRAY_SIZE(levels);i++) {
2464 printf("Testing QueryDisplayInfo3 level %u\n", levels[i]);
2466 r.in.domain_handle = handle;
2467 r.in.level = levels[i];
2469 r.in.max_entries = 1000;
2470 r.in.buf_size = (uint32_t)-1;
2472 status = dcerpc_samr_QueryDisplayInfo3(p, mem_ctx, &r);
2473 if (!NT_STATUS_IS_OK(status)) {
2474 printf("QueryDisplayInfo3 level %u failed - %s\n",
2475 levels[i], nt_errstr(status));
2484 static BOOL test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2485 struct policy_handle *handle)
2488 struct samr_QueryDisplayInfo r;
2491 printf("Testing QueryDisplayInfo continuation\n");
2493 r.in.domain_handle = handle;
2496 r.in.max_entries = 1;
2497 r.in.buf_size = (uint32_t)-1;
2500 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
2501 if (NT_STATUS_IS_OK(status) && r.out.returned_size != 0) {
2502 if (r.out.info.info1.entries[0].idx != r.in.start_idx + 1) {
2503 printf("failed: expected idx %d but got %d\n",
2505 r.out.info.info1.entries[0].idx);
2510 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
2511 !NT_STATUS_IS_OK(status)) {
2512 printf("QueryDisplayInfo level %u failed - %s\n",
2513 r.in.level, nt_errstr(status));
2518 } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
2519 NT_STATUS_IS_OK(status)) &&
2520 r.out.returned_size != 0);
2525 static BOOL test_QueryDomainInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2526 struct policy_handle *handle)
2529 struct samr_QueryDomainInfo r;
2530 struct samr_SetDomainInfo s;
2531 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
2532 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
2536 for (i=0;i<ARRAY_SIZE(levels);i++) {
2537 printf("Testing QueryDomainInfo level %u\n", levels[i]);
2539 r.in.domain_handle = handle;
2540 r.in.level = levels[i];
2542 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2543 if (!NT_STATUS_IS_OK(status)) {
2544 printf("QueryDomainInfo level %u failed - %s\n",
2545 r.in.level, nt_errstr(status));
2550 printf("Testing SetDomainInfo level %u\n", levels[i]);
2552 s.in.domain_handle = handle;
2553 s.in.level = levels[i];
2554 s.in.info = r.out.info;
2556 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2558 if (!NT_STATUS_IS_OK(status)) {
2559 printf("SetDomainInfo level %u failed - %s\n",
2560 r.in.level, nt_errstr(status));
2565 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
2566 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
2567 r.in.level, nt_errstr(status));
2573 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2574 if (!NT_STATUS_IS_OK(status)) {
2575 printf("QueryDomainInfo level %u failed - %s\n",
2576 r.in.level, nt_errstr(status));
2586 static BOOL test_QueryDomainInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2587 struct policy_handle *handle)
2590 struct samr_QueryDomainInfo2 r;
2591 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
2595 for (i=0;i<ARRAY_SIZE(levels);i++) {
2596 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
2598 r.in.domain_handle = handle;
2599 r.in.level = levels[i];
2601 status = dcerpc_samr_QueryDomainInfo2(p, mem_ctx, &r);
2602 if (!NT_STATUS_IS_OK(status)) {
2603 printf("QueryDomainInfo2 level %u failed - %s\n",
2604 r.in.level, nt_errstr(status));
2613 /* Test whether querydispinfo level 5 and enumdomgroups return the same
2614 set of group names. */
2615 static BOOL test_GroupList(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2616 struct policy_handle *handle)
2618 struct samr_EnumDomainGroups q1;
2619 struct samr_QueryDisplayInfo q2;
2621 uint32_t resume_handle=0;
2626 const char **names = NULL;
2628 printf("Testing coherency of querydispinfo vs enumdomgroups\n");
2630 q1.in.domain_handle = handle;
2631 q1.in.resume_handle = &resume_handle;
2633 q1.out.resume_handle = &resume_handle;
2635 status = STATUS_MORE_ENTRIES;
2636 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
2637 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &q1);
2639 if (!NT_STATUS_IS_OK(status) &&
2640 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
2643 for (i=0; i<q1.out.num_entries; i++) {
2644 add_string_to_array(mem_ctx,
2645 q1.out.sam->entries[i].name.string,
2646 &names, &num_names);
2650 if (!NT_STATUS_IS_OK(status)) {
2651 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
2659 q2.in.domain_handle = handle;
2661 q2.in.start_idx = 0;
2662 q2.in.max_entries = 5;
2663 q2.in.buf_size = (uint32_t)-1;
2665 status = STATUS_MORE_ENTRIES;
2666 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
2667 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &q2);
2669 if (!NT_STATUS_IS_OK(status) &&
2670 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
2673 for (i=0; i<q2.out.info.info5.count; i++) {
2675 const char *name = q2.out.info.info5.entries[i].account_name.string;
2677 for (j=0; j<num_names; j++) {
2678 if (names[j] == NULL)
2680 /* Hmm. No strequal in samba4 */
2681 if (strequal(names[j], name)) {
2689 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
2694 q2.in.start_idx += q2.out.info.info5.count;
2697 if (!NT_STATUS_IS_OK(status)) {
2698 printf("QueryDisplayInfo level 5 failed - %s\n",
2703 for (i=0; i<num_names; i++) {
2704 if (names[i] != NULL) {
2705 printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
2714 static BOOL test_DeleteDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2715 struct policy_handle *group_handle)
2717 struct samr_DeleteDomainGroup d;
2721 printf("Testing DeleteDomainGroup\n");
2723 d.in.group_handle = group_handle;
2724 d.out.group_handle = group_handle;
2726 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
2727 if (!NT_STATUS_IS_OK(status)) {
2728 printf("DeleteDomainGroup failed - %s\n", nt_errstr(status));
2735 static BOOL test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2736 struct policy_handle *domain_handle)
2738 struct samr_TestPrivateFunctionsDomain r;
2742 printf("Testing TestPrivateFunctionsDomain\n");
2744 r.in.domain_handle = domain_handle;
2746 status = dcerpc_samr_TestPrivateFunctionsDomain(p, mem_ctx, &r);
2747 if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
2748 printf("TestPrivateFunctionsDomain failed - %s\n", nt_errstr(status));
2755 static BOOL test_RidToSid(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2756 struct policy_handle *domain_handle)
2758 struct samr_RidToSid r;
2762 printf("Testing RidToSid\n");
2764 r.in.domain_handle = domain_handle;
2767 status = dcerpc_samr_RidToSid(p, mem_ctx, &r);
2768 if (!NT_STATUS_IS_OK(status)) {
2769 printf("RidToSid failed - %s\n", nt_errstr(status));
2776 static BOOL test_GetBootKeyInformation(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2777 struct policy_handle *domain_handle)
2779 struct samr_GetBootKeyInformation r;
2783 printf("Testing GetBootKeyInformation\n");
2785 r.in.domain_handle = domain_handle;
2787 status = dcerpc_samr_GetBootKeyInformation(p, mem_ctx, &r);
2788 if (!NT_STATUS_IS_OK(status)) {
2789 /* w2k3 seems to fail this sometimes and pass it sometimes */
2790 printf("GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
2796 static BOOL test_AddGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2797 struct policy_handle *domain_handle,
2798 struct policy_handle *group_handle)
2801 struct samr_AddGroupMember r;
2802 struct samr_DeleteGroupMember d;
2803 struct samr_QueryGroupMember q;
2804 struct samr_SetMemberAttributesOfGroup s;
2808 status = test_LookupName(p, mem_ctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
2809 if (!NT_STATUS_IS_OK(status)) {
2813 r.in.group_handle = group_handle;
2815 r.in.flags = 0; /* ??? */
2817 printf("Testing AddGroupMember and DeleteGroupMember\n");
2819 d.in.group_handle = group_handle;
2822 status = dcerpc_samr_DeleteGroupMember(p, mem_ctx, &d);
2823 if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_NOT_IN_GROUP, status)) {
2824 printf("DeleteGroupMember gave %s - should be NT_STATUS_MEMBER_NOT_IN_GROUP\n",
2829 status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
2830 if (!NT_STATUS_IS_OK(status)) {
2831 printf("AddGroupMember failed - %s\n", nt_errstr(status));
2835 status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
2836 if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_IN_GROUP, status)) {
2837 printf("AddGroupMember gave %s - should be NT_STATUS_MEMBER_IN_GROUP\n",
2842 /* this one is quite strange. I am using random inputs in the
2843 hope of triggering an error that might give us a clue */
2844 s.in.group_handle = group_handle;
2845 s.in.unknown1 = random();
2846 s.in.unknown2 = random();
2848 status = dcerpc_samr_SetMemberAttributesOfGroup(p, mem_ctx, &s);
2849 if (!NT_STATUS_IS_OK(status)) {
2850 printf("SetMemberAttributesOfGroup failed - %s\n", nt_errstr(status));
2854 q.in.group_handle = group_handle;
2856 status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &q);
2857 if (!NT_STATUS_IS_OK(status)) {
2858 printf("QueryGroupMember failed - %s\n", nt_errstr(status));
2862 status = dcerpc_samr_DeleteGroupMember(p, mem_ctx, &d);
2863 if (!NT_STATUS_IS_OK(status)) {
2864 printf("DeleteGroupMember failed - %s\n", nt_errstr(status));
2868 status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
2869 if (!NT_STATUS_IS_OK(status)) {
2870 printf("AddGroupMember failed - %s\n", nt_errstr(status));
2878 static BOOL test_CreateDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2879 struct policy_handle *domain_handle, struct policy_handle *group_handle)
2882 struct samr_CreateDomainGroup r;
2884 struct lsa_String name;
2887 init_lsa_String(&name, TEST_GROUPNAME);
2889 r.in.domain_handle = domain_handle;
2891 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2892 r.out.group_handle = group_handle;
2895 printf("Testing CreateDomainGroup(%s)\n", r.in.name->string);
2897 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
2899 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2900 printf("Server refused create of '%s'\n", r.in.name->string);
2901 ZERO_STRUCTP(group_handle);
2905 if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS) ||
2906 NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
2907 if (!test_DeleteGroup_byname(p, mem_ctx, domain_handle, r.in.name->string)) {
2910 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
2912 if (!NT_STATUS_IS_OK(status)) {
2913 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
2917 if (!test_AddGroupMember(p, mem_ctx, domain_handle, group_handle)) {
2921 if (!test_SetGroupInfo(p, mem_ctx, group_handle)) {
2930 its not totally clear what this does. It seems to accept any sid you like.
2932 static BOOL test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p,
2933 TALLOC_CTX *mem_ctx,
2934 struct policy_handle *domain_handle)
2937 struct samr_RemoveMemberFromForeignDomain r;
2939 r.in.domain_handle = domain_handle;
2940 r.in.sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-12-34-56-78");
2942 status = dcerpc_samr_RemoveMemberFromForeignDomain(p, mem_ctx, &r);
2943 if (!NT_STATUS_IS_OK(status)) {
2944 printf("RemoveMemberFromForeignDomain failed - %s\n", nt_errstr(status));
2953 static BOOL test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2954 struct policy_handle *handle);
2956 static BOOL test_OpenDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2957 struct policy_handle *handle, struct dom_sid *sid)
2960 struct samr_OpenDomain r;
2961 struct policy_handle domain_handle;
2962 struct policy_handle user_handle;
2963 struct policy_handle alias_handle;
2964 struct policy_handle group_handle;
2967 ZERO_STRUCT(user_handle);
2968 ZERO_STRUCT(alias_handle);
2969 ZERO_STRUCT(group_handle);
2970 ZERO_STRUCT(domain_handle);
2972 printf("Testing OpenDomain\n");
2974 r.in.connect_handle = handle;
2975 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2977 r.out.domain_handle = &domain_handle;
2979 status = dcerpc_samr_OpenDomain(p, mem_ctx, &r);
2980 if (!NT_STATUS_IS_OK(status)) {
2981 printf("OpenDomain failed - %s\n", nt_errstr(status));
2985 /* run the domain tests with the main handle closed - this tests
2986 the servers reference counting */
2987 ret &= test_samr_handle_Close(p, mem_ctx, handle);
2989 ret &= test_QuerySecurity(p, mem_ctx, &domain_handle);
2990 ret &= test_RemoveMemberFromForeignDomain(p, mem_ctx, &domain_handle);
2991 ret &= test_CreateUser2(p, mem_ctx, &domain_handle);
2992 ret &= test_CreateUser(p, mem_ctx, &domain_handle, &user_handle);
2993 ret &= test_CreateAlias(p, mem_ctx, &domain_handle, &alias_handle, sid);
2994 ret &= test_CreateDomainGroup(p, mem_ctx, &domain_handle, &group_handle);
2995 ret &= test_QueryDomainInfo(p, mem_ctx, &domain_handle);
2996 ret &= test_QueryDomainInfo2(p, mem_ctx, &domain_handle);
2997 ret &= test_EnumDomainUsers(p, mem_ctx, &domain_handle);
2998 ret &= test_EnumDomainUsers_async(p, mem_ctx, &domain_handle);
2999 ret &= test_EnumDomainGroups(p, mem_ctx, &domain_handle);
3000 ret &= test_EnumDomainAliases(p, mem_ctx, &domain_handle);
3001 ret &= test_QueryDisplayInfo(p, mem_ctx, &domain_handle);
3002 ret &= test_QueryDisplayInfo2(p, mem_ctx, &domain_handle);
3003 ret &= test_QueryDisplayInfo3(p, mem_ctx, &domain_handle);
3004 ret &= test_QueryDisplayInfo_continue(p, mem_ctx, &domain_handle);
3005 ret &= test_GetDisplayEnumerationIndex(p, mem_ctx, &domain_handle);
3006 ret &= test_GetDisplayEnumerationIndex2(p, mem_ctx, &domain_handle);
3007 ret &= test_GroupList(p, mem_ctx, &domain_handle);
3008 ret &= test_TestPrivateFunctionsDomain(p, mem_ctx, &domain_handle);
3009 ret &= test_RidToSid(p, mem_ctx, &domain_handle);
3010 ret &= test_GetBootKeyInformation(p, mem_ctx, &domain_handle);
3012 if (!policy_handle_empty(&user_handle) &&
3013 !test_DeleteUser(p, mem_ctx, &user_handle)) {
3017 if (!policy_handle_empty(&alias_handle) &&
3018 !test_DeleteAlias(p, mem_ctx, &alias_handle)) {
3022 if (!policy_handle_empty(&group_handle) &&
3023 !test_DeleteDomainGroup(p, mem_ctx, &group_handle)) {
3027 ret &= test_samr_handle_Close(p, mem_ctx, &domain_handle);
3029 /* reconnect the main handle */
3030 ret &= test_Connect(p, mem_ctx, handle);
3035 static BOOL test_LookupDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3036 struct policy_handle *handle, struct lsa_String *domain)
3039 struct samr_LookupDomain r;
3040 struct lsa_String n2;
3043 printf("Testing LookupDomain(%s)\n", domain->string);
3045 /* check for correct error codes */
3046 r.in.connect_handle = handle;
3047 r.in.domain_name = &n2;
3050 status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
3051 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_PARAMETER, status)) {
3052 printf("failed: LookupDomain expected NT_STATUS_INVALID_PARAMETER - %s\n", nt_errstr(status));
3056 n2.string = "xxNODOMAINxx";
3058 status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
3059 if (!NT_STATUS_EQUAL(NT_STATUS_NO_SUCH_DOMAIN, status)) {
3060 printf("failed: LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN - %s\n", nt_errstr(status));
3064 r.in.connect_handle = handle;
3065 r.in.domain_name = domain;
3067 status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
3068 if (!NT_STATUS_IS_OK(status)) {
3069 printf("LookupDomain failed - %s\n", nt_errstr(status));
3073 if (!test_GetDomPwInfo(p, mem_ctx, domain)) {
3077 if (!test_OpenDomain(p, mem_ctx, handle, r.out.sid)) {
3085 static BOOL test_EnumDomains(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3086 struct policy_handle *handle)
3089 struct samr_EnumDomains r;
3090 uint32_t resume_handle = 0;
3094 r.in.connect_handle = handle;
3095 r.in.resume_handle = &resume_handle;
3096 r.in.buf_size = (uint32_t)-1;
3097 r.out.resume_handle = &resume_handle;
3099 status = dcerpc_samr_EnumDomains(p, mem_ctx, &r);
3100 if (!NT_STATUS_IS_OK(status)) {
3101 printf("EnumDomains failed - %s\n", nt_errstr(status));
3109 for (i=0;i<r.out.sam->count;i++) {
3110 if (!test_LookupDomain(p, mem_ctx, handle,
3111 &r.out.sam->entries[i].name)) {
3116 status = dcerpc_samr_EnumDomains(p, mem_ctx, &r);
3117 if (!NT_STATUS_IS_OK(status)) {
3118 printf("EnumDomains failed - %s\n", nt_errstr(status));
3126 static BOOL test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3127 struct policy_handle *handle)
3130 struct samr_Connect r;
3131 struct samr_Connect2 r2;
3132 struct samr_Connect3 r3;
3133 struct samr_Connect4 r4;
3134 struct samr_Connect5 r5;
3135 union samr_ConnectInfo info;
3136 struct policy_handle h;
3137 BOOL ret = True, got_handle = False;
3139 printf("testing samr_Connect\n");
3141 r.in.system_name = 0;
3142 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3143 r.out.connect_handle = &h;
3145 status = dcerpc_samr_Connect(p, mem_ctx, &r);
3146 if (!NT_STATUS_IS_OK(status)) {
3147 printf("Connect failed - %s\n", nt_errstr(status));
3154 printf("testing samr_Connect2\n");
3156 r2.in.system_name = NULL;
3157 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3158 r2.out.connect_handle = &h;
3160 status = dcerpc_samr_Connect2(p, mem_ctx, &r2);
3161 if (!NT_STATUS_IS_OK(status)) {
3162 printf("Connect2 failed - %s\n", nt_errstr(status));
3166 test_samr_handle_Close(p, mem_ctx, handle);
3172 printf("testing samr_Connect3\n");
3174 r3.in.system_name = NULL;
3176 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3177 r3.out.connect_handle = &h;
3179 status = dcerpc_samr_Connect3(p, mem_ctx, &r3);
3180 if (!NT_STATUS_IS_OK(status)) {
3181 printf("Connect3 failed - %s\n", nt_errstr(status));
3185 test_samr_handle_Close(p, mem_ctx, handle);
3191 printf("testing samr_Connect4\n");
3193 r4.in.system_name = "";
3195 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3196 r4.out.connect_handle = &h;
3198 status = dcerpc_samr_Connect4(p, mem_ctx, &r4);
3199 if (!NT_STATUS_IS_OK(status)) {
3200 printf("Connect4 failed - %s\n", nt_errstr(status));
3204 test_samr_handle_Close(p, mem_ctx, handle);
3210 printf("testing samr_Connect5\n");
3212 info.info1.unknown1 = 0;
3213 info.info1.unknown2 = 0;
3215 r5.in.system_name = "";
3216 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3219 r5.out.info = &info;
3220 r5.out.connect_handle = &h;
3222 status = dcerpc_samr_Connect5(p, mem_ctx, &r5);
3223 if (!NT_STATUS_IS_OK(status)) {
3224 printf("Connect5 failed - %s\n", nt_errstr(status));
3228 test_samr_handle_Close(p, mem_ctx, handle);
3238 BOOL torture_rpc_samr(void)
3241 struct dcerpc_pipe *p;
3242 TALLOC_CTX *mem_ctx;
3244 struct policy_handle handle;
3246 mem_ctx = talloc_init("torture_rpc_samr");
3248 status = torture_rpc_connection(mem_ctx,
3252 DCERPC_SAMR_VERSION);
3253 if (!NT_STATUS_IS_OK(status)) {
3254 talloc_free(mem_ctx);
3258 if (!test_Connect(p, mem_ctx, &handle)) {
3262 if (!test_QuerySecurity(p, mem_ctx, &handle)) {
3266 if (!test_EnumDomains(p, mem_ctx, &handle)) {
3270 if (!test_SetDsrmPassword(p, mem_ctx, &handle)) {
3274 if (!test_Shutdown(p, mem_ctx, &handle)) {
3278 if (!test_samr_handle_Close(p, mem_ctx, &handle)) {
3282 talloc_free(mem_ctx);