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 ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
654 case ALIASINFODESCRIPTION: 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 lsa_AsciiString 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 BOOL test_ChangePasswordUser3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1086 const char *account_string,
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, account_string);
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, account_string, policy_min_pw_len, password);
1138 printf("ChangePasswordUser3 failed (no min length known) - %s\n", nt_errstr(status));
1141 } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1142 printf("ChangePasswordUser3 failed: %s unacceptable as new password - %s\n", newpass, nt_errstr(status));
1144 } else if (!NT_STATUS_IS_OK(status)) {
1145 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
1148 *password = newpass;
1155 static BOOL test_GetMembersInAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1156 struct policy_handle *alias_handle)
1158 struct samr_GetMembersInAlias r;
1159 struct lsa_SidArray sids;
1163 printf("Testing GetMembersInAlias\n");
1165 r.in.alias_handle = alias_handle;
1168 status = dcerpc_samr_GetMembersInAlias(p, mem_ctx, &r);
1169 if (!NT_STATUS_IS_OK(status)) {
1170 printf("GetMembersInAlias failed - %s\n",
1178 static BOOL test_AddMemberToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1179 struct policy_handle *alias_handle,
1180 const struct dom_sid *domain_sid)
1182 struct samr_AddAliasMember r;
1183 struct samr_DeleteAliasMember d;
1186 struct dom_sid *sid;
1188 sid = dom_sid_add_rid(mem_ctx, domain_sid, 512);
1190 printf("testing AddAliasMember\n");
1191 r.in.alias_handle = alias_handle;
1194 status = dcerpc_samr_AddAliasMember(p, mem_ctx, &r);
1195 if (!NT_STATUS_IS_OK(status)) {
1196 printf("AddAliasMember failed - %s\n", nt_errstr(status));
1200 d.in.alias_handle = alias_handle;
1203 status = dcerpc_samr_DeleteAliasMember(p, mem_ctx, &d);
1204 if (!NT_STATUS_IS_OK(status)) {
1205 printf("DelAliasMember failed - %s\n", nt_errstr(status));
1212 static BOOL test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1213 struct policy_handle *alias_handle)
1215 struct samr_AddMultipleMembersToAlias a;
1216 struct samr_RemoveMultipleMembersFromAlias r;
1219 struct lsa_SidArray sids;
1221 printf("testing AddMultipleMembersToAlias\n");
1222 a.in.alias_handle = alias_handle;
1226 sids.sids = talloc_array(mem_ctx, struct lsa_SidPtr, 3);
1228 sids.sids[0].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-1");
1229 sids.sids[1].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-2");
1230 sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-3");
1232 status = dcerpc_samr_AddMultipleMembersToAlias(p, mem_ctx, &a);
1233 if (!NT_STATUS_IS_OK(status)) {
1234 printf("AddMultipleMembersToAlias failed - %s\n", nt_errstr(status));
1239 printf("testing RemoveMultipleMembersFromAlias\n");
1240 r.in.alias_handle = alias_handle;
1243 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1244 if (!NT_STATUS_IS_OK(status)) {
1245 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1249 /* strange! removing twice doesn't give any error */
1250 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1251 if (!NT_STATUS_IS_OK(status)) {
1252 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1256 /* but removing an alias that isn't there does */
1257 sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-4");
1259 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1260 if (!NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_NOT_FOUND, status)) {
1261 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1268 static BOOL test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1269 struct policy_handle *user_handle)
1271 struct samr_TestPrivateFunctionsUser r;
1275 printf("Testing TestPrivateFunctionsUser\n");
1277 r.in.user_handle = user_handle;
1279 status = dcerpc_samr_TestPrivateFunctionsUser(p, mem_ctx, &r);
1280 if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
1281 printf("TestPrivateFunctionsUser failed - %s\n", nt_errstr(status));
1289 static BOOL test_user_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1290 struct policy_handle *handle, uint32_t base_acct_flags,
1291 const char *base_acct_name)
1295 if (!test_QuerySecurity(p, mem_ctx, handle)) {
1299 if (!test_QueryUserInfo(p, mem_ctx, handle)) {
1303 if (!test_QueryUserInfo2(p, mem_ctx, handle)) {
1307 if (!test_SetUserInfo(p, mem_ctx, handle, base_acct_flags,
1312 if (!test_GetUserPwInfo(p, mem_ctx, handle)) {
1316 if (!test_TestPrivateFunctionsUser(p, mem_ctx, handle)) {
1323 static BOOL test_alias_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1324 struct policy_handle *alias_handle,
1325 const struct dom_sid *domain_sid)
1329 if (!test_QuerySecurity(p, mem_ctx, alias_handle)) {
1333 if (!test_QueryAliasInfo(p, mem_ctx, alias_handle)) {
1337 if (!test_SetAliasInfo(p, mem_ctx, alias_handle)) {
1341 if (!test_AddMemberToAlias(p, mem_ctx, alias_handle, domain_sid)) {
1345 if (!test_AddMultipleMembersToAlias(p, mem_ctx, alias_handle)) {
1353 BOOL test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1354 struct policy_handle *handle, const char *name)
1357 struct samr_DeleteUser d;
1358 struct policy_handle user_handle;
1361 status = test_LookupName(p, mem_ctx, handle, name, &rid);
1362 if (!NT_STATUS_IS_OK(status)) {
1366 status = test_OpenUser_byname(p, mem_ctx, handle, name, &user_handle);
1367 if (!NT_STATUS_IS_OK(status)) {
1371 d.in.user_handle = &user_handle;
1372 d.out.user_handle = &user_handle;
1373 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
1374 if (!NT_STATUS_IS_OK(status)) {
1381 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
1386 static BOOL test_DeleteGroup_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1387 struct policy_handle *handle, const char *name)
1390 struct samr_OpenGroup r;
1391 struct samr_DeleteDomainGroup d;
1392 struct policy_handle group_handle;
1395 status = test_LookupName(p, mem_ctx, handle, name, &rid);
1396 if (!NT_STATUS_IS_OK(status)) {
1400 r.in.domain_handle = handle;
1401 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1403 r.out.group_handle = &group_handle;
1404 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
1405 if (!NT_STATUS_IS_OK(status)) {
1409 d.in.group_handle = &group_handle;
1410 d.out.group_handle = &group_handle;
1411 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
1412 if (!NT_STATUS_IS_OK(status)) {
1419 printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
1424 static BOOL test_DeleteAlias_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1425 struct policy_handle *domain_handle, const char *name)
1428 struct samr_OpenAlias r;
1429 struct samr_DeleteDomAlias d;
1430 struct policy_handle alias_handle;
1433 printf("testing DeleteAlias_byname\n");
1435 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
1436 if (!NT_STATUS_IS_OK(status)) {
1440 r.in.domain_handle = domain_handle;
1441 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1443 r.out.alias_handle = &alias_handle;
1444 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
1445 if (!NT_STATUS_IS_OK(status)) {
1449 d.in.alias_handle = &alias_handle;
1450 d.out.alias_handle = &alias_handle;
1451 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
1452 if (!NT_STATUS_IS_OK(status)) {
1459 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
1463 static BOOL test_DeleteAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1464 struct policy_handle *alias_handle)
1466 struct samr_DeleteDomAlias d;
1469 printf("Testing DeleteAlias\n");
1471 d.in.alias_handle = alias_handle;
1472 d.out.alias_handle = alias_handle;
1474 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
1475 if (!NT_STATUS_IS_OK(status)) {
1476 printf("DeleteAlias failed - %s\n", nt_errstr(status));
1483 static BOOL test_CreateAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1484 struct policy_handle *domain_handle,
1485 struct policy_handle *alias_handle,
1486 const struct dom_sid *domain_sid)
1489 struct samr_CreateDomAlias r;
1490 struct lsa_String name;
1494 init_lsa_String(&name, TEST_ALIASNAME);
1495 r.in.domain_handle = domain_handle;
1496 r.in.alias_name = &name;
1497 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1498 r.out.alias_handle = alias_handle;
1501 printf("Testing CreateAlias (%s)\n", r.in.alias_name->string);
1503 status = dcerpc_samr_CreateDomAlias(p, mem_ctx, &r);
1505 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1506 printf("Server refused create of '%s'\n", r.in.alias_name->string);
1510 if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
1511 if (!test_DeleteAlias_byname(p, mem_ctx, domain_handle, r.in.alias_name->string)) {
1514 status = dcerpc_samr_CreateDomAlias(p, mem_ctx, &r);
1517 if (!NT_STATUS_IS_OK(status)) {
1518 printf("CreateAlias failed - %s\n", nt_errstr(status));
1522 if (!test_alias_ops(p, mem_ctx, alias_handle, domain_sid)) {
1529 static BOOL test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1530 struct policy_handle *domain_handle, char **password)
1538 if (!test_ChangePasswordUser(p, mem_ctx, domain_handle, password)) {
1542 if (!test_ChangePasswordUser2(p, mem_ctx, domain_handle, password)) {
1546 if (!test_OemChangePasswordUser2(p, mem_ctx, domain_handle, password)) {
1550 /* we change passwords twice - this has the effect of verifying
1551 they were changed correctly for the final call */
1552 if (!test_ChangePasswordUser3(p, mem_ctx, TEST_ACCOUNT_NAME, 0, password)) {
1556 if (!test_ChangePasswordUser3(p, mem_ctx, TEST_ACCOUNT_NAME, 0, password)) {
1563 static BOOL test_CreateUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1564 struct policy_handle *domain_handle, struct policy_handle *user_handle)
1567 struct samr_CreateUser r;
1568 struct samr_QueryUserInfo q;
1570 char *password = NULL;
1573 const uint32_t password_fields[] = {
1574 SAMR_FIELD_PASSWORD,
1575 SAMR_FIELD_PASSWORD2,
1576 SAMR_FIELD_PASSWORD | SAMR_FIELD_PASSWORD2,
1580 TALLOC_CTX *user_ctx;
1582 /* This call creates a 'normal' account - check that it really does */
1583 const uint32_t acct_flags = ACB_NORMAL;
1584 struct lsa_String name;
1587 user_ctx = talloc_named(mem_ctx, 0, "test_CreateUser2 per-user context");
1588 init_lsa_String(&name, TEST_ACCOUNT_NAME);
1590 r.in.domain_handle = domain_handle;
1591 r.in.account_name = &name;
1592 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1593 r.out.user_handle = user_handle;
1596 printf("Testing CreateUser(%s)\n", r.in.account_name->string);
1598 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
1600 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1601 printf("Server refused create of '%s'\n", r.in.account_name->string);
1602 ZERO_STRUCTP(user_handle);
1603 talloc_free(user_ctx);
1607 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
1608 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
1609 talloc_free(user_ctx);
1612 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
1614 if (!NT_STATUS_IS_OK(status)) {
1615 talloc_free(user_ctx);
1616 printf("CreateUser failed - %s\n", nt_errstr(status));
1620 q.in.user_handle = user_handle;
1623 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
1624 if (!NT_STATUS_IS_OK(status)) {
1625 printf("QueryUserInfo level %u failed - %s\n",
1626 q.in.level, nt_errstr(status));
1629 if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
1630 printf("QuerUserInfo level 16 failed, it returned 0x%08x (%u) when we expected flags of 0x%08x (%u)\n",
1631 q.out.info->info16.acct_flags, q.out.info->info16.acct_flags,
1632 acct_flags, acct_flags);
1637 if (!test_user_ops(p, user_ctx, user_handle, acct_flags, name.string)) {
1641 if (!test_SetUserPass(p, user_ctx, user_handle, &password)) {
1645 for (i = 0; password_fields[i]; i++) {
1646 if (!test_SetUserPass_23(p, user_ctx, user_handle, password_fields[i], &password)) {
1650 /* check it was set right */
1651 if (!test_ChangePasswordUser3(p, user_ctx, TEST_ACCOUNT_NAME, 0, &password)) {
1656 for (i = 0; password_fields[i]; i++) {
1657 if (!test_SetUserPass_25(p, user_ctx, user_handle, password_fields[i], &password)) {
1661 /* check it was set right */
1662 if (!test_ChangePasswordUser3(p, user_ctx, TEST_ACCOUNT_NAME, 0, &password)) {
1667 if (!test_SetUserPassEx(p, user_ctx, user_handle, &password)) {
1671 if (!test_ChangePassword(p, user_ctx, domain_handle, &password)) {
1675 talloc_free(user_ctx);
1681 static BOOL test_DeleteUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1682 struct policy_handle *user_handle)
1684 struct samr_DeleteUser d;
1688 printf("Testing DeleteUser\n");
1690 d.in.user_handle = user_handle;
1691 d.out.user_handle = user_handle;
1693 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
1694 if (!NT_STATUS_IS_OK(status)) {
1695 printf("DeleteUser failed - %s\n", nt_errstr(status));
1702 static BOOL test_CreateUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1703 struct policy_handle *handle)
1706 struct samr_CreateUser2 r;
1707 struct samr_QueryUserInfo q;
1708 struct samr_DeleteUser d;
1709 struct policy_handle user_handle;
1711 struct lsa_String name;
1716 uint32_t acct_flags;
1717 const char *account_name;
1719 } account_types[] = {
1720 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
1721 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1722 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1723 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
1724 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1725 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1726 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
1727 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1728 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1729 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
1730 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
1731 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
1732 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1733 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1734 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
1737 for (i = 0; account_types[i].account_name; i++) {
1738 TALLOC_CTX *user_ctx;
1739 uint32_t acct_flags = account_types[i].acct_flags;
1740 uint32_t access_granted;
1741 user_ctx = talloc_named(mem_ctx, 0, "test_CreateUser2 per-user context");
1742 init_lsa_String(&name, account_types[i].account_name);
1744 r.in.domain_handle = handle;
1745 r.in.account_name = &name;
1746 r.in.acct_flags = acct_flags;
1747 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1748 r.out.user_handle = &user_handle;
1749 r.out.access_granted = &access_granted;
1752 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
1754 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
1756 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1757 talloc_free(user_ctx);
1758 printf("Server refused create of '%s'\n", r.in.account_name->string);
1761 } else if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
1762 if (!test_DeleteUser_byname(p, user_ctx, handle, r.in.account_name->string)) {
1763 talloc_free(user_ctx);
1767 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
1770 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
1771 printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
1772 nt_errstr(status), nt_errstr(account_types[i].nt_status));
1776 if (NT_STATUS_IS_OK(status)) {
1777 q.in.user_handle = &user_handle;
1780 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
1781 if (!NT_STATUS_IS_OK(status)) {
1782 printf("QueryUserInfo level %u failed - %s\n",
1783 q.in.level, nt_errstr(status));
1786 if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
1787 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
1788 q.out.info->info16.acct_flags,
1794 if (!test_user_ops(p, user_ctx, &user_handle, acct_flags, name.string)) {
1798 printf("Testing DeleteUser (createuser2 test)\n");
1800 d.in.user_handle = &user_handle;
1801 d.out.user_handle = &user_handle;
1803 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
1804 if (!NT_STATUS_IS_OK(status)) {
1805 printf("DeleteUser failed - %s\n", nt_errstr(status));
1809 talloc_free(user_ctx);
1815 static BOOL test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1816 struct policy_handle *handle)
1819 struct samr_QueryAliasInfo r;
1820 uint16_t levels[] = {1, 2, 3};
1824 for (i=0;i<ARRAY_SIZE(levels);i++) {
1825 printf("Testing QueryAliasInfo level %u\n", levels[i]);
1827 r.in.alias_handle = handle;
1828 r.in.level = levels[i];
1830 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
1831 if (!NT_STATUS_IS_OK(status)) {
1832 printf("QueryAliasInfo level %u failed - %s\n",
1833 levels[i], nt_errstr(status));
1841 static BOOL test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1842 struct policy_handle *handle)
1845 struct samr_QueryGroupInfo r;
1846 uint16_t levels[] = {1, 2, 3, 4, 5};
1850 for (i=0;i<ARRAY_SIZE(levels);i++) {
1851 printf("Testing QueryGroupInfo level %u\n", levels[i]);
1853 r.in.group_handle = handle;
1854 r.in.level = levels[i];
1856 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
1857 if (!NT_STATUS_IS_OK(status)) {
1858 printf("QueryGroupInfo level %u failed - %s\n",
1859 levels[i], nt_errstr(status));
1867 static BOOL test_QueryGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1868 struct policy_handle *handle)
1871 struct samr_QueryGroupMember r;
1874 printf("Testing QueryGroupMember\n");
1876 r.in.group_handle = handle;
1878 status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &r);
1879 if (!NT_STATUS_IS_OK(status)) {
1880 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
1888 static BOOL test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1889 struct policy_handle *handle)
1892 struct samr_QueryGroupInfo r;
1893 struct samr_SetGroupInfo s;
1894 uint16_t levels[] = {1, 2, 3, 4};
1895 uint16_t set_ok[] = {0, 1, 1, 1};
1899 for (i=0;i<ARRAY_SIZE(levels);i++) {
1900 printf("Testing QueryGroupInfo level %u\n", levels[i]);
1902 r.in.group_handle = handle;
1903 r.in.level = levels[i];
1905 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
1906 if (!NT_STATUS_IS_OK(status)) {
1907 printf("QueryGroupInfo level %u failed - %s\n",
1908 levels[i], nt_errstr(status));
1912 printf("Testing SetGroupInfo level %u\n", levels[i]);
1914 s.in.group_handle = handle;
1915 s.in.level = levels[i];
1916 s.in.info = r.out.info;
1919 /* disabled this, as it changes the name only from the point of view of samr,
1920 but leaves the name from the point of view of w2k3 internals (and ldap). This means
1921 the name is still reserved, so creating the old name fails, but deleting by the old name
1923 if (s.in.level == 2) {
1924 init_lsa_String(&s.in.info->string, "NewName");
1928 if (s.in.level == 4) {
1929 init_lsa_String(&s.in.info->description, "test description");
1932 status = dcerpc_samr_SetGroupInfo(p, mem_ctx, &s);
1934 if (!NT_STATUS_IS_OK(status)) {
1935 printf("SetGroupInfo level %u failed - %s\n",
1936 r.in.level, nt_errstr(status));
1941 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
1942 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
1943 r.in.level, nt_errstr(status));
1953 static BOOL test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1954 struct policy_handle *handle)
1957 struct samr_QueryUserInfo r;
1958 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
1959 11, 12, 13, 14, 16, 17, 20, 21};
1963 for (i=0;i<ARRAY_SIZE(levels);i++) {
1964 printf("Testing QueryUserInfo level %u\n", levels[i]);
1966 r.in.user_handle = handle;
1967 r.in.level = levels[i];
1969 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
1970 if (!NT_STATUS_IS_OK(status)) {
1971 printf("QueryUserInfo level %u failed - %s\n",
1972 levels[i], nt_errstr(status));
1980 static BOOL test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1981 struct policy_handle *handle)
1984 struct samr_QueryUserInfo2 r;
1985 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
1986 11, 12, 13, 14, 16, 17, 20, 21};
1990 for (i=0;i<ARRAY_SIZE(levels);i++) {
1991 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
1993 r.in.user_handle = handle;
1994 r.in.level = levels[i];
1996 status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r);
1997 if (!NT_STATUS_IS_OK(status)) {
1998 printf("QueryUserInfo2 level %u failed - %s\n",
1999 levels[i], nt_errstr(status));
2007 static BOOL test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2008 struct policy_handle *handle, uint32_t rid)
2011 struct samr_OpenUser r;
2012 struct policy_handle user_handle;
2015 printf("Testing OpenUser(%u)\n", rid);
2017 r.in.domain_handle = handle;
2018 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2020 r.out.user_handle = &user_handle;
2022 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
2023 if (!NT_STATUS_IS_OK(status)) {
2024 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
2028 if (!test_QuerySecurity(p, mem_ctx, &user_handle)) {
2032 if (!test_QueryUserInfo(p, mem_ctx, &user_handle)) {
2036 if (!test_QueryUserInfo2(p, mem_ctx, &user_handle)) {
2040 if (!test_GetUserPwInfo(p, mem_ctx, &user_handle)) {
2044 if (!test_GetGroupsForUser(p,mem_ctx, &user_handle)) {
2048 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
2055 static BOOL test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2056 struct policy_handle *handle, uint32_t rid)
2059 struct samr_OpenGroup r;
2060 struct policy_handle group_handle;
2063 printf("Testing OpenGroup(%u)\n", rid);
2065 r.in.domain_handle = handle;
2066 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2068 r.out.group_handle = &group_handle;
2070 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
2071 if (!NT_STATUS_IS_OK(status)) {
2072 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
2076 if (!test_QuerySecurity(p, mem_ctx, &group_handle)) {
2080 if (!test_QueryGroupInfo(p, mem_ctx, &group_handle)) {
2084 if (!test_QueryGroupMember(p, mem_ctx, &group_handle)) {
2088 if (!test_samr_handle_Close(p, mem_ctx, &group_handle)) {
2095 static BOOL test_OpenAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2096 struct policy_handle *handle, uint32_t rid)
2099 struct samr_OpenAlias r;
2100 struct policy_handle alias_handle;
2103 printf("Testing OpenAlias(%u)\n", rid);
2105 r.in.domain_handle = handle;
2106 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2108 r.out.alias_handle = &alias_handle;
2110 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
2111 if (!NT_STATUS_IS_OK(status)) {
2112 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
2116 if (!test_QuerySecurity(p, mem_ctx, &alias_handle)) {
2120 if (!test_QueryAliasInfo(p, mem_ctx, &alias_handle)) {
2124 if (!test_GetMembersInAlias(p, mem_ctx, &alias_handle)) {
2128 if (!test_samr_handle_Close(p, mem_ctx, &alias_handle)) {
2135 static BOOL test_EnumDomainUsers(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2136 struct policy_handle *handle)
2139 struct samr_EnumDomainUsers r;
2140 uint32_t resume_handle=0;
2143 struct samr_LookupNames n;
2144 struct samr_LookupRids lr ;
2146 printf("Testing EnumDomainUsers\n");
2148 r.in.domain_handle = handle;
2149 r.in.resume_handle = &resume_handle;
2150 r.in.acct_flags = 0;
2151 r.in.max_size = (uint32_t)-1;
2152 r.out.resume_handle = &resume_handle;
2154 status = dcerpc_samr_EnumDomainUsers(p, mem_ctx, &r);
2155 if (!NT_STATUS_IS_OK(status)) {
2156 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
2164 if (r.out.sam->count == 0) {
2168 for (i=0;i<r.out.sam->count;i++) {
2169 if (!test_OpenUser(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
2174 printf("Testing LookupNames\n");
2175 n.in.domain_handle = handle;
2176 n.in.num_names = r.out.sam->count;
2177 n.in.names = talloc_array(mem_ctx, struct lsa_String, r.out.sam->count);
2178 for (i=0;i<r.out.sam->count;i++) {
2179 n.in.names[i] = r.out.sam->entries[i].name;
2181 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
2182 if (!NT_STATUS_IS_OK(status)) {
2183 printf("LookupNames failed - %s\n", nt_errstr(status));
2188 printf("Testing LookupRids\n");
2189 lr.in.domain_handle = handle;
2190 lr.in.num_rids = r.out.sam->count;
2191 lr.in.rids = talloc_array(mem_ctx, uint32_t, r.out.sam->count);
2192 for (i=0;i<r.out.sam->count;i++) {
2193 lr.in.rids[i] = r.out.sam->entries[i].idx;
2195 status = dcerpc_samr_LookupRids(p, mem_ctx, &lr);
2196 if (!NT_STATUS_IS_OK(status)) {
2197 printf("LookupRids failed - %s\n", nt_errstr(status));
2205 try blasting the server with a bunch of sync requests
2207 static BOOL test_EnumDomainUsers_async(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2208 struct policy_handle *handle)
2211 struct samr_EnumDomainUsers r;
2212 uint32_t resume_handle=0;
2214 #define ASYNC_COUNT 100
2215 struct rpc_request *req[ASYNC_COUNT];
2217 if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
2218 printf("samr async test disabled - enable dangerous tests to use\n");
2222 printf("Testing EnumDomainUsers_async\n");
2224 r.in.domain_handle = handle;
2225 r.in.resume_handle = &resume_handle;
2226 r.in.acct_flags = 0;
2227 r.in.max_size = (uint32_t)-1;
2228 r.out.resume_handle = &resume_handle;
2230 for (i=0;i<ASYNC_COUNT;i++) {
2231 req[i] = dcerpc_samr_EnumDomainUsers_send(p, mem_ctx, &r);
2234 for (i=0;i<ASYNC_COUNT;i++) {
2235 status = dcerpc_ndr_request_recv(req[i]);
2236 if (!NT_STATUS_IS_OK(status)) {
2237 printf("EnumDomainUsers[%d] failed - %s\n",
2238 i, nt_errstr(status));
2243 printf("%d async requests OK\n", i);
2248 static BOOL test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2249 struct policy_handle *handle)
2252 struct samr_EnumDomainGroups r;
2253 uint32_t resume_handle=0;
2257 printf("Testing EnumDomainGroups\n");
2259 r.in.domain_handle = handle;
2260 r.in.resume_handle = &resume_handle;
2261 r.in.max_size = (uint32_t)-1;
2262 r.out.resume_handle = &resume_handle;
2264 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
2265 if (!NT_STATUS_IS_OK(status)) {
2266 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
2274 for (i=0;i<r.out.sam->count;i++) {
2275 if (!test_OpenGroup(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
2283 static BOOL test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2284 struct policy_handle *handle)
2287 struct samr_EnumDomainAliases r;
2288 uint32_t resume_handle=0;
2292 printf("Testing EnumDomainAliases\n");
2294 r.in.domain_handle = handle;
2295 r.in.resume_handle = &resume_handle;
2296 r.in.acct_flags = (uint32_t)-1;
2297 r.out.resume_handle = &resume_handle;
2299 status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
2300 if (!NT_STATUS_IS_OK(status)) {
2301 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
2309 for (i=0;i<r.out.sam->count;i++) {
2310 if (!test_OpenAlias(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
2318 static BOOL test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2319 struct policy_handle *handle)
2322 struct samr_GetDisplayEnumerationIndex r;
2324 uint16_t levels[] = {1, 2, 3, 4, 5};
2325 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
2328 for (i=0;i<ARRAY_SIZE(levels);i++) {
2329 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
2331 r.in.domain_handle = handle;
2332 r.in.level = levels[i];
2333 init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
2335 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
2338 !NT_STATUS_IS_OK(status) &&
2339 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2340 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
2341 levels[i], nt_errstr(status));
2345 init_lsa_String(&r.in.name, "zzzzzzzz");
2347 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
2349 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2350 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
2351 levels[i], nt_errstr(status));
2359 static BOOL test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2360 struct policy_handle *handle)
2363 struct samr_GetDisplayEnumerationIndex2 r;
2365 uint16_t levels[] = {1, 2, 3, 4, 5};
2366 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
2369 for (i=0;i<ARRAY_SIZE(levels);i++) {
2370 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
2372 r.in.domain_handle = handle;
2373 r.in.level = levels[i];
2374 init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
2376 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
2378 !NT_STATUS_IS_OK(status) &&
2379 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2380 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
2381 levels[i], nt_errstr(status));
2385 init_lsa_String(&r.in.name, "zzzzzzzz");
2387 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
2388 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2389 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
2390 levels[i], nt_errstr(status));
2398 static BOOL test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2399 struct policy_handle *handle)
2402 struct samr_QueryDisplayInfo r;
2404 uint16_t levels[] = {1, 2, 3, 4, 5};
2407 for (i=0;i<ARRAY_SIZE(levels);i++) {
2408 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
2410 r.in.domain_handle = handle;
2411 r.in.level = levels[i];
2413 r.in.max_entries = 1000;
2414 r.in.buf_size = (uint32_t)-1;
2416 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
2417 if (!NT_STATUS_IS_OK(status)) {
2418 printf("QueryDisplayInfo level %u failed - %s\n",
2419 levels[i], nt_errstr(status));
2427 static BOOL test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2428 struct policy_handle *handle)
2431 struct samr_QueryDisplayInfo2 r;
2433 uint16_t levels[] = {1, 2, 3, 4, 5};
2436 for (i=0;i<ARRAY_SIZE(levels);i++) {
2437 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
2439 r.in.domain_handle = handle;
2440 r.in.level = levels[i];
2442 r.in.max_entries = 1000;
2443 r.in.buf_size = (uint32_t)-1;
2445 status = dcerpc_samr_QueryDisplayInfo2(p, mem_ctx, &r);
2446 if (!NT_STATUS_IS_OK(status)) {
2447 printf("QueryDisplayInfo2 level %u failed - %s\n",
2448 levels[i], nt_errstr(status));
2456 static BOOL test_QueryDisplayInfo3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2457 struct policy_handle *handle)
2460 struct samr_QueryDisplayInfo3 r;
2462 uint16_t levels[] = {1, 2, 3, 4, 5};
2465 for (i=0;i<ARRAY_SIZE(levels);i++) {
2466 printf("Testing QueryDisplayInfo3 level %u\n", levels[i]);
2468 r.in.domain_handle = handle;
2469 r.in.level = levels[i];
2471 r.in.max_entries = 1000;
2472 r.in.buf_size = (uint32_t)-1;
2474 status = dcerpc_samr_QueryDisplayInfo3(p, mem_ctx, &r);
2475 if (!NT_STATUS_IS_OK(status)) {
2476 printf("QueryDisplayInfo3 level %u failed - %s\n",
2477 levels[i], nt_errstr(status));
2486 static BOOL test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2487 struct policy_handle *handle)
2490 struct samr_QueryDisplayInfo r;
2493 printf("Testing QueryDisplayInfo continuation\n");
2495 r.in.domain_handle = handle;
2498 r.in.max_entries = 1;
2499 r.in.buf_size = (uint32_t)-1;
2502 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
2503 if (NT_STATUS_IS_OK(status) && r.out.returned_size != 0) {
2504 if (r.out.info.info1.entries[0].idx != r.in.start_idx + 1) {
2505 printf("failed: expected idx %d but got %d\n",
2507 r.out.info.info1.entries[0].idx);
2512 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
2513 !NT_STATUS_IS_OK(status)) {
2514 printf("QueryDisplayInfo level %u failed - %s\n",
2515 r.in.level, nt_errstr(status));
2520 } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
2521 NT_STATUS_IS_OK(status)) &&
2522 r.out.returned_size != 0);
2527 static BOOL test_QueryDomainInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2528 struct policy_handle *handle)
2531 struct samr_QueryDomainInfo r;
2532 struct samr_SetDomainInfo s;
2533 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
2534 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
2538 for (i=0;i<ARRAY_SIZE(levels);i++) {
2539 printf("Testing QueryDomainInfo level %u\n", levels[i]);
2541 r.in.domain_handle = handle;
2542 r.in.level = levels[i];
2544 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2545 if (!NT_STATUS_IS_OK(status)) {
2546 printf("QueryDomainInfo level %u failed - %s\n",
2547 r.in.level, nt_errstr(status));
2552 printf("Testing SetDomainInfo level %u\n", levels[i]);
2554 s.in.domain_handle = handle;
2555 s.in.level = levels[i];
2556 s.in.info = r.out.info;
2558 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2560 if (!NT_STATUS_IS_OK(status)) {
2561 printf("SetDomainInfo level %u failed - %s\n",
2562 r.in.level, nt_errstr(status));
2567 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
2568 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
2569 r.in.level, nt_errstr(status));
2575 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2576 if (!NT_STATUS_IS_OK(status)) {
2577 printf("QueryDomainInfo level %u failed - %s\n",
2578 r.in.level, nt_errstr(status));
2588 static BOOL test_QueryDomainInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2589 struct policy_handle *handle)
2592 struct samr_QueryDomainInfo2 r;
2593 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
2597 for (i=0;i<ARRAY_SIZE(levels);i++) {
2598 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
2600 r.in.domain_handle = handle;
2601 r.in.level = levels[i];
2603 status = dcerpc_samr_QueryDomainInfo2(p, mem_ctx, &r);
2604 if (!NT_STATUS_IS_OK(status)) {
2605 printf("QueryDomainInfo2 level %u failed - %s\n",
2606 r.in.level, nt_errstr(status));
2615 /* Test whether querydispinfo level 5 and enumdomgroups return the same
2616 set of group names. */
2617 static BOOL test_GroupList(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2618 struct policy_handle *handle)
2620 struct samr_EnumDomainGroups q1;
2621 struct samr_QueryDisplayInfo q2;
2623 uint32_t resume_handle=0;
2628 const char **names = NULL;
2630 printf("Testing coherency of querydispinfo vs enumdomgroups\n");
2632 q1.in.domain_handle = handle;
2633 q1.in.resume_handle = &resume_handle;
2635 q1.out.resume_handle = &resume_handle;
2637 status = STATUS_MORE_ENTRIES;
2638 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
2639 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &q1);
2641 if (!NT_STATUS_IS_OK(status) &&
2642 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
2645 for (i=0; i<q1.out.num_entries; i++) {
2646 add_string_to_array(mem_ctx,
2647 q1.out.sam->entries[i].name.string,
2648 &names, &num_names);
2652 if (!NT_STATUS_IS_OK(status)) {
2653 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
2661 q2.in.domain_handle = handle;
2663 q2.in.start_idx = 0;
2664 q2.in.max_entries = 5;
2665 q2.in.buf_size = (uint32_t)-1;
2667 status = STATUS_MORE_ENTRIES;
2668 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
2669 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &q2);
2671 if (!NT_STATUS_IS_OK(status) &&
2672 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
2675 for (i=0; i<q2.out.info.info5.count; i++) {
2677 const char *name = q2.out.info.info5.entries[i].account_name.string;
2679 for (j=0; j<num_names; j++) {
2680 if (names[j] == NULL)
2682 /* Hmm. No strequal in samba4 */
2683 if (strequal(names[j], name)) {
2691 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
2696 q2.in.start_idx += q2.out.info.info5.count;
2699 if (!NT_STATUS_IS_OK(status)) {
2700 printf("QueryDisplayInfo level 5 failed - %s\n",
2705 for (i=0; i<num_names; i++) {
2706 if (names[i] != NULL) {
2707 printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
2716 static BOOL test_DeleteDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2717 struct policy_handle *group_handle)
2719 struct samr_DeleteDomainGroup d;
2723 printf("Testing DeleteDomainGroup\n");
2725 d.in.group_handle = group_handle;
2726 d.out.group_handle = group_handle;
2728 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
2729 if (!NT_STATUS_IS_OK(status)) {
2730 printf("DeleteDomainGroup failed - %s\n", nt_errstr(status));
2737 static BOOL test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2738 struct policy_handle *domain_handle)
2740 struct samr_TestPrivateFunctionsDomain r;
2744 printf("Testing TestPrivateFunctionsDomain\n");
2746 r.in.domain_handle = domain_handle;
2748 status = dcerpc_samr_TestPrivateFunctionsDomain(p, mem_ctx, &r);
2749 if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
2750 printf("TestPrivateFunctionsDomain failed - %s\n", nt_errstr(status));
2757 static BOOL test_RidToSid(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2758 struct dom_sid *domain_sid,
2759 struct policy_handle *domain_handle)
2761 struct samr_RidToSid r;
2764 struct dom_sid *calc_sid;
2765 int rids[] = { 0, 42, 512, 10200 };
2768 for (i=0;i<ARRAY_SIZE(rids);i++) {
2770 printf("Testing RidToSid\n");
2772 calc_sid = dom_sid_dup(mem_ctx, domain_sid);
2773 r.in.domain_handle = domain_handle;
2776 status = dcerpc_samr_RidToSid(p, mem_ctx, &r);
2777 if (!NT_STATUS_IS_OK(status)) {
2778 printf("RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
2781 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
2783 if (!dom_sid_equal(calc_sid, r.out.sid)) {
2784 printf("RidToSid for %d failed - got %s, expected %s\n", rids[i],
2785 dom_sid_string(mem_ctx, r.out.sid),
2786 dom_sid_string(mem_ctx, calc_sid));
2795 static BOOL test_GetBootKeyInformation(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2796 struct policy_handle *domain_handle)
2798 struct samr_GetBootKeyInformation r;
2802 printf("Testing GetBootKeyInformation\n");
2804 r.in.domain_handle = domain_handle;
2806 status = dcerpc_samr_GetBootKeyInformation(p, mem_ctx, &r);
2807 if (!NT_STATUS_IS_OK(status)) {
2808 /* w2k3 seems to fail this sometimes and pass it sometimes */
2809 printf("GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
2815 static BOOL test_AddGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2816 struct policy_handle *domain_handle,
2817 struct policy_handle *group_handle)
2820 struct samr_AddGroupMember r;
2821 struct samr_DeleteGroupMember d;
2822 struct samr_QueryGroupMember q;
2823 struct samr_SetMemberAttributesOfGroup s;
2827 status = test_LookupName(p, mem_ctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
2828 if (!NT_STATUS_IS_OK(status)) {
2832 r.in.group_handle = group_handle;
2834 r.in.flags = 0; /* ??? */
2836 printf("Testing AddGroupMember and DeleteGroupMember\n");
2838 d.in.group_handle = group_handle;
2841 status = dcerpc_samr_DeleteGroupMember(p, mem_ctx, &d);
2842 if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_NOT_IN_GROUP, status)) {
2843 printf("DeleteGroupMember gave %s - should be NT_STATUS_MEMBER_NOT_IN_GROUP\n",
2848 status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
2849 if (!NT_STATUS_IS_OK(status)) {
2850 printf("AddGroupMember failed - %s\n", nt_errstr(status));
2854 status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
2855 if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_IN_GROUP, status)) {
2856 printf("AddGroupMember gave %s - should be NT_STATUS_MEMBER_IN_GROUP\n",
2861 /* this one is quite strange. I am using random inputs in the
2862 hope of triggering an error that might give us a clue */
2863 s.in.group_handle = group_handle;
2864 s.in.unknown1 = random();
2865 s.in.unknown2 = random();
2867 status = dcerpc_samr_SetMemberAttributesOfGroup(p, mem_ctx, &s);
2868 if (!NT_STATUS_IS_OK(status)) {
2869 printf("SetMemberAttributesOfGroup failed - %s\n", nt_errstr(status));
2873 q.in.group_handle = group_handle;
2875 status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &q);
2876 if (!NT_STATUS_IS_OK(status)) {
2877 printf("QueryGroupMember failed - %s\n", nt_errstr(status));
2881 status = dcerpc_samr_DeleteGroupMember(p, mem_ctx, &d);
2882 if (!NT_STATUS_IS_OK(status)) {
2883 printf("DeleteGroupMember failed - %s\n", nt_errstr(status));
2887 status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
2888 if (!NT_STATUS_IS_OK(status)) {
2889 printf("AddGroupMember failed - %s\n", nt_errstr(status));
2897 static BOOL test_CreateDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2898 struct policy_handle *domain_handle, struct policy_handle *group_handle)
2901 struct samr_CreateDomainGroup r;
2903 struct lsa_String name;
2906 init_lsa_String(&name, TEST_GROUPNAME);
2908 r.in.domain_handle = domain_handle;
2910 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2911 r.out.group_handle = group_handle;
2914 printf("Testing CreateDomainGroup(%s)\n", r.in.name->string);
2916 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
2918 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2919 printf("Server refused create of '%s'\n", r.in.name->string);
2920 ZERO_STRUCTP(group_handle);
2924 if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS) ||
2925 NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
2926 if (!test_DeleteGroup_byname(p, mem_ctx, domain_handle, r.in.name->string)) {
2929 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
2931 if (!NT_STATUS_IS_OK(status)) {
2932 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
2936 if (!test_AddGroupMember(p, mem_ctx, domain_handle, group_handle)) {
2940 if (!test_SetGroupInfo(p, mem_ctx, group_handle)) {
2949 its not totally clear what this does. It seems to accept any sid you like.
2951 static BOOL test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p,
2952 TALLOC_CTX *mem_ctx,
2953 struct policy_handle *domain_handle)
2956 struct samr_RemoveMemberFromForeignDomain r;
2958 r.in.domain_handle = domain_handle;
2959 r.in.sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-12-34-56-78");
2961 status = dcerpc_samr_RemoveMemberFromForeignDomain(p, mem_ctx, &r);
2962 if (!NT_STATUS_IS_OK(status)) {
2963 printf("RemoveMemberFromForeignDomain failed - %s\n", nt_errstr(status));
2972 static BOOL test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2973 struct policy_handle *handle);
2975 static BOOL test_OpenDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2976 struct policy_handle *handle, struct dom_sid *sid)
2979 struct samr_OpenDomain r;
2980 struct policy_handle domain_handle;
2981 struct policy_handle user_handle;
2982 struct policy_handle alias_handle;
2983 struct policy_handle group_handle;
2986 ZERO_STRUCT(user_handle);
2987 ZERO_STRUCT(alias_handle);
2988 ZERO_STRUCT(group_handle);
2989 ZERO_STRUCT(domain_handle);
2991 printf("Testing OpenDomain\n");
2993 r.in.connect_handle = handle;
2994 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2996 r.out.domain_handle = &domain_handle;
2998 status = dcerpc_samr_OpenDomain(p, mem_ctx, &r);
2999 if (!NT_STATUS_IS_OK(status)) {
3000 printf("OpenDomain failed - %s\n", nt_errstr(status));
3004 /* run the domain tests with the main handle closed - this tests
3005 the servers reference counting */
3006 ret &= test_samr_handle_Close(p, mem_ctx, handle);
3008 ret &= test_QuerySecurity(p, mem_ctx, &domain_handle);
3009 ret &= test_RemoveMemberFromForeignDomain(p, mem_ctx, &domain_handle);
3010 ret &= test_CreateUser2(p, mem_ctx, &domain_handle);
3011 ret &= test_CreateUser(p, mem_ctx, &domain_handle, &user_handle);
3012 ret &= test_CreateAlias(p, mem_ctx, &domain_handle, &alias_handle, sid);
3013 ret &= test_CreateDomainGroup(p, mem_ctx, &domain_handle, &group_handle);
3014 ret &= test_QueryDomainInfo(p, mem_ctx, &domain_handle);
3015 ret &= test_QueryDomainInfo2(p, mem_ctx, &domain_handle);
3016 ret &= test_EnumDomainUsers(p, mem_ctx, &domain_handle);
3017 ret &= test_EnumDomainUsers_async(p, mem_ctx, &domain_handle);
3018 ret &= test_EnumDomainGroups(p, mem_ctx, &domain_handle);
3019 ret &= test_EnumDomainAliases(p, mem_ctx, &domain_handle);
3020 ret &= test_QueryDisplayInfo(p, mem_ctx, &domain_handle);
3021 ret &= test_QueryDisplayInfo2(p, mem_ctx, &domain_handle);
3022 ret &= test_QueryDisplayInfo3(p, mem_ctx, &domain_handle);
3023 ret &= test_QueryDisplayInfo_continue(p, mem_ctx, &domain_handle);
3024 ret &= test_GetDisplayEnumerationIndex(p, mem_ctx, &domain_handle);
3025 ret &= test_GetDisplayEnumerationIndex2(p, mem_ctx, &domain_handle);
3026 ret &= test_GroupList(p, mem_ctx, &domain_handle);
3027 ret &= test_TestPrivateFunctionsDomain(p, mem_ctx, &domain_handle);
3028 ret &= test_RidToSid(p, mem_ctx, sid, &domain_handle);
3029 ret &= test_GetBootKeyInformation(p, mem_ctx, &domain_handle);
3031 if (!policy_handle_empty(&user_handle) &&
3032 !test_DeleteUser(p, mem_ctx, &user_handle)) {
3036 if (!policy_handle_empty(&alias_handle) &&
3037 !test_DeleteAlias(p, mem_ctx, &alias_handle)) {
3041 if (!policy_handle_empty(&group_handle) &&
3042 !test_DeleteDomainGroup(p, mem_ctx, &group_handle)) {
3046 ret &= test_samr_handle_Close(p, mem_ctx, &domain_handle);
3048 /* reconnect the main handle */
3049 ret &= test_Connect(p, mem_ctx, handle);
3054 static BOOL test_LookupDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3055 struct policy_handle *handle, struct lsa_String *domain)
3058 struct samr_LookupDomain r;
3059 struct lsa_String n2;
3062 printf("Testing LookupDomain(%s)\n", domain->string);
3064 /* check for correct error codes */
3065 r.in.connect_handle = handle;
3066 r.in.domain_name = &n2;
3069 status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
3070 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_PARAMETER, status)) {
3071 printf("failed: LookupDomain expected NT_STATUS_INVALID_PARAMETER - %s\n", nt_errstr(status));
3075 n2.string = "xxNODOMAINxx";
3077 status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
3078 if (!NT_STATUS_EQUAL(NT_STATUS_NO_SUCH_DOMAIN, status)) {
3079 printf("failed: LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN - %s\n", nt_errstr(status));
3083 r.in.connect_handle = handle;
3084 r.in.domain_name = domain;
3086 status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
3087 if (!NT_STATUS_IS_OK(status)) {
3088 printf("LookupDomain failed - %s\n", nt_errstr(status));
3092 if (!test_GetDomPwInfo(p, mem_ctx, domain)) {
3096 if (!test_OpenDomain(p, mem_ctx, handle, r.out.sid)) {
3104 static BOOL test_EnumDomains(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3105 struct policy_handle *handle)
3108 struct samr_EnumDomains r;
3109 uint32_t resume_handle = 0;
3113 r.in.connect_handle = handle;
3114 r.in.resume_handle = &resume_handle;
3115 r.in.buf_size = (uint32_t)-1;
3116 r.out.resume_handle = &resume_handle;
3118 status = dcerpc_samr_EnumDomains(p, mem_ctx, &r);
3119 if (!NT_STATUS_IS_OK(status)) {
3120 printf("EnumDomains failed - %s\n", nt_errstr(status));
3128 for (i=0;i<r.out.sam->count;i++) {
3129 if (!test_LookupDomain(p, mem_ctx, handle,
3130 &r.out.sam->entries[i].name)) {
3135 status = dcerpc_samr_EnumDomains(p, mem_ctx, &r);
3136 if (!NT_STATUS_IS_OK(status)) {
3137 printf("EnumDomains failed - %s\n", nt_errstr(status));
3145 static BOOL test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3146 struct policy_handle *handle)
3149 struct samr_Connect r;
3150 struct samr_Connect2 r2;
3151 struct samr_Connect3 r3;
3152 struct samr_Connect4 r4;
3153 struct samr_Connect5 r5;
3154 union samr_ConnectInfo info;
3155 struct policy_handle h;
3156 BOOL ret = True, got_handle = False;
3158 printf("testing samr_Connect\n");
3160 r.in.system_name = 0;
3161 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3162 r.out.connect_handle = &h;
3164 status = dcerpc_samr_Connect(p, mem_ctx, &r);
3165 if (!NT_STATUS_IS_OK(status)) {
3166 printf("Connect failed - %s\n", nt_errstr(status));
3173 printf("testing samr_Connect2\n");
3175 r2.in.system_name = NULL;
3176 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3177 r2.out.connect_handle = &h;
3179 status = dcerpc_samr_Connect2(p, mem_ctx, &r2);
3180 if (!NT_STATUS_IS_OK(status)) {
3181 printf("Connect2 failed - %s\n", nt_errstr(status));
3185 test_samr_handle_Close(p, mem_ctx, handle);
3191 printf("testing samr_Connect3\n");
3193 r3.in.system_name = NULL;
3195 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3196 r3.out.connect_handle = &h;
3198 status = dcerpc_samr_Connect3(p, mem_ctx, &r3);
3199 if (!NT_STATUS_IS_OK(status)) {
3200 printf("Connect3 failed - %s\n", nt_errstr(status));
3204 test_samr_handle_Close(p, mem_ctx, handle);
3210 printf("testing samr_Connect4\n");
3212 r4.in.system_name = "";
3214 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3215 r4.out.connect_handle = &h;
3217 status = dcerpc_samr_Connect4(p, mem_ctx, &r4);
3218 if (!NT_STATUS_IS_OK(status)) {
3219 printf("Connect4 failed - %s\n", nt_errstr(status));
3223 test_samr_handle_Close(p, mem_ctx, handle);
3229 printf("testing samr_Connect5\n");
3231 info.info1.unknown1 = 0;
3232 info.info1.unknown2 = 0;
3234 r5.in.system_name = "";
3235 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3238 r5.out.info = &info;
3239 r5.out.connect_handle = &h;
3241 status = dcerpc_samr_Connect5(p, mem_ctx, &r5);
3242 if (!NT_STATUS_IS_OK(status)) {
3243 printf("Connect5 failed - %s\n", nt_errstr(status));
3247 test_samr_handle_Close(p, mem_ctx, handle);
3257 BOOL torture_rpc_samr(void)
3260 struct dcerpc_pipe *p;
3261 TALLOC_CTX *mem_ctx;
3263 struct policy_handle handle;
3265 mem_ctx = talloc_init("torture_rpc_samr");
3267 status = torture_rpc_connection(mem_ctx,
3271 DCERPC_SAMR_VERSION);
3272 if (!NT_STATUS_IS_OK(status)) {
3273 talloc_free(mem_ctx);
3277 if (!test_Connect(p, mem_ctx, &handle)) {
3281 if (!test_QuerySecurity(p, mem_ctx, &handle)) {
3285 if (!test_EnumDomains(p, mem_ctx, &handle)) {
3289 if (!test_SetDsrmPassword(p, mem_ctx, &handle)) {
3293 if (!test_Shutdown(p, mem_ctx, &handle)) {
3297 if (!test_samr_handle_Close(p, mem_ctx, &handle)) {
3301 talloc_free(mem_ctx);