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_samr_String(struct samr_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 samr_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_samr_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_samr_String(&u.info ## lvl1.field1, value); \
230 TESTCALL(SetUserInfo, s) \
231 TESTCALL(SetUserInfo2, s2) \
232 init_samr_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_WORKSTATION);
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);
392 generate a random password for password change tests
394 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
396 size_t len = MAX(8, min_len) + (random() % 6);
397 char *s = generate_random_str(mem_ctx, len);
398 printf("Generated password '%s'\n", s);
402 static BOOL test_SetUserPass(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
403 struct policy_handle *handle, char **password)
406 struct samr_SetUserInfo s;
407 union samr_UserInfo u;
409 DATA_BLOB session_key;
411 struct samr_GetUserPwInfo pwp;
412 int policy_min_pw_len = 0;
413 pwp.in.user_handle = handle;
415 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
416 if (NT_STATUS_IS_OK(status)) {
417 policy_min_pw_len = pwp.out.info.min_password_length;
419 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
421 s.in.user_handle = handle;
425 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
426 /* w2k3 ignores this length */
427 u.info24.pw_len = strlen_m(newpass) * 2;
429 status = dcerpc_fetch_session_key(p, &session_key);
430 if (!NT_STATUS_IS_OK(status)) {
431 printf("SetUserInfo level %u - no session key - %s\n",
432 s.in.level, nt_errstr(status));
436 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
438 printf("Testing SetUserInfo level 24 (set password)\n");
440 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
441 if (!NT_STATUS_IS_OK(status)) {
442 printf("SetUserInfo level %u failed - %s\n",
443 s.in.level, nt_errstr(status));
453 static BOOL test_SetUserPass_23(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
454 struct policy_handle *handle, uint32_t fields_present,
458 struct samr_SetUserInfo s;
459 union samr_UserInfo u;
461 DATA_BLOB session_key;
463 struct samr_GetUserPwInfo pwp;
464 int policy_min_pw_len = 0;
465 pwp.in.user_handle = handle;
467 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
468 if (NT_STATUS_IS_OK(status)) {
469 policy_min_pw_len = pwp.out.info.min_password_length;
471 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
473 s.in.user_handle = handle;
479 u.info23.info.fields_present = fields_present;
481 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
483 status = dcerpc_fetch_session_key(p, &session_key);
484 if (!NT_STATUS_IS_OK(status)) {
485 printf("SetUserInfo level %u - no session key - %s\n",
486 s.in.level, nt_errstr(status));
490 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
492 printf("Testing SetUserInfo level 23 (set password)\n");
494 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
495 if (!NT_STATUS_IS_OK(status)) {
496 printf("SetUserInfo level %u failed - %s\n",
497 s.in.level, nt_errstr(status));
507 static BOOL test_SetUserPassEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
508 struct policy_handle *handle, char **password)
511 struct samr_SetUserInfo s;
512 union samr_UserInfo u;
514 DATA_BLOB session_key;
515 DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
516 uint8_t confounder[16];
518 struct MD5Context ctx;
519 struct samr_GetUserPwInfo pwp;
520 int policy_min_pw_len = 0;
521 pwp.in.user_handle = handle;
523 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
524 if (NT_STATUS_IS_OK(status)) {
525 policy_min_pw_len = pwp.out.info.min_password_length;
527 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
529 s.in.user_handle = handle;
533 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
534 u.info26.pw_len = strlen(newpass);
536 status = dcerpc_fetch_session_key(p, &session_key);
537 if (!NT_STATUS_IS_OK(status)) {
538 printf("SetUserInfo level %u - no session key - %s\n",
539 s.in.level, nt_errstr(status));
543 generate_random_buffer((uint8_t *)confounder, 16);
546 MD5Update(&ctx, confounder, 16);
547 MD5Update(&ctx, session_key.data, session_key.length);
548 MD5Final(confounded_session_key.data, &ctx);
550 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
551 memcpy(&u.info26.password.data[516], confounder, 16);
553 printf("Testing SetUserInfo level 26 (set password ex)\n");
555 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
556 if (!NT_STATUS_IS_OK(status)) {
557 printf("SetUserInfo level %u failed - %s\n",
558 s.in.level, nt_errstr(status));
567 static BOOL test_SetUserPass_25(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
568 struct policy_handle *handle, uint32_t fields_present,
572 struct samr_SetUserInfo s;
573 union samr_UserInfo u;
575 DATA_BLOB session_key;
576 DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
577 struct MD5Context ctx;
578 uint8_t confounder[16];
580 struct samr_GetUserPwInfo pwp;
581 int policy_min_pw_len = 0;
582 pwp.in.user_handle = handle;
584 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
585 if (NT_STATUS_IS_OK(status)) {
586 policy_min_pw_len = pwp.out.info.min_password_length;
588 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
590 s.in.user_handle = handle;
596 u.info25.info.fields_present = fields_present;
598 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
600 status = dcerpc_fetch_session_key(p, &session_key);
601 if (!NT_STATUS_IS_OK(status)) {
602 printf("SetUserInfo level %u - no session key - %s\n",
603 s.in.level, nt_errstr(status));
607 generate_random_buffer((uint8_t *)confounder, 16);
610 MD5Update(&ctx, confounder, 16);
611 MD5Update(&ctx, session_key.data, session_key.length);
612 MD5Final(confounded_session_key.data, &ctx);
614 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
615 memcpy(&u.info25.password.data[516], confounder, 16);
617 printf("Testing SetUserInfo level 25 (set password ex)\n");
619 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
620 if (!NT_STATUS_IS_OK(status)) {
621 printf("SetUserInfo level %u failed - %s\n",
622 s.in.level, nt_errstr(status));
631 static BOOL test_SetAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
632 struct policy_handle *handle)
635 struct samr_SetAliasInfo r;
636 struct samr_QueryAliasInfo q;
637 uint16_t levels[] = {2, 3};
641 /* Ignoring switch level 1, as that includes the number of members for the alias
642 * and setting this to a wrong value might have negative consequences
645 for (i=0;i<ARRAY_SIZE(levels);i++) {
646 printf("Testing SetAliasInfo level %u\n", levels[i]);
648 r.in.alias_handle = handle;
649 r.in.level = levels[i];
650 r.in.info = talloc(mem_ctx, union samr_AliasInfo);
651 switch (r.in.level) {
652 case 2 : init_samr_String(&r.in.info->name,TEST_ALIASNAME); break;
653 case 3 : init_samr_String(&r.in.info->description,
654 "Test Description, should test I18N as well"); break;
657 status = dcerpc_samr_SetAliasInfo(p, mem_ctx, &r);
658 if (!NT_STATUS_IS_OK(status)) {
659 printf("SetAliasInfo level %u failed - %s\n",
660 levels[i], nt_errstr(status));
664 q.in.alias_handle = handle;
665 q.in.level = levels[i];
667 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &q);
668 if (!NT_STATUS_IS_OK(status)) {
669 printf("QueryAliasInfo level %u failed - %s\n",
670 levels[i], nt_errstr(status));
678 static BOOL test_GetGroupsForUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
679 struct policy_handle *user_handle)
681 struct samr_GetGroupsForUser r;
685 printf("testing GetGroupsForUser\n");
687 r.in.user_handle = user_handle;
689 status = dcerpc_samr_GetGroupsForUser(p, mem_ctx, &r);
690 if (!NT_STATUS_IS_OK(status)) {
691 printf("GetGroupsForUser failed - %s\n",nt_errstr(status));
699 static BOOL test_GetDomPwInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
700 struct samr_String *domain_name)
703 struct samr_GetDomPwInfo r;
706 r.in.domain_name = domain_name;
707 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
709 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
710 if (!NT_STATUS_IS_OK(status)) {
711 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
715 r.in.domain_name->string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
716 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
718 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
719 if (!NT_STATUS_IS_OK(status)) {
720 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
724 r.in.domain_name->string = "\\\\__NONAME__";
725 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
727 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
728 if (!NT_STATUS_IS_OK(status)) {
729 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
733 r.in.domain_name->string = "\\\\Builtin";
734 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
736 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
737 if (!NT_STATUS_IS_OK(status)) {
738 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
746 static BOOL test_GetUserPwInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
747 struct policy_handle *handle)
750 struct samr_GetUserPwInfo r;
753 printf("Testing GetUserPwInfo\n");
755 r.in.user_handle = handle;
757 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &r);
758 if (!NT_STATUS_IS_OK(status)) {
759 printf("GetUserPwInfo failed - %s\n", nt_errstr(status));
766 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
767 struct policy_handle *domain_handle, const char *name,
771 struct samr_LookupNames n;
772 struct samr_String sname[2];
774 init_samr_String(&sname[0], name);
776 n.in.domain_handle = domain_handle;
779 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
780 if (NT_STATUS_IS_OK(status)) {
781 *rid = n.out.rids.ids[0];
786 init_samr_String(&sname[1], "xxNONAMExx");
788 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
789 if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
790 printf("LookupNames[2] failed - %s\n", nt_errstr(status));
794 init_samr_String(&sname[1], "xxNONAMExx");
796 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
797 if (!NT_STATUS_IS_OK(status)) {
798 printf("LookupNames[0] failed - %s\n", nt_errstr(status));
804 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
805 struct policy_handle *domain_handle,
806 const char *name, struct policy_handle *user_handle)
809 struct samr_OpenUser r;
812 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
813 if (!NT_STATUS_IS_OK(status)) {
817 r.in.domain_handle = domain_handle;
818 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
820 r.out.user_handle = user_handle;
821 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
822 if (!NT_STATUS_IS_OK(status)) {
823 printf("OpenUser_byname(%s) failed - %s\n", name, nt_errstr(status));
830 static BOOL test_ChangePasswordNT3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
831 struct policy_handle *handle)
834 struct samr_ChangePasswordUser r;
836 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
837 struct policy_handle user_handle;
838 char *oldpass = "test";
839 char *newpass = "test2";
840 uint8_t old_nt_hash[16], new_nt_hash[16];
841 uint8_t old_lm_hash[16], new_lm_hash[16];
843 status = test_OpenUser_byname(p, mem_ctx, handle, "testuser", &user_handle);
844 if (!NT_STATUS_IS_OK(status)) {
848 printf("Testing ChangePasswordUser for user 'testuser'\n");
850 printf("old password: %s\n", oldpass);
851 printf("new password: %s\n", newpass);
853 E_md4hash(oldpass, old_nt_hash);
854 E_md4hash(newpass, new_nt_hash);
855 E_deshash(oldpass, old_lm_hash);
856 E_deshash(newpass, new_lm_hash);
858 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
859 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
860 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
861 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
862 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
863 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
865 r.in.handle = &user_handle;
867 r.in.old_lm_crypted = &hash1;
868 r.in.new_lm_crypted = &hash2;
870 r.in.old_nt_crypted = &hash3;
871 r.in.new_nt_crypted = &hash4;
872 r.in.cross1_present = 1;
873 r.in.nt_cross = &hash5;
874 r.in.cross2_present = 1;
875 r.in.lm_cross = &hash6;
877 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
878 if (!NT_STATUS_IS_OK(status)) {
879 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
883 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
891 static BOOL test_ChangePasswordUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
892 struct policy_handle *handle, char **password)
895 struct samr_ChangePasswordUser r;
897 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
898 struct policy_handle user_handle;
899 char *oldpass = *password;
900 uint8_t old_nt_hash[16], new_nt_hash[16];
901 uint8_t old_lm_hash[16], new_lm_hash[16];
904 struct samr_GetUserPwInfo pwp;
905 int policy_min_pw_len = 0;
907 status = test_OpenUser_byname(p, mem_ctx, handle, TEST_ACCOUNT_NAME, &user_handle);
908 if (!NT_STATUS_IS_OK(status)) {
911 pwp.in.user_handle = &user_handle;
913 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
914 if (NT_STATUS_IS_OK(status)) {
915 policy_min_pw_len = pwp.out.info.min_password_length;
917 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
919 printf("Testing ChangePasswordUser\n");
921 E_md4hash(oldpass, old_nt_hash);
922 E_md4hash(newpass, new_nt_hash);
923 E_deshash(oldpass, old_lm_hash);
924 E_deshash(newpass, new_lm_hash);
926 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
927 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
928 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
929 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
930 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
931 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
933 r.in.user_handle = &user_handle;
935 r.in.old_lm_crypted = &hash1;
936 r.in.new_lm_crypted = &hash2;
938 r.in.old_nt_crypted = &hash3;
939 r.in.new_nt_crypted = &hash4;
940 r.in.cross1_present = 1;
941 r.in.nt_cross = &hash5;
942 r.in.cross2_present = 1;
943 r.in.lm_cross = &hash6;
945 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
946 if (!NT_STATUS_IS_OK(status)) {
947 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
953 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
961 static BOOL test_OemChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
962 struct policy_handle *handle, char **password)
965 struct samr_OemChangePasswordUser2 r;
967 struct samr_Password lm_verifier;
968 struct samr_CryptPassword lm_pass;
969 struct samr_AsciiName server, account;
970 char *oldpass = *password;
972 uint8_t old_lm_hash[16], new_lm_hash[16];
974 struct samr_GetDomPwInfo dom_pw_info;
975 int policy_min_pw_len = 0;
977 struct samr_String domain_name;
978 domain_name.string = "";
979 dom_pw_info.in.domain_name = &domain_name;
981 printf("Testing OemChangePasswordUser2\n");
983 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &dom_pw_info);
984 if (NT_STATUS_IS_OK(status)) {
985 policy_min_pw_len = dom_pw_info.out.info.min_password_length;
988 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
990 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
991 account.string = TEST_ACCOUNT_NAME;
993 E_deshash(oldpass, old_lm_hash);
994 E_deshash(newpass, new_lm_hash);
996 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
997 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
998 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1000 r.in.server = &server;
1001 r.in.account = &account;
1002 r.in.password = &lm_pass;
1003 r.in.hash = &lm_verifier;
1005 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1006 if (!NT_STATUS_IS_OK(status)) {
1007 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
1010 *password = newpass;
1017 static BOOL test_ChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1018 struct policy_handle *handle, char **password)
1021 struct samr_ChangePasswordUser2 r;
1023 struct samr_String server, account;
1024 struct samr_CryptPassword nt_pass, lm_pass;
1025 struct samr_Password nt_verifier, lm_verifier;
1026 char *oldpass = *password;
1028 uint8_t old_nt_hash[16], new_nt_hash[16];
1029 uint8_t old_lm_hash[16], new_lm_hash[16];
1031 struct samr_GetDomPwInfo dom_pw_info;
1032 int policy_min_pw_len = 0;
1034 struct samr_String domain_name;
1035 domain_name.string = "";
1036 dom_pw_info.in.domain_name = &domain_name;
1038 printf("Testing ChangePasswordUser2\n");
1040 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &dom_pw_info);
1041 if (NT_STATUS_IS_OK(status)) {
1042 policy_min_pw_len = dom_pw_info.out.info.min_password_length;
1045 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1047 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1048 init_samr_String(&account, TEST_ACCOUNT_NAME);
1050 E_md4hash(oldpass, old_nt_hash);
1051 E_md4hash(newpass, new_nt_hash);
1053 E_deshash(oldpass, old_lm_hash);
1054 E_deshash(newpass, new_lm_hash);
1056 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
1057 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1058 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1060 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1061 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1062 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1064 r.in.server = &server;
1065 r.in.account = &account;
1066 r.in.nt_password = &nt_pass;
1067 r.in.nt_verifier = &nt_verifier;
1069 r.in.lm_password = &lm_pass;
1070 r.in.lm_verifier = &lm_verifier;
1072 status = dcerpc_samr_ChangePasswordUser2(p, mem_ctx, &r);
1073 if (!NT_STATUS_IS_OK(status)) {
1074 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
1077 *password = newpass;
1084 static BOOL test_ChangePasswordUser3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1085 struct policy_handle *handle,
1086 int policy_min_pw_len,
1090 struct samr_ChangePasswordUser3 r;
1092 struct samr_String server, account;
1093 struct samr_CryptPassword nt_pass, lm_pass;
1094 struct samr_Password nt_verifier, lm_verifier;
1095 char *oldpass = *password;
1096 char *newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1097 uint8_t old_nt_hash[16], new_nt_hash[16];
1098 uint8_t old_lm_hash[16], new_lm_hash[16];
1100 printf("Testing ChangePasswordUser3\n");
1102 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1103 init_samr_String(&account, TEST_ACCOUNT_NAME);
1105 E_md4hash(oldpass, old_nt_hash);
1106 E_md4hash(newpass, new_nt_hash);
1108 E_deshash(oldpass, old_lm_hash);
1109 E_deshash(newpass, new_lm_hash);
1111 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1112 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1113 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1115 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1116 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1117 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1119 r.in.server = &server;
1120 r.in.account = &account;
1121 r.in.nt_password = &nt_pass;
1122 r.in.nt_verifier = &nt_verifier;
1124 r.in.lm_password = &lm_pass;
1125 r.in.lm_verifier = &lm_verifier;
1126 r.in.password3 = NULL;
1128 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1129 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1130 && !policy_min_pw_len) {
1131 if (r.out.dominfo) {
1132 policy_min_pw_len = r.out.dominfo->min_password_length;
1134 if (policy_min_pw_len) /* try again with the right min password length */ {
1135 ret = test_ChangePasswordUser3(p, mem_ctx, handle, policy_min_pw_len, password);
1137 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
1140 } else if (!NT_STATUS_IS_OK(status)) {
1141 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
1144 *password = newpass;
1151 static BOOL test_GetMembersInAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1152 struct policy_handle *alias_handle)
1154 struct samr_GetMembersInAlias r;
1155 struct lsa_SidArray sids;
1159 printf("Testing GetMembersInAlias\n");
1161 r.in.alias_handle = alias_handle;
1164 status = dcerpc_samr_GetMembersInAlias(p, mem_ctx, &r);
1165 if (!NT_STATUS_IS_OK(status)) {
1166 printf("GetMembersInAlias failed - %s\n",
1174 static BOOL test_AddMemberToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1175 struct policy_handle *alias_handle,
1176 const struct dom_sid *domain_sid)
1178 struct samr_AddAliasMember r;
1179 struct samr_DeleteAliasMember d;
1182 struct dom_sid *sid;
1184 sid = dom_sid_add_rid(mem_ctx, domain_sid, 512);
1186 printf("testing AddAliasMember\n");
1187 r.in.alias_handle = alias_handle;
1190 status = dcerpc_samr_AddAliasMember(p, mem_ctx, &r);
1191 if (!NT_STATUS_IS_OK(status)) {
1192 printf("AddAliasMember failed - %s\n", nt_errstr(status));
1196 d.in.alias_handle = alias_handle;
1199 status = dcerpc_samr_DeleteAliasMember(p, mem_ctx, &d);
1200 if (!NT_STATUS_IS_OK(status)) {
1201 printf("DelAliasMember failed - %s\n", nt_errstr(status));
1208 static BOOL test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1209 struct policy_handle *alias_handle)
1211 struct samr_AddMultipleMembersToAlias a;
1212 struct samr_RemoveMultipleMembersFromAlias r;
1215 struct lsa_SidArray sids;
1217 printf("testing AddMultipleMembersToAlias\n");
1218 a.in.alias_handle = alias_handle;
1222 sids.sids = talloc_array(mem_ctx, struct lsa_SidPtr, 3);
1224 sids.sids[0].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-1");
1225 sids.sids[1].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-2");
1226 sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-3");
1228 status = dcerpc_samr_AddMultipleMembersToAlias(p, mem_ctx, &a);
1229 if (!NT_STATUS_IS_OK(status)) {
1230 printf("AddMultipleMembersToAlias failed - %s\n", nt_errstr(status));
1235 printf("testing RemoveMultipleMembersFromAlias\n");
1236 r.in.alias_handle = alias_handle;
1239 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1240 if (!NT_STATUS_IS_OK(status)) {
1241 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1245 /* strange! removing twice doesn't give any error */
1246 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1247 if (!NT_STATUS_IS_OK(status)) {
1248 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1252 /* but removing an alias that isn't there does */
1253 sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-4");
1255 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1256 if (!NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_NOT_FOUND, status)) {
1257 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1264 static BOOL test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1265 struct policy_handle *user_handle)
1267 struct samr_TestPrivateFunctionsUser r;
1271 printf("Testing TestPrivateFunctionsUser\n");
1273 r.in.user_handle = user_handle;
1275 status = dcerpc_samr_TestPrivateFunctionsUser(p, mem_ctx, &r);
1276 if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
1277 printf("TestPrivateFunctionsUser failed - %s\n", nt_errstr(status));
1285 static BOOL test_user_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1286 struct policy_handle *handle, uint32_t base_acct_flags,
1287 const char *base_acct_name)
1291 if (!test_QuerySecurity(p, mem_ctx, handle)) {
1295 if (!test_QueryUserInfo(p, mem_ctx, handle)) {
1299 if (!test_QueryUserInfo2(p, mem_ctx, handle)) {
1303 if (!test_SetUserInfo(p, mem_ctx, handle, base_acct_flags,
1308 if (!test_GetUserPwInfo(p, mem_ctx, handle)) {
1312 if (!test_TestPrivateFunctionsUser(p, mem_ctx, handle)) {
1319 static BOOL test_alias_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1320 struct policy_handle *alias_handle,
1321 const struct dom_sid *domain_sid)
1325 if (!test_QuerySecurity(p, mem_ctx, alias_handle)) {
1329 if (!test_QueryAliasInfo(p, mem_ctx, alias_handle)) {
1333 if (!test_SetAliasInfo(p, mem_ctx, alias_handle)) {
1337 if (!test_AddMemberToAlias(p, mem_ctx, alias_handle, domain_sid)) {
1341 if (!test_AddMultipleMembersToAlias(p, mem_ctx, alias_handle)) {
1349 BOOL test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1350 struct policy_handle *handle, const char *name)
1353 struct samr_DeleteUser d;
1354 struct policy_handle user_handle;
1357 status = test_LookupName(p, mem_ctx, handle, name, &rid);
1358 if (!NT_STATUS_IS_OK(status)) {
1362 status = test_OpenUser_byname(p, mem_ctx, handle, name, &user_handle);
1363 if (!NT_STATUS_IS_OK(status)) {
1367 d.in.user_handle = &user_handle;
1368 d.out.user_handle = &user_handle;
1369 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
1370 if (!NT_STATUS_IS_OK(status)) {
1377 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
1382 static BOOL test_DeleteGroup_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1383 struct policy_handle *handle, const char *name)
1386 struct samr_OpenGroup r;
1387 struct samr_DeleteDomainGroup d;
1388 struct policy_handle group_handle;
1391 status = test_LookupName(p, mem_ctx, handle, name, &rid);
1392 if (!NT_STATUS_IS_OK(status)) {
1396 r.in.domain_handle = handle;
1397 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1399 r.out.group_handle = &group_handle;
1400 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
1401 if (!NT_STATUS_IS_OK(status)) {
1405 d.in.group_handle = &group_handle;
1406 d.out.group_handle = &group_handle;
1407 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
1408 if (!NT_STATUS_IS_OK(status)) {
1415 printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
1420 static BOOL test_DeleteAlias_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1421 struct policy_handle *domain_handle, const char *name)
1424 struct samr_OpenAlias r;
1425 struct samr_DeleteDomAlias d;
1426 struct policy_handle alias_handle;
1429 printf("testing DeleteAlias_byname\n");
1431 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
1432 if (!NT_STATUS_IS_OK(status)) {
1436 r.in.domain_handle = domain_handle;
1437 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1439 r.out.alias_handle = &alias_handle;
1440 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
1441 if (!NT_STATUS_IS_OK(status)) {
1445 d.in.alias_handle = &alias_handle;
1446 d.out.alias_handle = &alias_handle;
1447 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
1448 if (!NT_STATUS_IS_OK(status)) {
1455 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
1459 static BOOL test_DeleteAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1460 struct policy_handle *alias_handle)
1462 struct samr_DeleteDomAlias d;
1465 printf("Testing DeleteAlias\n");
1467 d.in.alias_handle = alias_handle;
1468 d.out.alias_handle = alias_handle;
1470 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
1471 if (!NT_STATUS_IS_OK(status)) {
1472 printf("DeleteAlias failed - %s\n", nt_errstr(status));
1479 static BOOL test_CreateAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1480 struct policy_handle *domain_handle,
1481 struct policy_handle *alias_handle,
1482 const struct dom_sid *domain_sid)
1485 struct samr_CreateDomAlias r;
1486 struct samr_String name;
1490 init_samr_String(&name, TEST_ALIASNAME);
1491 r.in.domain_handle = domain_handle;
1492 r.in.aliasname = &name;
1493 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1494 r.out.alias_handle = alias_handle;
1497 printf("Testing CreateAlias (%s)\n", r.in.aliasname->string);
1499 status = dcerpc_samr_CreateDomAlias(p, mem_ctx, &r);
1501 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1502 printf("Server refused create of '%s'\n", r.in.aliasname->string);
1506 if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
1507 if (!test_DeleteAlias_byname(p, mem_ctx, domain_handle, r.in.aliasname->string)) {
1510 status = dcerpc_samr_CreateDomAlias(p, mem_ctx, &r);
1513 if (!NT_STATUS_IS_OK(status)) {
1514 printf("CreateAlias failed - %s\n", nt_errstr(status));
1518 if (!test_alias_ops(p, mem_ctx, alias_handle, domain_sid)) {
1525 static BOOL test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1526 struct policy_handle *domain_handle, char **password)
1534 if (!test_ChangePasswordUser(p, mem_ctx, domain_handle, password)) {
1538 if (!test_ChangePasswordUser2(p, mem_ctx, domain_handle, password)) {
1542 if (!test_OemChangePasswordUser2(p, mem_ctx, domain_handle, password)) {
1546 /* we change passwords twice - this has the effect of verifying
1547 they were changed correctly for the final call */
1548 if (!test_ChangePasswordUser3(p, mem_ctx, domain_handle, 0, password)) {
1552 if (!test_ChangePasswordUser3(p, mem_ctx, domain_handle, 0, password)) {
1559 static BOOL test_CreateUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1560 struct policy_handle *domain_handle, struct policy_handle *user_handle)
1563 struct samr_CreateUser r;
1564 struct samr_QueryUserInfo q;
1566 char *password = NULL;
1569 const uint32_t password_fields[] = {
1570 SAMR_FIELD_PASSWORD,
1571 SAMR_FIELD_PASSWORD2,
1572 SAMR_FIELD_PASSWORD | SAMR_FIELD_PASSWORD2,
1576 /* This call creates a 'normal' account - check that it really does */
1577 const uint32_t acct_flags = ACB_NORMAL;
1578 struct samr_String name;
1581 init_samr_String(&name, TEST_ACCOUNT_NAME);
1583 r.in.domain_handle = domain_handle;
1584 r.in.account_name = &name;
1585 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1586 r.out.user_handle = user_handle;
1589 printf("Testing CreateUser(%s)\n", r.in.account_name->string);
1591 status = dcerpc_samr_CreateUser(p, mem_ctx, &r);
1593 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1594 printf("Server refused create of '%s'\n", r.in.account_name->string);
1595 ZERO_STRUCTP(user_handle);
1599 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
1600 if (!test_DeleteUser_byname(p, mem_ctx, domain_handle, r.in.account_name->string)) {
1603 status = dcerpc_samr_CreateUser(p, mem_ctx, &r);
1605 if (!NT_STATUS_IS_OK(status)) {
1606 printf("CreateUser failed - %s\n", nt_errstr(status));
1610 q.in.user_handle = user_handle;
1613 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
1614 if (!NT_STATUS_IS_OK(status)) {
1615 printf("QueryUserInfo level %u failed - %s\n",
1616 q.in.level, nt_errstr(status));
1619 if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
1620 printf("QuerUserInfo level 16 failed, it returned 0x%08x (%u) when we expected flags of 0x%08x (%u)\n",
1621 q.out.info->info16.acct_flags, q.out.info->info16.acct_flags,
1622 acct_flags, acct_flags);
1627 if (!test_user_ops(p, mem_ctx, user_handle, acct_flags, name.string)) {
1631 if (!test_SetUserPass(p, mem_ctx, user_handle, &password)) {
1635 for (i = 0; password_fields[i]; i++) {
1636 if (!test_SetUserPass_23(p, mem_ctx, user_handle, password_fields[i], &password)) {
1640 /* check it was set right */
1641 if (!test_ChangePasswordUser3(p, mem_ctx, domain_handle, 0, &password)) {
1646 for (i = 0; password_fields[i]; i++) {
1647 if (!test_SetUserPass_25(p, mem_ctx, user_handle, password_fields[i], &password)) {
1651 /* check it was set right */
1652 if (!test_ChangePasswordUser3(p, mem_ctx, domain_handle, 0, &password)) {
1657 if (!test_SetUserPassEx(p, mem_ctx, user_handle, &password)) {
1661 if (!test_ChangePassword(p, mem_ctx, domain_handle, &password)) {
1669 static BOOL test_DeleteUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1670 struct policy_handle *user_handle)
1672 struct samr_DeleteUser d;
1676 printf("Testing DeleteUser\n");
1678 d.in.user_handle = user_handle;
1679 d.out.user_handle = user_handle;
1681 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
1682 if (!NT_STATUS_IS_OK(status)) {
1683 printf("DeleteUser failed - %s\n", nt_errstr(status));
1690 static BOOL test_CreateUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1691 struct policy_handle *handle)
1694 struct samr_CreateUser2 r;
1695 struct samr_QueryUserInfo q;
1696 struct samr_DeleteUser d;
1697 struct policy_handle user_handle;
1699 struct samr_String name;
1704 uint32_t acct_flags;
1705 const char *account_name;
1707 } account_types[] = {
1708 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
1709 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1710 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1711 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
1712 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1713 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1714 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
1715 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1716 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1717 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
1718 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
1719 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
1720 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1721 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1722 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
1725 for (i = 0; account_types[i].account_name; i++) {
1726 uint32_t acct_flags = account_types[i].acct_flags;
1727 uint32_t access_granted;
1729 init_samr_String(&name, account_types[i].account_name);
1731 r.in.domain_handle = handle;
1732 r.in.account_name = &name;
1733 r.in.acct_flags = acct_flags;
1734 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1735 r.out.user_handle = &user_handle;
1736 r.out.access_granted = &access_granted;
1739 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
1741 status = dcerpc_samr_CreateUser2(p, mem_ctx, &r);
1743 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1744 printf("Server refused create of '%s'\n", r.in.account_name->string);
1747 } else if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
1748 if (!test_DeleteUser_byname(p, mem_ctx, handle, r.in.account_name->string)) {
1751 status = dcerpc_samr_CreateUser2(p, mem_ctx, &r);
1754 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
1755 printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
1756 nt_errstr(status), nt_errstr(account_types[i].nt_status));
1760 if (NT_STATUS_IS_OK(status)) {
1761 q.in.user_handle = &user_handle;
1764 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
1765 if (!NT_STATUS_IS_OK(status)) {
1766 printf("QueryUserInfo level %u failed - %s\n",
1767 q.in.level, nt_errstr(status));
1770 if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
1771 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
1772 q.out.info->info16.acct_flags,
1778 if (!test_user_ops(p, mem_ctx, &user_handle, acct_flags, name.string)) {
1782 printf("Testing DeleteUser (createuser2 test)\n");
1784 d.in.user_handle = &user_handle;
1785 d.out.user_handle = &user_handle;
1787 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
1788 if (!NT_STATUS_IS_OK(status)) {
1789 printf("DeleteUser failed - %s\n", nt_errstr(status));
1798 static BOOL test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1799 struct policy_handle *handle)
1802 struct samr_QueryAliasInfo r;
1803 uint16_t levels[] = {1, 2, 3};
1807 for (i=0;i<ARRAY_SIZE(levels);i++) {
1808 printf("Testing QueryAliasInfo level %u\n", levels[i]);
1810 r.in.alias_handle = handle;
1811 r.in.level = levels[i];
1813 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
1814 if (!NT_STATUS_IS_OK(status)) {
1815 printf("QueryAliasInfo level %u failed - %s\n",
1816 levels[i], nt_errstr(status));
1824 static BOOL test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1825 struct policy_handle *handle)
1828 struct samr_QueryGroupInfo r;
1829 uint16_t levels[] = {1, 2, 3, 4, 5};
1833 for (i=0;i<ARRAY_SIZE(levels);i++) {
1834 printf("Testing QueryGroupInfo level %u\n", levels[i]);
1836 r.in.group_handle = handle;
1837 r.in.level = levels[i];
1839 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
1840 if (!NT_STATUS_IS_OK(status)) {
1841 printf("QueryGroupInfo level %u failed - %s\n",
1842 levels[i], nt_errstr(status));
1850 static BOOL test_QueryGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1851 struct policy_handle *handle)
1854 struct samr_QueryGroupMember r;
1857 printf("Testing QueryGroupMember\n");
1859 r.in.group_handle = handle;
1861 status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &r);
1862 if (!NT_STATUS_IS_OK(status)) {
1863 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
1871 static BOOL test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1872 struct policy_handle *handle)
1875 struct samr_QueryGroupInfo r;
1876 struct samr_SetGroupInfo s;
1877 uint16_t levels[] = {1, 2, 3, 4};
1878 uint16_t set_ok[] = {0, 1, 1, 1};
1882 for (i=0;i<ARRAY_SIZE(levels);i++) {
1883 printf("Testing QueryGroupInfo level %u\n", levels[i]);
1885 r.in.group_handle = handle;
1886 r.in.level = levels[i];
1888 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
1889 if (!NT_STATUS_IS_OK(status)) {
1890 printf("QueryGroupInfo level %u failed - %s\n",
1891 levels[i], nt_errstr(status));
1895 printf("Testing SetGroupInfo level %u\n", levels[i]);
1897 s.in.group_handle = handle;
1898 s.in.level = levels[i];
1899 s.in.info = r.out.info;
1902 /* disabled this, as it changes the name only from the point of view of samr,
1903 but leaves the name from the point of view of w2k3 internals (and ldap). This means
1904 the name is still reserved, so creating the old name fails, but deleting by the old name
1906 if (s.in.level == 2) {
1907 init_samr_String(&s.in.info->string, "NewName");
1911 if (s.in.level == 4) {
1912 init_samr_String(&s.in.info->description, "test description");
1915 status = dcerpc_samr_SetGroupInfo(p, mem_ctx, &s);
1917 if (!NT_STATUS_IS_OK(status)) {
1918 printf("SetGroupInfo level %u failed - %s\n",
1919 r.in.level, nt_errstr(status));
1924 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
1925 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
1926 r.in.level, nt_errstr(status));
1936 static BOOL test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1937 struct policy_handle *handle)
1940 struct samr_QueryUserInfo r;
1941 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
1942 11, 12, 13, 14, 16, 17, 20, 21};
1946 for (i=0;i<ARRAY_SIZE(levels);i++) {
1947 printf("Testing QueryUserInfo level %u\n", levels[i]);
1949 r.in.user_handle = handle;
1950 r.in.level = levels[i];
1952 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
1953 if (!NT_STATUS_IS_OK(status)) {
1954 printf("QueryUserInfo level %u failed - %s\n",
1955 levels[i], nt_errstr(status));
1963 static BOOL test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1964 struct policy_handle *handle)
1967 struct samr_QueryUserInfo2 r;
1968 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
1969 11, 12, 13, 14, 16, 17, 20, 21};
1973 for (i=0;i<ARRAY_SIZE(levels);i++) {
1974 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
1976 r.in.user_handle = handle;
1977 r.in.level = levels[i];
1979 status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r);
1980 if (!NT_STATUS_IS_OK(status)) {
1981 printf("QueryUserInfo2 level %u failed - %s\n",
1982 levels[i], nt_errstr(status));
1990 static BOOL test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1991 struct policy_handle *handle, uint32_t rid)
1994 struct samr_OpenUser r;
1995 struct policy_handle user_handle;
1998 printf("Testing OpenUser(%u)\n", rid);
2000 r.in.domain_handle = handle;
2001 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2003 r.out.user_handle = &user_handle;
2005 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
2006 if (!NT_STATUS_IS_OK(status)) {
2007 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
2011 if (!test_QuerySecurity(p, mem_ctx, &user_handle)) {
2015 if (!test_QueryUserInfo(p, mem_ctx, &user_handle)) {
2019 if (!test_QueryUserInfo2(p, mem_ctx, &user_handle)) {
2023 if (!test_GetUserPwInfo(p, mem_ctx, &user_handle)) {
2027 if (!test_GetGroupsForUser(p,mem_ctx, &user_handle)) {
2031 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
2038 static BOOL test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2039 struct policy_handle *handle, uint32_t rid)
2042 struct samr_OpenGroup r;
2043 struct policy_handle group_handle;
2046 printf("Testing OpenGroup(%u)\n", rid);
2048 r.in.domain_handle = handle;
2049 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2051 r.out.group_handle = &group_handle;
2053 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
2054 if (!NT_STATUS_IS_OK(status)) {
2055 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
2059 if (!test_QuerySecurity(p, mem_ctx, &group_handle)) {
2063 if (!test_QueryGroupInfo(p, mem_ctx, &group_handle)) {
2067 if (!test_QueryGroupMember(p, mem_ctx, &group_handle)) {
2071 if (!test_samr_handle_Close(p, mem_ctx, &group_handle)) {
2078 static BOOL test_OpenAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2079 struct policy_handle *handle, uint32_t rid)
2082 struct samr_OpenAlias r;
2083 struct policy_handle alias_handle;
2086 printf("Testing OpenAlias(%u)\n", rid);
2088 r.in.domain_handle = handle;
2089 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2091 r.out.alias_handle = &alias_handle;
2093 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
2094 if (!NT_STATUS_IS_OK(status)) {
2095 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
2099 if (!test_QuerySecurity(p, mem_ctx, &alias_handle)) {
2103 if (!test_QueryAliasInfo(p, mem_ctx, &alias_handle)) {
2107 if (!test_GetMembersInAlias(p, mem_ctx, &alias_handle)) {
2111 if (!test_samr_handle_Close(p, mem_ctx, &alias_handle)) {
2118 static BOOL test_EnumDomainUsers(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2119 struct policy_handle *handle)
2122 struct samr_EnumDomainUsers r;
2123 uint32_t resume_handle=0;
2126 struct samr_LookupNames n;
2127 struct samr_LookupRids lr ;
2129 printf("Testing EnumDomainUsers\n");
2131 r.in.domain_handle = handle;
2132 r.in.resume_handle = &resume_handle;
2133 r.in.acct_flags = 0;
2134 r.in.max_size = (uint32_t)-1;
2135 r.out.resume_handle = &resume_handle;
2137 status = dcerpc_samr_EnumDomainUsers(p, mem_ctx, &r);
2138 if (!NT_STATUS_IS_OK(status)) {
2139 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
2147 if (r.out.sam->count == 0) {
2151 for (i=0;i<r.out.sam->count;i++) {
2152 if (!test_OpenUser(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
2157 printf("Testing LookupNames\n");
2158 n.in.domain_handle = handle;
2159 n.in.num_names = r.out.sam->count;
2160 n.in.names = talloc_array(mem_ctx, struct samr_String, r.out.sam->count);
2161 for (i=0;i<r.out.sam->count;i++) {
2162 n.in.names[i] = r.out.sam->entries[i].name;
2164 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
2165 if (!NT_STATUS_IS_OK(status)) {
2166 printf("LookupNames failed - %s\n", nt_errstr(status));
2171 printf("Testing LookupRids\n");
2172 lr.in.domain_handle = handle;
2173 lr.in.num_rids = r.out.sam->count;
2174 lr.in.rids = talloc_array(mem_ctx, uint32_t, r.out.sam->count);
2175 for (i=0;i<r.out.sam->count;i++) {
2176 lr.in.rids[i] = r.out.sam->entries[i].idx;
2178 status = dcerpc_samr_LookupRids(p, mem_ctx, &lr);
2179 if (!NT_STATUS_IS_OK(status)) {
2180 printf("LookupRids failed - %s\n", nt_errstr(status));
2188 try blasting the server with a bunch of sync requests
2190 static BOOL test_EnumDomainUsers_async(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2191 struct policy_handle *handle)
2194 struct samr_EnumDomainUsers r;
2195 uint32_t resume_handle=0;
2197 #define ASYNC_COUNT 100
2198 struct rpc_request *req[ASYNC_COUNT];
2200 if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
2201 printf("samr async test disabled - enable dangerous tests to use\n");
2205 printf("Testing EnumDomainUsers_async\n");
2207 r.in.domain_handle = handle;
2208 r.in.resume_handle = &resume_handle;
2209 r.in.acct_flags = 0;
2210 r.in.max_size = (uint32_t)-1;
2211 r.out.resume_handle = &resume_handle;
2213 for (i=0;i<ASYNC_COUNT;i++) {
2214 req[i] = dcerpc_samr_EnumDomainUsers_send(p, mem_ctx, &r);
2217 for (i=0;i<ASYNC_COUNT;i++) {
2218 status = dcerpc_ndr_request_recv(req[i]);
2219 if (!NT_STATUS_IS_OK(status)) {
2220 printf("EnumDomainUsers[%d] failed - %s\n",
2221 i, nt_errstr(status));
2226 printf("%d async requests OK\n", i);
2231 static BOOL test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2232 struct policy_handle *handle)
2235 struct samr_EnumDomainGroups r;
2236 uint32_t resume_handle=0;
2240 printf("Testing EnumDomainGroups\n");
2242 r.in.domain_handle = handle;
2243 r.in.resume_handle = &resume_handle;
2244 r.in.max_size = (uint32_t)-1;
2245 r.out.resume_handle = &resume_handle;
2247 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
2248 if (!NT_STATUS_IS_OK(status)) {
2249 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
2257 for (i=0;i<r.out.sam->count;i++) {
2258 if (!test_OpenGroup(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
2266 static BOOL test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2267 struct policy_handle *handle)
2270 struct samr_EnumDomainAliases r;
2271 uint32_t resume_handle=0;
2275 printf("Testing EnumDomainAliases\n");
2277 r.in.domain_handle = handle;
2278 r.in.resume_handle = &resume_handle;
2279 r.in.acct_flags = (uint32_t)-1;
2280 r.out.resume_handle = &resume_handle;
2282 status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
2283 if (!NT_STATUS_IS_OK(status)) {
2284 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
2292 for (i=0;i<r.out.sam->count;i++) {
2293 if (!test_OpenAlias(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
2301 static BOOL test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2302 struct policy_handle *handle)
2305 struct samr_GetDisplayEnumerationIndex r;
2307 uint16_t levels[] = {1, 2, 3, 4, 5};
2308 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
2311 for (i=0;i<ARRAY_SIZE(levels);i++) {
2312 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
2314 r.in.domain_handle = handle;
2315 r.in.level = levels[i];
2316 init_samr_String(&r.in.name, TEST_ACCOUNT_NAME);
2318 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
2321 !NT_STATUS_IS_OK(status) &&
2322 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2323 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
2324 levels[i], nt_errstr(status));
2328 init_samr_String(&r.in.name, "zzzzzzzz");
2330 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
2332 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2333 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
2334 levels[i], nt_errstr(status));
2342 static BOOL test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2343 struct policy_handle *handle)
2346 struct samr_GetDisplayEnumerationIndex2 r;
2348 uint16_t levels[] = {1, 2, 3, 4, 5};
2349 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
2352 for (i=0;i<ARRAY_SIZE(levels);i++) {
2353 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
2355 r.in.domain_handle = handle;
2356 r.in.level = levels[i];
2357 init_samr_String(&r.in.name, TEST_ACCOUNT_NAME);
2359 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
2361 !NT_STATUS_IS_OK(status) &&
2362 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2363 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
2364 levels[i], nt_errstr(status));
2368 init_samr_String(&r.in.name, "zzzzzzzz");
2370 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
2371 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2372 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
2373 levels[i], nt_errstr(status));
2381 static BOOL test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2382 struct policy_handle *handle)
2385 struct samr_QueryDisplayInfo r;
2387 uint16_t levels[] = {1, 2, 3, 4, 5};
2390 for (i=0;i<ARRAY_SIZE(levels);i++) {
2391 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
2393 r.in.domain_handle = handle;
2394 r.in.level = levels[i];
2396 r.in.max_entries = 1000;
2397 r.in.buf_size = (uint32_t)-1;
2399 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
2400 if (!NT_STATUS_IS_OK(status)) {
2401 printf("QueryDisplayInfo level %u failed - %s\n",
2402 levels[i], nt_errstr(status));
2410 static BOOL test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2411 struct policy_handle *handle)
2414 struct samr_QueryDisplayInfo2 r;
2416 uint16_t levels[] = {1, 2, 3, 4, 5};
2419 for (i=0;i<ARRAY_SIZE(levels);i++) {
2420 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
2422 r.in.domain_handle = handle;
2423 r.in.level = levels[i];
2425 r.in.max_entries = 1000;
2426 r.in.buf_size = (uint32_t)-1;
2428 status = dcerpc_samr_QueryDisplayInfo2(p, mem_ctx, &r);
2429 if (!NT_STATUS_IS_OK(status)) {
2430 printf("QueryDisplayInfo2 level %u failed - %s\n",
2431 levels[i], nt_errstr(status));
2439 static BOOL test_QueryDisplayInfo3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2440 struct policy_handle *handle)
2443 struct samr_QueryDisplayInfo3 r;
2445 uint16_t levels[] = {1, 2, 3, 4, 5};
2448 for (i=0;i<ARRAY_SIZE(levels);i++) {
2449 printf("Testing QueryDisplayInfo3 level %u\n", levels[i]);
2451 r.in.domain_handle = handle;
2452 r.in.level = levels[i];
2454 r.in.max_entries = 1000;
2455 r.in.buf_size = (uint32_t)-1;
2457 status = dcerpc_samr_QueryDisplayInfo3(p, mem_ctx, &r);
2458 if (!NT_STATUS_IS_OK(status)) {
2459 printf("QueryDisplayInfo3 level %u failed - %s\n",
2460 levels[i], nt_errstr(status));
2468 static BOOL test_QueryDomainInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2469 struct policy_handle *handle)
2472 struct samr_QueryDomainInfo r;
2473 struct samr_SetDomainInfo s;
2474 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
2475 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
2479 for (i=0;i<ARRAY_SIZE(levels);i++) {
2480 printf("Testing QueryDomainInfo level %u\n", levels[i]);
2482 r.in.domain_handle = handle;
2483 r.in.level = levels[i];
2485 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2486 if (!NT_STATUS_IS_OK(status)) {
2487 printf("QueryDomainInfo level %u failed - %s\n",
2488 r.in.level, nt_errstr(status));
2493 printf("Testing SetDomainInfo level %u\n", levels[i]);
2495 s.in.domain_handle = handle;
2496 s.in.level = levels[i];
2497 s.in.info = r.out.info;
2499 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2501 if (!NT_STATUS_IS_OK(status)) {
2502 printf("SetDomainInfo level %u failed - %s\n",
2503 r.in.level, nt_errstr(status));
2508 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
2509 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
2510 r.in.level, nt_errstr(status));
2516 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2517 if (!NT_STATUS_IS_OK(status)) {
2518 printf("QueryDomainInfo level %u failed - %s\n",
2519 r.in.level, nt_errstr(status));
2529 static BOOL test_QueryDomainInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2530 struct policy_handle *handle)
2533 struct samr_QueryDomainInfo2 r;
2534 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
2538 for (i=0;i<ARRAY_SIZE(levels);i++) {
2539 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
2541 r.in.domain_handle = handle;
2542 r.in.level = levels[i];
2544 status = dcerpc_samr_QueryDomainInfo2(p, mem_ctx, &r);
2545 if (!NT_STATUS_IS_OK(status)) {
2546 printf("QueryDomainInfo2 level %u failed - %s\n",
2547 r.in.level, nt_errstr(status));
2556 /* Test whether querydispinfo level 5 and enumdomgroups return the same
2557 set of group names. */
2558 static BOOL test_GroupList(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2559 struct policy_handle *handle)
2561 struct samr_EnumDomainGroups q1;
2562 struct samr_QueryDisplayInfo q2;
2564 uint32_t resume_handle=0;
2569 const char **names = NULL;
2571 printf("Testing coherency of querydispinfo vs enumdomgroups\n");
2573 q1.in.domain_handle = handle;
2574 q1.in.resume_handle = &resume_handle;
2576 q1.out.resume_handle = &resume_handle;
2578 status = STATUS_MORE_ENTRIES;
2579 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
2580 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &q1);
2582 if (!NT_STATUS_IS_OK(status) &&
2583 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
2586 for (i=0; i<q1.out.num_entries; i++) {
2587 add_string_to_array(mem_ctx,
2588 q1.out.sam->entries[i].name.string,
2589 &names, &num_names);
2593 if (!NT_STATUS_IS_OK(status)) {
2594 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
2602 q2.in.domain_handle = handle;
2604 q2.in.start_idx = 0;
2605 q2.in.max_entries = 5;
2606 q2.in.buf_size = (uint32_t)-1;
2608 status = STATUS_MORE_ENTRIES;
2609 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
2610 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &q2);
2612 if (!NT_STATUS_IS_OK(status) &&
2613 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
2616 for (i=0; i<q2.out.info.info5.count; i++) {
2618 const char *name = q2.out.info.info5.entries[i].account_name.string;
2620 for (j=0; j<num_names; j++) {
2621 if (names[j] == NULL)
2623 /* Hmm. No strequal in samba4 */
2624 if (strequal(names[j], name)) {
2632 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
2637 q2.in.start_idx += q2.out.info.info5.count;
2640 if (!NT_STATUS_IS_OK(status)) {
2641 printf("QueryDisplayInfo level 5 failed - %s\n",
2646 for (i=0; i<num_names; i++) {
2647 if (names[i] != NULL) {
2648 printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
2657 static BOOL test_DeleteDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2658 struct policy_handle *group_handle)
2660 struct samr_DeleteDomainGroup d;
2664 printf("Testing DeleteDomainGroup\n");
2666 d.in.group_handle = group_handle;
2667 d.out.group_handle = group_handle;
2669 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
2670 if (!NT_STATUS_IS_OK(status)) {
2671 printf("DeleteDomainGroup failed - %s\n", nt_errstr(status));
2678 static BOOL test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2679 struct policy_handle *domain_handle)
2681 struct samr_TestPrivateFunctionsDomain r;
2685 printf("Testing TestPrivateFunctionsDomain\n");
2687 r.in.domain_handle = domain_handle;
2689 status = dcerpc_samr_TestPrivateFunctionsDomain(p, mem_ctx, &r);
2690 if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
2691 printf("TestPrivateFunctionsDomain failed - %s\n", nt_errstr(status));
2698 static BOOL test_RidToSid(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2699 struct policy_handle *domain_handle)
2701 struct samr_RidToSid r;
2705 printf("Testing RidToSid\n");
2707 r.in.domain_handle = domain_handle;
2710 status = dcerpc_samr_RidToSid(p, mem_ctx, &r);
2711 if (!NT_STATUS_IS_OK(status)) {
2712 printf("RidToSid failed - %s\n", nt_errstr(status));
2719 static BOOL test_GetBootKeyInformation(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2720 struct policy_handle *domain_handle)
2722 struct samr_GetBootKeyInformation r;
2726 printf("Testing GetBootKeyInformation\n");
2728 r.in.domain_handle = domain_handle;
2730 status = dcerpc_samr_GetBootKeyInformation(p, mem_ctx, &r);
2731 if (!NT_STATUS_IS_OK(status)) {
2732 /* w2k3 seems to fail this sometimes and pass it sometimes */
2733 printf("GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
2739 static BOOL test_AddGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2740 struct policy_handle *domain_handle,
2741 struct policy_handle *group_handle)
2744 struct samr_AddGroupMember r;
2745 struct samr_DeleteGroupMember d;
2746 struct samr_QueryGroupMember q;
2747 struct samr_SetMemberAttributesOfGroup s;
2751 status = test_LookupName(p, mem_ctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
2752 if (!NT_STATUS_IS_OK(status)) {
2756 r.in.group_handle = group_handle;
2758 r.in.flags = 0; /* ??? */
2760 printf("Testing AddGroupMember and DeleteGroupMember\n");
2762 d.in.group_handle = group_handle;
2765 status = dcerpc_samr_DeleteGroupMember(p, mem_ctx, &d);
2766 if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_NOT_IN_GROUP, status)) {
2767 printf("DeleteGroupMember gave %s - should be NT_STATUS_MEMBER_NOT_IN_GROUP\n",
2772 status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
2773 if (!NT_STATUS_IS_OK(status)) {
2774 printf("AddGroupMember failed - %s\n", nt_errstr(status));
2778 status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
2779 if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_IN_GROUP, status)) {
2780 printf("AddGroupMember gave %s - should be NT_STATUS_MEMBER_IN_GROUP\n",
2785 /* this one is quite strange. I am using random inputs in the
2786 hope of triggering an error that might give us a clue */
2787 s.in.group_handle = group_handle;
2788 s.in.unknown1 = random();
2789 s.in.unknown2 = random();
2791 status = dcerpc_samr_SetMemberAttributesOfGroup(p, mem_ctx, &s);
2792 if (!NT_STATUS_IS_OK(status)) {
2793 printf("SetMemberAttributesOfGroup failed - %s\n", nt_errstr(status));
2797 q.in.group_handle = group_handle;
2799 status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &q);
2800 if (!NT_STATUS_IS_OK(status)) {
2801 printf("QueryGroupMember failed - %s\n", nt_errstr(status));
2805 status = dcerpc_samr_DeleteGroupMember(p, mem_ctx, &d);
2806 if (!NT_STATUS_IS_OK(status)) {
2807 printf("DeleteGroupMember failed - %s\n", nt_errstr(status));
2811 status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
2812 if (!NT_STATUS_IS_OK(status)) {
2813 printf("AddGroupMember failed - %s\n", nt_errstr(status));
2821 static BOOL test_CreateDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2822 struct policy_handle *domain_handle, struct policy_handle *group_handle)
2825 struct samr_CreateDomainGroup r;
2827 struct samr_String name;
2830 init_samr_String(&name, TEST_GROUPNAME);
2832 r.in.domain_handle = domain_handle;
2834 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2835 r.out.group_handle = group_handle;
2838 printf("Testing CreateDomainGroup(%s)\n", r.in.name->string);
2840 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
2842 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2843 printf("Server refused create of '%s'\n", r.in.name->string);
2844 ZERO_STRUCTP(group_handle);
2848 if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS) ||
2849 NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
2850 if (!test_DeleteGroup_byname(p, mem_ctx, domain_handle, r.in.name->string)) {
2853 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
2855 if (!NT_STATUS_IS_OK(status)) {
2856 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
2860 if (!test_AddGroupMember(p, mem_ctx, domain_handle, group_handle)) {
2864 if (!test_SetGroupInfo(p, mem_ctx, group_handle)) {
2873 its not totally clear what this does. It seems to accept any sid you like.
2875 static BOOL test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p,
2876 TALLOC_CTX *mem_ctx,
2877 struct policy_handle *domain_handle)
2880 struct samr_RemoveMemberFromForeignDomain r;
2882 r.in.domain_handle = domain_handle;
2883 r.in.sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-12-34-56-78-9");
2885 status = dcerpc_samr_RemoveMemberFromForeignDomain(p, mem_ctx, &r);
2886 if (!NT_STATUS_IS_OK(status)) {
2887 printf("RemoveMemberFromForeignDomain failed - %s\n", nt_errstr(status));
2896 static BOOL test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2897 struct policy_handle *handle);
2899 static BOOL test_OpenDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2900 struct policy_handle *handle, struct dom_sid *sid)
2903 struct samr_OpenDomain r;
2904 struct policy_handle domain_handle;
2905 struct policy_handle user_handle;
2906 struct policy_handle alias_handle;
2907 struct policy_handle group_handle;
2910 ZERO_STRUCT(user_handle);
2911 ZERO_STRUCT(alias_handle);
2912 ZERO_STRUCT(group_handle);
2913 ZERO_STRUCT(domain_handle);
2915 printf("Testing OpenDomain\n");
2917 r.in.connect_handle = handle;
2918 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2920 r.out.domain_handle = &domain_handle;
2922 status = dcerpc_samr_OpenDomain(p, mem_ctx, &r);
2923 if (!NT_STATUS_IS_OK(status)) {
2924 printf("OpenDomain failed - %s\n", nt_errstr(status));
2928 /* run the domain tests with the main handle closed - this tests
2929 the servers reference counting */
2930 ret &= test_samr_handle_Close(p, mem_ctx, handle);
2932 ret &= test_QuerySecurity(p, mem_ctx, &domain_handle);
2933 ret &= test_RemoveMemberFromForeignDomain(p, mem_ctx, &domain_handle);
2934 ret &= test_CreateUser2(p, mem_ctx, &domain_handle);
2935 ret &= test_CreateUser(p, mem_ctx, &domain_handle, &user_handle);
2936 ret &= test_CreateAlias(p, mem_ctx, &domain_handle, &alias_handle, sid);
2937 ret &= test_CreateDomainGroup(p, mem_ctx, &domain_handle, &group_handle);
2938 ret &= test_QueryDomainInfo(p, mem_ctx, &domain_handle);
2939 ret &= test_QueryDomainInfo2(p, mem_ctx, &domain_handle);
2940 ret &= test_EnumDomainUsers(p, mem_ctx, &domain_handle);
2941 ret &= test_EnumDomainUsers_async(p, mem_ctx, &domain_handle);
2942 ret &= test_EnumDomainGroups(p, mem_ctx, &domain_handle);
2943 ret &= test_EnumDomainAliases(p, mem_ctx, &domain_handle);
2944 ret &= test_QueryDisplayInfo(p, mem_ctx, &domain_handle);
2945 ret &= test_QueryDisplayInfo2(p, mem_ctx, &domain_handle);
2946 ret &= test_QueryDisplayInfo3(p, mem_ctx, &domain_handle);
2947 ret &= test_GetDisplayEnumerationIndex(p, mem_ctx, &domain_handle);
2948 ret &= test_GetDisplayEnumerationIndex2(p, mem_ctx, &domain_handle);
2949 ret &= test_GroupList(p, mem_ctx, &domain_handle);
2950 ret &= test_TestPrivateFunctionsDomain(p, mem_ctx, &domain_handle);
2951 ret &= test_RidToSid(p, mem_ctx, &domain_handle);
2952 ret &= test_GetBootKeyInformation(p, mem_ctx, &domain_handle);
2954 if (!policy_handle_empty(&user_handle) &&
2955 !test_DeleteUser(p, mem_ctx, &user_handle)) {
2959 if (!policy_handle_empty(&alias_handle) &&
2960 !test_DeleteAlias(p, mem_ctx, &alias_handle)) {
2964 if (!policy_handle_empty(&group_handle) &&
2965 !test_DeleteDomainGroup(p, mem_ctx, &group_handle)) {
2969 ret &= test_samr_handle_Close(p, mem_ctx, &domain_handle);
2971 /* reconnect the main handle */
2972 ret &= test_Connect(p, mem_ctx, handle);
2977 static BOOL test_LookupDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2978 struct policy_handle *handle, struct samr_String *domain)
2981 struct samr_LookupDomain r;
2982 struct samr_String n2;
2985 printf("Testing LookupDomain(%s)\n", domain->string);
2987 /* check for correct error codes */
2988 r.in.connect_handle = handle;
2989 r.in.domain_name = &n2;
2992 status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
2993 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_PARAMETER, status)) {
2994 printf("failed: LookupDomain expected NT_STATUS_INVALID_PARAMETER - %s\n", nt_errstr(status));
2998 n2.string = "xxNODOMAINxx";
3000 status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
3001 if (!NT_STATUS_EQUAL(NT_STATUS_NO_SUCH_DOMAIN, status)) {
3002 printf("failed: LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN - %s\n", nt_errstr(status));
3006 r.in.connect_handle = handle;
3007 r.in.domain_name = domain;
3009 status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
3010 if (!NT_STATUS_IS_OK(status)) {
3011 printf("LookupDomain failed - %s\n", nt_errstr(status));
3015 if (!test_GetDomPwInfo(p, mem_ctx, domain)) {
3019 if (!test_OpenDomain(p, mem_ctx, handle, r.out.sid)) {
3027 static BOOL test_EnumDomains(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3028 struct policy_handle *handle)
3031 struct samr_EnumDomains r;
3032 uint32_t resume_handle = 0;
3036 r.in.connect_handle = handle;
3037 r.in.resume_handle = &resume_handle;
3038 r.in.buf_size = (uint32_t)-1;
3039 r.out.resume_handle = &resume_handle;
3041 status = dcerpc_samr_EnumDomains(p, mem_ctx, &r);
3042 if (!NT_STATUS_IS_OK(status)) {
3043 printf("EnumDomains failed - %s\n", nt_errstr(status));
3051 for (i=0;i<r.out.sam->count;i++) {
3052 if (!test_LookupDomain(p, mem_ctx, handle,
3053 &r.out.sam->entries[i].name)) {
3058 status = dcerpc_samr_EnumDomains(p, mem_ctx, &r);
3059 if (!NT_STATUS_IS_OK(status)) {
3060 printf("EnumDomains failed - %s\n", nt_errstr(status));
3068 static BOOL test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3069 struct policy_handle *handle)
3072 struct samr_Connect r;
3073 struct samr_Connect2 r2;
3074 struct samr_Connect3 r3;
3075 struct samr_Connect4 r4;
3076 struct samr_Connect5 r5;
3077 union samr_ConnectInfo info;
3078 struct policy_handle h;
3079 BOOL ret = True, got_handle = False;
3081 printf("testing samr_Connect\n");
3083 r.in.system_name = 0;
3084 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3085 r.out.connect_handle = &h;
3087 status = dcerpc_samr_Connect(p, mem_ctx, &r);
3088 if (!NT_STATUS_IS_OK(status)) {
3089 printf("Connect failed - %s\n", nt_errstr(status));
3096 printf("testing samr_Connect2\n");
3098 r2.in.system_name = NULL;
3099 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3100 r2.out.connect_handle = &h;
3102 status = dcerpc_samr_Connect2(p, mem_ctx, &r2);
3103 if (!NT_STATUS_IS_OK(status)) {
3104 printf("Connect2 failed - %s\n", nt_errstr(status));
3108 test_samr_handle_Close(p, mem_ctx, handle);
3114 printf("testing samr_Connect3\n");
3116 r3.in.system_name = NULL;
3118 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3119 r3.out.connect_handle = &h;
3121 status = dcerpc_samr_Connect3(p, mem_ctx, &r3);
3122 if (!NT_STATUS_IS_OK(status)) {
3123 printf("Connect3 failed - %s\n", nt_errstr(status));
3127 test_samr_handle_Close(p, mem_ctx, handle);
3133 printf("testing samr_Connect4\n");
3135 r4.in.system_name = "";
3137 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3138 r4.out.connect_handle = &h;
3140 status = dcerpc_samr_Connect4(p, mem_ctx, &r4);
3141 if (!NT_STATUS_IS_OK(status)) {
3142 printf("Connect4 failed - %s\n", nt_errstr(status));
3146 test_samr_handle_Close(p, mem_ctx, handle);
3152 printf("testing samr_Connect5\n");
3154 info.info1.unknown1 = 0;
3155 info.info1.unknown2 = 0;
3157 r5.in.system_name = "";
3158 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3161 r5.out.info = &info;
3162 r5.out.connect_handle = &h;
3164 status = dcerpc_samr_Connect5(p, mem_ctx, &r5);
3165 if (!NT_STATUS_IS_OK(status)) {
3166 printf("Connect5 failed - %s\n", nt_errstr(status));
3170 test_samr_handle_Close(p, mem_ctx, handle);
3180 BOOL torture_rpc_samr(void)
3183 struct dcerpc_pipe *p;
3184 TALLOC_CTX *mem_ctx;
3186 struct policy_handle handle;
3188 mem_ctx = talloc_init("torture_rpc_samr");
3190 status = torture_rpc_connection(&p,
3193 DCERPC_SAMR_VERSION);
3194 if (!NT_STATUS_IS_OK(status)) {
3198 if (!test_Connect(p, mem_ctx, &handle)) {
3202 if (!test_QuerySecurity(p, mem_ctx, &handle)) {
3206 if (!test_EnumDomains(p, mem_ctx, &handle)) {
3210 if (!test_SetDsrmPassword(p, mem_ctx, &handle)) {
3214 if (!test_Shutdown(p, mem_ctx, &handle)) {
3218 if (!test_samr_handle_Close(p, mem_ctx, &handle)) {
3222 talloc_free(mem_ctx);
3224 torture_rpc_close(p);