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_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
948 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
949 } else if (!NT_STATUS_IS_OK(status)) {
950 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
956 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
964 static BOOL test_OemChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
965 struct policy_handle *handle, char **password)
968 struct samr_OemChangePasswordUser2 r;
970 struct samr_Password lm_verifier;
971 struct samr_CryptPassword lm_pass;
972 struct lsa_AsciiString server, account, account_bad;
973 char *oldpass = *password;
975 uint8_t old_lm_hash[16], new_lm_hash[16];
977 struct samr_GetDomPwInfo dom_pw_info;
978 int policy_min_pw_len = 0;
980 struct lsa_String domain_name;
981 domain_name.string = "";
982 dom_pw_info.in.domain_name = &domain_name;
984 printf("Testing OemChangePasswordUser2\n");
986 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &dom_pw_info);
987 if (NT_STATUS_IS_OK(status)) {
988 policy_min_pw_len = dom_pw_info.out.info.min_password_length;
991 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
993 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
994 account.string = TEST_ACCOUNT_NAME;
996 E_deshash(oldpass, old_lm_hash);
997 E_deshash(newpass, new_lm_hash);
999 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1000 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1001 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1003 r.in.server = &server;
1004 r.in.account = &account;
1005 r.in.password = &lm_pass;
1006 r.in.hash = &lm_verifier;
1008 /* Break the verification */
1009 lm_verifier.hash[0]++;
1011 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1013 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1014 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1015 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1020 /* This shouldn't be a valid name */
1021 account_bad.string = TEST_ACCOUNT_NAME "XX";
1022 r.in.account = &account_bad;
1024 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1026 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1027 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1032 E_deshash(oldpass, old_lm_hash);
1033 E_deshash(newpass, new_lm_hash);
1035 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1036 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1037 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1039 r.in.server = &server;
1040 r.in.account = &account;
1041 r.in.password = &lm_pass;
1042 r.in.hash = &lm_verifier;
1044 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1045 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1046 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1047 } else if (!NT_STATUS_IS_OK(status)) {
1048 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
1051 *password = newpass;
1058 static BOOL test_ChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1059 struct policy_handle *handle, char **password)
1062 struct samr_ChangePasswordUser2 r;
1064 struct lsa_String server, account;
1065 struct samr_CryptPassword nt_pass, lm_pass;
1066 struct samr_Password nt_verifier, lm_verifier;
1067 char *oldpass = *password;
1069 uint8_t old_nt_hash[16], new_nt_hash[16];
1070 uint8_t old_lm_hash[16], new_lm_hash[16];
1072 struct samr_GetDomPwInfo dom_pw_info;
1073 int policy_min_pw_len = 0;
1075 struct lsa_String domain_name;
1076 domain_name.string = "";
1077 dom_pw_info.in.domain_name = &domain_name;
1079 printf("Testing ChangePasswordUser2\n");
1081 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &dom_pw_info);
1082 if (NT_STATUS_IS_OK(status)) {
1083 policy_min_pw_len = dom_pw_info.out.info.min_password_length;
1086 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1088 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1089 init_lsa_String(&account, TEST_ACCOUNT_NAME);
1091 E_md4hash(oldpass, old_nt_hash);
1092 E_md4hash(newpass, new_nt_hash);
1094 E_deshash(oldpass, old_lm_hash);
1095 E_deshash(newpass, new_lm_hash);
1097 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
1098 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1099 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1101 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1102 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1103 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1105 r.in.server = &server;
1106 r.in.account = &account;
1107 r.in.nt_password = &nt_pass;
1108 r.in.nt_verifier = &nt_verifier;
1110 r.in.lm_password = &lm_pass;
1111 r.in.lm_verifier = &lm_verifier;
1113 status = dcerpc_samr_ChangePasswordUser2(p, mem_ctx, &r);
1114 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1115 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1116 } else if (!NT_STATUS_IS_OK(status)) {
1117 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
1120 *password = newpass;
1127 BOOL test_ChangePasswordUser3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1128 const char *account_string,
1129 int policy_min_pw_len,
1133 struct samr_ChangePasswordUser3 r;
1135 struct lsa_String server, account, account_bad;
1136 struct samr_CryptPassword nt_pass, lm_pass;
1137 struct samr_Password nt_verifier, lm_verifier;
1138 char *oldpass = *password;
1139 char *newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1140 uint8_t old_nt_hash[16], new_nt_hash[16];
1141 uint8_t old_lm_hash[16], new_lm_hash[16];
1143 printf("Testing ChangePasswordUser3\n");
1145 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1146 init_lsa_String(&account, account_string);
1148 E_md4hash(oldpass, old_nt_hash);
1149 E_md4hash(newpass, new_nt_hash);
1151 E_deshash(oldpass, old_lm_hash);
1152 E_deshash(newpass, new_lm_hash);
1154 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1155 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1156 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1158 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1159 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1160 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1162 /* Break the verification */
1163 nt_verifier.hash[0]++;
1165 r.in.server = &server;
1166 r.in.account = &account;
1167 r.in.nt_password = &nt_pass;
1168 r.in.nt_verifier = &nt_verifier;
1170 r.in.lm_password = &lm_pass;
1171 r.in.lm_verifier = &lm_verifier;
1172 r.in.password3 = NULL;
1174 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1175 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1176 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1177 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1182 /* This shouldn't be a valid name */
1183 init_lsa_String(&account_bad, talloc_asprintf(mem_ctx, "%sXX", account_string));
1185 r.in.account = &account_bad;
1186 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1187 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1188 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
1193 E_md4hash(oldpass, old_nt_hash);
1194 E_md4hash(newpass, new_nt_hash);
1196 E_deshash(oldpass, old_lm_hash);
1197 E_deshash(newpass, new_lm_hash);
1199 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1200 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1201 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1203 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1204 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1205 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1207 r.in.server = &server;
1208 r.in.account = &account;
1209 r.in.nt_password = &nt_pass;
1210 r.in.nt_verifier = &nt_verifier;
1212 r.in.lm_password = &lm_pass;
1213 r.in.lm_verifier = &lm_verifier;
1214 r.in.password3 = NULL;
1216 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1217 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1218 && !policy_min_pw_len) {
1219 if (r.out.dominfo) {
1220 policy_min_pw_len = r.out.dominfo->min_password_length;
1222 if (policy_min_pw_len) /* try again with the right min password length */ {
1223 ret = test_ChangePasswordUser3(p, mem_ctx, account_string, policy_min_pw_len, password);
1225 printf("ChangePasswordUser3 failed (no min length known) - %s\n", nt_errstr(status));
1228 } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1229 printf("ChangePasswordUser3 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1230 } else if (!NT_STATUS_IS_OK(status)) {
1231 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
1234 *password = newpass;
1241 static BOOL test_GetMembersInAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1242 struct policy_handle *alias_handle)
1244 struct samr_GetMembersInAlias r;
1245 struct lsa_SidArray sids;
1249 printf("Testing GetMembersInAlias\n");
1251 r.in.alias_handle = alias_handle;
1254 status = dcerpc_samr_GetMembersInAlias(p, mem_ctx, &r);
1255 if (!NT_STATUS_IS_OK(status)) {
1256 printf("GetMembersInAlias failed - %s\n",
1264 static BOOL test_AddMemberToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1265 struct policy_handle *alias_handle,
1266 const struct dom_sid *domain_sid)
1268 struct samr_AddAliasMember r;
1269 struct samr_DeleteAliasMember d;
1272 struct dom_sid *sid;
1274 sid = dom_sid_add_rid(mem_ctx, domain_sid, 512);
1276 printf("testing AddAliasMember\n");
1277 r.in.alias_handle = alias_handle;
1280 status = dcerpc_samr_AddAliasMember(p, mem_ctx, &r);
1281 if (!NT_STATUS_IS_OK(status)) {
1282 printf("AddAliasMember failed - %s\n", nt_errstr(status));
1286 d.in.alias_handle = alias_handle;
1289 status = dcerpc_samr_DeleteAliasMember(p, mem_ctx, &d);
1290 if (!NT_STATUS_IS_OK(status)) {
1291 printf("DelAliasMember failed - %s\n", nt_errstr(status));
1298 static BOOL test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1299 struct policy_handle *alias_handle)
1301 struct samr_AddMultipleMembersToAlias a;
1302 struct samr_RemoveMultipleMembersFromAlias r;
1305 struct lsa_SidArray sids;
1307 printf("testing AddMultipleMembersToAlias\n");
1308 a.in.alias_handle = alias_handle;
1312 sids.sids = talloc_array(mem_ctx, struct lsa_SidPtr, 3);
1314 sids.sids[0].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-1");
1315 sids.sids[1].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-2");
1316 sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-3");
1318 status = dcerpc_samr_AddMultipleMembersToAlias(p, mem_ctx, &a);
1319 if (!NT_STATUS_IS_OK(status)) {
1320 printf("AddMultipleMembersToAlias failed - %s\n", nt_errstr(status));
1325 printf("testing RemoveMultipleMembersFromAlias\n");
1326 r.in.alias_handle = alias_handle;
1329 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1330 if (!NT_STATUS_IS_OK(status)) {
1331 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1335 /* strange! removing twice doesn't give any error */
1336 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1337 if (!NT_STATUS_IS_OK(status)) {
1338 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1342 /* but removing an alias that isn't there does */
1343 sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-4");
1345 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1346 if (!NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_NOT_FOUND, status)) {
1347 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1354 static BOOL test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1355 struct policy_handle *user_handle)
1357 struct samr_TestPrivateFunctionsUser r;
1361 printf("Testing TestPrivateFunctionsUser\n");
1363 r.in.user_handle = user_handle;
1365 status = dcerpc_samr_TestPrivateFunctionsUser(p, mem_ctx, &r);
1366 if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
1367 printf("TestPrivateFunctionsUser failed - %s\n", nt_errstr(status));
1375 static BOOL test_user_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1376 struct policy_handle *handle, uint32_t base_acct_flags,
1377 const char *base_acct_name)
1381 if (!test_QuerySecurity(p, mem_ctx, handle)) {
1385 if (!test_QueryUserInfo(p, mem_ctx, handle)) {
1389 if (!test_QueryUserInfo2(p, mem_ctx, handle)) {
1393 if (!test_SetUserInfo(p, mem_ctx, handle, base_acct_flags,
1398 if (!test_GetUserPwInfo(p, mem_ctx, handle)) {
1402 if (!test_TestPrivateFunctionsUser(p, mem_ctx, handle)) {
1409 static BOOL test_alias_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1410 struct policy_handle *alias_handle,
1411 const struct dom_sid *domain_sid)
1415 if (!test_QuerySecurity(p, mem_ctx, alias_handle)) {
1419 if (!test_QueryAliasInfo(p, mem_ctx, alias_handle)) {
1423 if (!test_SetAliasInfo(p, mem_ctx, alias_handle)) {
1427 if (!test_AddMemberToAlias(p, mem_ctx, alias_handle, domain_sid)) {
1431 if (!test_AddMultipleMembersToAlias(p, mem_ctx, alias_handle)) {
1439 BOOL test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1440 struct policy_handle *handle, const char *name)
1443 struct samr_DeleteUser d;
1444 struct policy_handle user_handle;
1447 status = test_LookupName(p, mem_ctx, handle, name, &rid);
1448 if (!NT_STATUS_IS_OK(status)) {
1452 status = test_OpenUser_byname(p, mem_ctx, handle, name, &user_handle);
1453 if (!NT_STATUS_IS_OK(status)) {
1457 d.in.user_handle = &user_handle;
1458 d.out.user_handle = &user_handle;
1459 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
1460 if (!NT_STATUS_IS_OK(status)) {
1467 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
1472 static BOOL test_DeleteGroup_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1473 struct policy_handle *handle, const char *name)
1476 struct samr_OpenGroup r;
1477 struct samr_DeleteDomainGroup d;
1478 struct policy_handle group_handle;
1481 status = test_LookupName(p, mem_ctx, handle, name, &rid);
1482 if (!NT_STATUS_IS_OK(status)) {
1486 r.in.domain_handle = handle;
1487 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1489 r.out.group_handle = &group_handle;
1490 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
1491 if (!NT_STATUS_IS_OK(status)) {
1495 d.in.group_handle = &group_handle;
1496 d.out.group_handle = &group_handle;
1497 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
1498 if (!NT_STATUS_IS_OK(status)) {
1505 printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
1510 static BOOL test_DeleteAlias_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1511 struct policy_handle *domain_handle, const char *name)
1514 struct samr_OpenAlias r;
1515 struct samr_DeleteDomAlias d;
1516 struct policy_handle alias_handle;
1519 printf("testing DeleteAlias_byname\n");
1521 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
1522 if (!NT_STATUS_IS_OK(status)) {
1526 r.in.domain_handle = domain_handle;
1527 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1529 r.out.alias_handle = &alias_handle;
1530 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
1531 if (!NT_STATUS_IS_OK(status)) {
1535 d.in.alias_handle = &alias_handle;
1536 d.out.alias_handle = &alias_handle;
1537 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
1538 if (!NT_STATUS_IS_OK(status)) {
1545 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
1549 static BOOL test_DeleteAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1550 struct policy_handle *alias_handle)
1552 struct samr_DeleteDomAlias d;
1555 printf("Testing DeleteAlias\n");
1557 d.in.alias_handle = alias_handle;
1558 d.out.alias_handle = alias_handle;
1560 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
1561 if (!NT_STATUS_IS_OK(status)) {
1562 printf("DeleteAlias failed - %s\n", nt_errstr(status));
1569 static BOOL test_CreateAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1570 struct policy_handle *domain_handle,
1571 struct policy_handle *alias_handle,
1572 const struct dom_sid *domain_sid)
1575 struct samr_CreateDomAlias r;
1576 struct lsa_String name;
1580 init_lsa_String(&name, TEST_ALIASNAME);
1581 r.in.domain_handle = domain_handle;
1582 r.in.alias_name = &name;
1583 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1584 r.out.alias_handle = alias_handle;
1587 printf("Testing CreateAlias (%s)\n", r.in.alias_name->string);
1589 status = dcerpc_samr_CreateDomAlias(p, mem_ctx, &r);
1591 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1592 printf("Server refused create of '%s'\n", r.in.alias_name->string);
1596 if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
1597 if (!test_DeleteAlias_byname(p, mem_ctx, domain_handle, r.in.alias_name->string)) {
1600 status = dcerpc_samr_CreateDomAlias(p, mem_ctx, &r);
1603 if (!NT_STATUS_IS_OK(status)) {
1604 printf("CreateAlias failed - %s\n", nt_errstr(status));
1608 if (!test_alias_ops(p, mem_ctx, alias_handle, domain_sid)) {
1615 static BOOL test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1616 struct policy_handle *domain_handle, char **password)
1624 if (!test_ChangePasswordUser(p, mem_ctx, domain_handle, password)) {
1628 if (!test_ChangePasswordUser2(p, mem_ctx, domain_handle, password)) {
1632 if (!test_OemChangePasswordUser2(p, mem_ctx, domain_handle, password)) {
1636 /* we change passwords twice - this has the effect of verifying
1637 they were changed correctly for the final call */
1638 if (!test_ChangePasswordUser3(p, mem_ctx, TEST_ACCOUNT_NAME, 0, password)) {
1642 if (!test_ChangePasswordUser3(p, mem_ctx, TEST_ACCOUNT_NAME, 0, password)) {
1649 static BOOL test_CreateUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1650 struct policy_handle *domain_handle, struct policy_handle *user_handle)
1653 struct samr_CreateUser r;
1654 struct samr_QueryUserInfo q;
1656 char *password = NULL;
1659 const uint32_t password_fields[] = {
1660 SAMR_FIELD_PASSWORD,
1661 SAMR_FIELD_PASSWORD2,
1662 SAMR_FIELD_PASSWORD | SAMR_FIELD_PASSWORD2,
1666 TALLOC_CTX *user_ctx;
1668 /* This call creates a 'normal' account - check that it really does */
1669 const uint32_t acct_flags = ACB_NORMAL;
1670 struct lsa_String name;
1673 user_ctx = talloc_named(mem_ctx, 0, "test_CreateUser2 per-user context");
1674 init_lsa_String(&name, TEST_ACCOUNT_NAME);
1676 r.in.domain_handle = domain_handle;
1677 r.in.account_name = &name;
1678 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1679 r.out.user_handle = user_handle;
1682 printf("Testing CreateUser(%s)\n", r.in.account_name->string);
1684 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
1686 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1687 printf("Server refused create of '%s'\n", r.in.account_name->string);
1688 ZERO_STRUCTP(user_handle);
1689 talloc_free(user_ctx);
1693 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
1694 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
1695 talloc_free(user_ctx);
1698 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
1700 if (!NT_STATUS_IS_OK(status)) {
1701 talloc_free(user_ctx);
1702 printf("CreateUser failed - %s\n", nt_errstr(status));
1706 q.in.user_handle = user_handle;
1709 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
1710 if (!NT_STATUS_IS_OK(status)) {
1711 printf("QueryUserInfo level %u failed - %s\n",
1712 q.in.level, nt_errstr(status));
1715 if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
1716 printf("QuerUserInfo level 16 failed, it returned 0x%08x (%u) when we expected flags of 0x%08x (%u)\n",
1717 q.out.info->info16.acct_flags, q.out.info->info16.acct_flags,
1718 acct_flags, acct_flags);
1723 if (!test_user_ops(p, user_ctx, user_handle, acct_flags, name.string)) {
1727 if (!test_SetUserPass(p, user_ctx, user_handle, &password)) {
1731 for (i = 0; password_fields[i]; i++) {
1732 if (!test_SetUserPass_23(p, user_ctx, user_handle, password_fields[i], &password)) {
1736 /* check it was set right */
1737 if (!test_ChangePasswordUser3(p, user_ctx, TEST_ACCOUNT_NAME, 0, &password)) {
1742 for (i = 0; password_fields[i]; i++) {
1743 if (!test_SetUserPass_25(p, user_ctx, user_handle, password_fields[i], &password)) {
1747 /* check it was set right */
1748 if (!test_ChangePasswordUser3(p, user_ctx, TEST_ACCOUNT_NAME, 0, &password)) {
1753 if (!test_SetUserPassEx(p, user_ctx, user_handle, &password)) {
1757 if (!test_ChangePassword(p, user_ctx, domain_handle, &password)) {
1761 talloc_free(user_ctx);
1767 static BOOL test_DeleteUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1768 struct policy_handle *user_handle)
1770 struct samr_DeleteUser d;
1774 printf("Testing DeleteUser\n");
1776 d.in.user_handle = user_handle;
1777 d.out.user_handle = user_handle;
1779 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
1780 if (!NT_STATUS_IS_OK(status)) {
1781 printf("DeleteUser failed - %s\n", nt_errstr(status));
1788 static BOOL test_CreateUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1789 struct policy_handle *handle)
1792 struct samr_CreateUser2 r;
1793 struct samr_QueryUserInfo q;
1794 struct samr_DeleteUser d;
1795 struct policy_handle user_handle;
1797 struct lsa_String name;
1802 uint32_t acct_flags;
1803 const char *account_name;
1805 } account_types[] = {
1806 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
1807 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1808 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1809 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
1810 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1811 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1812 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
1813 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1814 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1815 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
1816 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
1817 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
1818 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1819 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1820 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
1823 for (i = 0; account_types[i].account_name; i++) {
1824 TALLOC_CTX *user_ctx;
1825 uint32_t acct_flags = account_types[i].acct_flags;
1826 uint32_t access_granted;
1827 user_ctx = talloc_named(mem_ctx, 0, "test_CreateUser2 per-user context");
1828 init_lsa_String(&name, account_types[i].account_name);
1830 r.in.domain_handle = handle;
1831 r.in.account_name = &name;
1832 r.in.acct_flags = acct_flags;
1833 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1834 r.out.user_handle = &user_handle;
1835 r.out.access_granted = &access_granted;
1838 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
1840 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
1842 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1843 talloc_free(user_ctx);
1844 printf("Server refused create of '%s'\n", r.in.account_name->string);
1847 } else if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
1848 if (!test_DeleteUser_byname(p, user_ctx, handle, r.in.account_name->string)) {
1849 talloc_free(user_ctx);
1853 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
1856 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
1857 printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
1858 nt_errstr(status), nt_errstr(account_types[i].nt_status));
1862 if (NT_STATUS_IS_OK(status)) {
1863 q.in.user_handle = &user_handle;
1866 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
1867 if (!NT_STATUS_IS_OK(status)) {
1868 printf("QueryUserInfo level %u failed - %s\n",
1869 q.in.level, nt_errstr(status));
1872 if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
1873 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
1874 q.out.info->info16.acct_flags,
1880 if (!test_user_ops(p, user_ctx, &user_handle, acct_flags, name.string)) {
1884 printf("Testing DeleteUser (createuser2 test)\n");
1886 d.in.user_handle = &user_handle;
1887 d.out.user_handle = &user_handle;
1889 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
1890 if (!NT_STATUS_IS_OK(status)) {
1891 printf("DeleteUser failed - %s\n", nt_errstr(status));
1895 talloc_free(user_ctx);
1901 static BOOL test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1902 struct policy_handle *handle)
1905 struct samr_QueryAliasInfo r;
1906 uint16_t levels[] = {1, 2, 3};
1910 for (i=0;i<ARRAY_SIZE(levels);i++) {
1911 printf("Testing QueryAliasInfo level %u\n", levels[i]);
1913 r.in.alias_handle = handle;
1914 r.in.level = levels[i];
1916 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
1917 if (!NT_STATUS_IS_OK(status)) {
1918 printf("QueryAliasInfo level %u failed - %s\n",
1919 levels[i], nt_errstr(status));
1927 static BOOL test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1928 struct policy_handle *handle)
1931 struct samr_QueryGroupInfo r;
1932 uint16_t levels[] = {1, 2, 3, 4, 5};
1936 for (i=0;i<ARRAY_SIZE(levels);i++) {
1937 printf("Testing QueryGroupInfo level %u\n", levels[i]);
1939 r.in.group_handle = handle;
1940 r.in.level = levels[i];
1942 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
1943 if (!NT_STATUS_IS_OK(status)) {
1944 printf("QueryGroupInfo level %u failed - %s\n",
1945 levels[i], nt_errstr(status));
1953 static BOOL test_QueryGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1954 struct policy_handle *handle)
1957 struct samr_QueryGroupMember r;
1960 printf("Testing QueryGroupMember\n");
1962 r.in.group_handle = handle;
1964 status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &r);
1965 if (!NT_STATUS_IS_OK(status)) {
1966 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
1974 static BOOL test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1975 struct policy_handle *handle)
1978 struct samr_QueryGroupInfo r;
1979 struct samr_SetGroupInfo s;
1980 uint16_t levels[] = {1, 2, 3, 4};
1981 uint16_t set_ok[] = {0, 1, 1, 1};
1985 for (i=0;i<ARRAY_SIZE(levels);i++) {
1986 printf("Testing QueryGroupInfo level %u\n", levels[i]);
1988 r.in.group_handle = handle;
1989 r.in.level = levels[i];
1991 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
1992 if (!NT_STATUS_IS_OK(status)) {
1993 printf("QueryGroupInfo level %u failed - %s\n",
1994 levels[i], nt_errstr(status));
1998 printf("Testing SetGroupInfo level %u\n", levels[i]);
2000 s.in.group_handle = handle;
2001 s.in.level = levels[i];
2002 s.in.info = r.out.info;
2005 /* disabled this, as it changes the name only from the point of view of samr,
2006 but leaves the name from the point of view of w2k3 internals (and ldap). This means
2007 the name is still reserved, so creating the old name fails, but deleting by the old name
2009 if (s.in.level == 2) {
2010 init_lsa_String(&s.in.info->string, "NewName");
2014 if (s.in.level == 4) {
2015 init_lsa_String(&s.in.info->description, "test description");
2018 status = dcerpc_samr_SetGroupInfo(p, mem_ctx, &s);
2020 if (!NT_STATUS_IS_OK(status)) {
2021 printf("SetGroupInfo level %u failed - %s\n",
2022 r.in.level, nt_errstr(status));
2027 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
2028 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
2029 r.in.level, nt_errstr(status));
2039 static BOOL test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2040 struct policy_handle *handle)
2043 struct samr_QueryUserInfo r;
2044 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
2045 11, 12, 13, 14, 16, 17, 20, 21};
2049 for (i=0;i<ARRAY_SIZE(levels);i++) {
2050 printf("Testing QueryUserInfo level %u\n", levels[i]);
2052 r.in.user_handle = handle;
2053 r.in.level = levels[i];
2055 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
2056 if (!NT_STATUS_IS_OK(status)) {
2057 printf("QueryUserInfo level %u failed - %s\n",
2058 levels[i], nt_errstr(status));
2066 static BOOL test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2067 struct policy_handle *handle)
2070 struct samr_QueryUserInfo2 r;
2071 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
2072 11, 12, 13, 14, 16, 17, 20, 21};
2076 for (i=0;i<ARRAY_SIZE(levels);i++) {
2077 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
2079 r.in.user_handle = handle;
2080 r.in.level = levels[i];
2082 status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r);
2083 if (!NT_STATUS_IS_OK(status)) {
2084 printf("QueryUserInfo2 level %u failed - %s\n",
2085 levels[i], nt_errstr(status));
2093 static BOOL test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2094 struct policy_handle *handle, uint32_t rid)
2097 struct samr_OpenUser r;
2098 struct policy_handle user_handle;
2101 printf("Testing OpenUser(%u)\n", rid);
2103 r.in.domain_handle = handle;
2104 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2106 r.out.user_handle = &user_handle;
2108 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
2109 if (!NT_STATUS_IS_OK(status)) {
2110 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
2114 if (!test_QuerySecurity(p, mem_ctx, &user_handle)) {
2118 if (!test_QueryUserInfo(p, mem_ctx, &user_handle)) {
2122 if (!test_QueryUserInfo2(p, mem_ctx, &user_handle)) {
2126 if (!test_GetUserPwInfo(p, mem_ctx, &user_handle)) {
2130 if (!test_GetGroupsForUser(p,mem_ctx, &user_handle)) {
2134 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
2141 static BOOL test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2142 struct policy_handle *handle, uint32_t rid)
2145 struct samr_OpenGroup r;
2146 struct policy_handle group_handle;
2149 printf("Testing OpenGroup(%u)\n", rid);
2151 r.in.domain_handle = handle;
2152 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2154 r.out.group_handle = &group_handle;
2156 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
2157 if (!NT_STATUS_IS_OK(status)) {
2158 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
2162 if (!test_QuerySecurity(p, mem_ctx, &group_handle)) {
2166 if (!test_QueryGroupInfo(p, mem_ctx, &group_handle)) {
2170 if (!test_QueryGroupMember(p, mem_ctx, &group_handle)) {
2174 if (!test_samr_handle_Close(p, mem_ctx, &group_handle)) {
2181 static BOOL test_OpenAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2182 struct policy_handle *handle, uint32_t rid)
2185 struct samr_OpenAlias r;
2186 struct policy_handle alias_handle;
2189 printf("Testing OpenAlias(%u)\n", rid);
2191 r.in.domain_handle = handle;
2192 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2194 r.out.alias_handle = &alias_handle;
2196 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
2197 if (!NT_STATUS_IS_OK(status)) {
2198 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
2202 if (!test_QuerySecurity(p, mem_ctx, &alias_handle)) {
2206 if (!test_QueryAliasInfo(p, mem_ctx, &alias_handle)) {
2210 if (!test_GetMembersInAlias(p, mem_ctx, &alias_handle)) {
2214 if (!test_samr_handle_Close(p, mem_ctx, &alias_handle)) {
2221 static BOOL test_EnumDomainUsers(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2222 struct policy_handle *handle)
2225 struct samr_EnumDomainUsers r;
2226 uint32_t resume_handle=0;
2229 struct samr_LookupNames n;
2230 struct samr_LookupRids lr ;
2232 printf("Testing EnumDomainUsers\n");
2234 r.in.domain_handle = handle;
2235 r.in.resume_handle = &resume_handle;
2236 r.in.acct_flags = 0;
2237 r.in.max_size = (uint32_t)-1;
2238 r.out.resume_handle = &resume_handle;
2240 status = dcerpc_samr_EnumDomainUsers(p, mem_ctx, &r);
2241 if (!NT_STATUS_IS_OK(status)) {
2242 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
2250 if (r.out.sam->count == 0) {
2254 for (i=0;i<r.out.sam->count;i++) {
2255 if (!test_OpenUser(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
2260 printf("Testing LookupNames\n");
2261 n.in.domain_handle = handle;
2262 n.in.num_names = r.out.sam->count;
2263 n.in.names = talloc_array(mem_ctx, struct lsa_String, r.out.sam->count);
2264 for (i=0;i<r.out.sam->count;i++) {
2265 n.in.names[i].string = r.out.sam->entries[i].name.string;
2267 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
2268 if (!NT_STATUS_IS_OK(status)) {
2269 printf("LookupNames failed - %s\n", nt_errstr(status));
2274 printf("Testing LookupRids\n");
2275 lr.in.domain_handle = handle;
2276 lr.in.num_rids = r.out.sam->count;
2277 lr.in.rids = talloc_array(mem_ctx, uint32_t, r.out.sam->count);
2278 for (i=0;i<r.out.sam->count;i++) {
2279 lr.in.rids[i] = r.out.sam->entries[i].idx;
2281 status = dcerpc_samr_LookupRids(p, mem_ctx, &lr);
2282 if (!NT_STATUS_IS_OK(status)) {
2283 printf("LookupRids failed - %s\n", nt_errstr(status));
2291 try blasting the server with a bunch of sync requests
2293 static BOOL test_EnumDomainUsers_async(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2294 struct policy_handle *handle)
2297 struct samr_EnumDomainUsers r;
2298 uint32_t resume_handle=0;
2300 #define ASYNC_COUNT 100
2301 struct rpc_request *req[ASYNC_COUNT];
2303 if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
2304 printf("samr async test disabled - enable dangerous tests to use\n");
2308 printf("Testing EnumDomainUsers_async\n");
2310 r.in.domain_handle = handle;
2311 r.in.resume_handle = &resume_handle;
2312 r.in.acct_flags = 0;
2313 r.in.max_size = (uint32_t)-1;
2314 r.out.resume_handle = &resume_handle;
2316 for (i=0;i<ASYNC_COUNT;i++) {
2317 req[i] = dcerpc_samr_EnumDomainUsers_send(p, mem_ctx, &r);
2320 for (i=0;i<ASYNC_COUNT;i++) {
2321 status = dcerpc_ndr_request_recv(req[i]);
2322 if (!NT_STATUS_IS_OK(status)) {
2323 printf("EnumDomainUsers[%d] failed - %s\n",
2324 i, nt_errstr(status));
2329 printf("%d async requests OK\n", i);
2334 static BOOL test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2335 struct policy_handle *handle)
2338 struct samr_EnumDomainGroups r;
2339 uint32_t resume_handle=0;
2343 printf("Testing EnumDomainGroups\n");
2345 r.in.domain_handle = handle;
2346 r.in.resume_handle = &resume_handle;
2347 r.in.max_size = (uint32_t)-1;
2348 r.out.resume_handle = &resume_handle;
2350 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
2351 if (!NT_STATUS_IS_OK(status)) {
2352 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
2360 for (i=0;i<r.out.sam->count;i++) {
2361 if (!test_OpenGroup(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
2369 static BOOL test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2370 struct policy_handle *handle)
2373 struct samr_EnumDomainAliases r;
2374 uint32_t resume_handle=0;
2378 printf("Testing EnumDomainAliases\n");
2380 r.in.domain_handle = handle;
2381 r.in.resume_handle = &resume_handle;
2382 r.in.acct_flags = (uint32_t)-1;
2383 r.out.resume_handle = &resume_handle;
2385 status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
2386 if (!NT_STATUS_IS_OK(status)) {
2387 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
2395 for (i=0;i<r.out.sam->count;i++) {
2396 if (!test_OpenAlias(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
2404 static BOOL test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2405 struct policy_handle *handle)
2408 struct samr_GetDisplayEnumerationIndex r;
2410 uint16_t levels[] = {1, 2, 3, 4, 5};
2411 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
2414 for (i=0;i<ARRAY_SIZE(levels);i++) {
2415 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
2417 r.in.domain_handle = handle;
2418 r.in.level = levels[i];
2419 init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
2421 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
2424 !NT_STATUS_IS_OK(status) &&
2425 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2426 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
2427 levels[i], nt_errstr(status));
2431 init_lsa_String(&r.in.name, "zzzzzzzz");
2433 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
2435 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2436 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
2437 levels[i], nt_errstr(status));
2445 static BOOL test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2446 struct policy_handle *handle)
2449 struct samr_GetDisplayEnumerationIndex2 r;
2451 uint16_t levels[] = {1, 2, 3, 4, 5};
2452 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
2455 for (i=0;i<ARRAY_SIZE(levels);i++) {
2456 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
2458 r.in.domain_handle = handle;
2459 r.in.level = levels[i];
2460 init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
2462 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
2464 !NT_STATUS_IS_OK(status) &&
2465 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2466 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
2467 levels[i], nt_errstr(status));
2471 init_lsa_String(&r.in.name, "zzzzzzzz");
2473 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
2474 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2475 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
2476 levels[i], nt_errstr(status));
2484 static BOOL test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2485 struct policy_handle *handle)
2488 struct samr_QueryDisplayInfo r;
2490 uint16_t levels[] = {1, 2, 3, 4, 5};
2493 for (i=0;i<ARRAY_SIZE(levels);i++) {
2494 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
2496 r.in.domain_handle = handle;
2497 r.in.level = levels[i];
2499 r.in.max_entries = 1000;
2500 r.in.buf_size = (uint32_t)-1;
2502 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
2503 if (!NT_STATUS_IS_OK(status)) {
2504 printf("QueryDisplayInfo level %u failed - %s\n",
2505 levels[i], nt_errstr(status));
2513 static BOOL test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2514 struct policy_handle *handle)
2517 struct samr_QueryDisplayInfo2 r;
2519 uint16_t levels[] = {1, 2, 3, 4, 5};
2522 for (i=0;i<ARRAY_SIZE(levels);i++) {
2523 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
2525 r.in.domain_handle = handle;
2526 r.in.level = levels[i];
2528 r.in.max_entries = 1000;
2529 r.in.buf_size = (uint32_t)-1;
2531 status = dcerpc_samr_QueryDisplayInfo2(p, mem_ctx, &r);
2532 if (!NT_STATUS_IS_OK(status)) {
2533 printf("QueryDisplayInfo2 level %u failed - %s\n",
2534 levels[i], nt_errstr(status));
2542 static BOOL test_QueryDisplayInfo3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2543 struct policy_handle *handle)
2546 struct samr_QueryDisplayInfo3 r;
2548 uint16_t levels[] = {1, 2, 3, 4, 5};
2551 for (i=0;i<ARRAY_SIZE(levels);i++) {
2552 printf("Testing QueryDisplayInfo3 level %u\n", levels[i]);
2554 r.in.domain_handle = handle;
2555 r.in.level = levels[i];
2557 r.in.max_entries = 1000;
2558 r.in.buf_size = (uint32_t)-1;
2560 status = dcerpc_samr_QueryDisplayInfo3(p, mem_ctx, &r);
2561 if (!NT_STATUS_IS_OK(status)) {
2562 printf("QueryDisplayInfo3 level %u failed - %s\n",
2563 levels[i], nt_errstr(status));
2572 static BOOL test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2573 struct policy_handle *handle)
2576 struct samr_QueryDisplayInfo r;
2579 printf("Testing QueryDisplayInfo continuation\n");
2581 r.in.domain_handle = handle;
2584 r.in.max_entries = 1;
2585 r.in.buf_size = (uint32_t)-1;
2588 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
2589 if (NT_STATUS_IS_OK(status) && r.out.returned_size != 0) {
2590 if (r.out.info.info1.entries[0].idx != r.in.start_idx + 1) {
2591 printf("failed: expected idx %d but got %d\n",
2593 r.out.info.info1.entries[0].idx);
2598 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
2599 !NT_STATUS_IS_OK(status)) {
2600 printf("QueryDisplayInfo level %u failed - %s\n",
2601 r.in.level, nt_errstr(status));
2606 } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
2607 NT_STATUS_IS_OK(status)) &&
2608 r.out.returned_size != 0);
2613 static BOOL test_QueryDomainInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2614 struct policy_handle *handle)
2617 struct samr_QueryDomainInfo r;
2618 struct samr_SetDomainInfo s;
2619 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
2620 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
2624 for (i=0;i<ARRAY_SIZE(levels);i++) {
2625 printf("Testing QueryDomainInfo level %u\n", levels[i]);
2627 r.in.domain_handle = handle;
2628 r.in.level = levels[i];
2630 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2631 if (!NT_STATUS_IS_OK(status)) {
2632 printf("QueryDomainInfo level %u failed - %s\n",
2633 r.in.level, nt_errstr(status));
2638 printf("Testing SetDomainInfo level %u\n", levels[i]);
2640 s.in.domain_handle = handle;
2641 s.in.level = levels[i];
2642 s.in.info = r.out.info;
2644 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2646 if (!NT_STATUS_IS_OK(status)) {
2647 printf("SetDomainInfo level %u failed - %s\n",
2648 r.in.level, nt_errstr(status));
2653 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
2654 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
2655 r.in.level, nt_errstr(status));
2661 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2662 if (!NT_STATUS_IS_OK(status)) {
2663 printf("QueryDomainInfo level %u failed - %s\n",
2664 r.in.level, nt_errstr(status));
2674 static BOOL test_QueryDomainInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2675 struct policy_handle *handle)
2678 struct samr_QueryDomainInfo2 r;
2679 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
2683 for (i=0;i<ARRAY_SIZE(levels);i++) {
2684 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
2686 r.in.domain_handle = handle;
2687 r.in.level = levels[i];
2689 status = dcerpc_samr_QueryDomainInfo2(p, mem_ctx, &r);
2690 if (!NT_STATUS_IS_OK(status)) {
2691 printf("QueryDomainInfo2 level %u failed - %s\n",
2692 r.in.level, nt_errstr(status));
2701 /* Test whether querydispinfo level 5 and enumdomgroups return the same
2702 set of group names. */
2703 static BOOL test_GroupList(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2704 struct policy_handle *handle)
2706 struct samr_EnumDomainGroups q1;
2707 struct samr_QueryDisplayInfo q2;
2709 uint32_t resume_handle=0;
2714 const char **names = NULL;
2716 printf("Testing coherency of querydispinfo vs enumdomgroups\n");
2718 q1.in.domain_handle = handle;
2719 q1.in.resume_handle = &resume_handle;
2721 q1.out.resume_handle = &resume_handle;
2723 status = STATUS_MORE_ENTRIES;
2724 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
2725 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &q1);
2727 if (!NT_STATUS_IS_OK(status) &&
2728 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
2731 for (i=0; i<q1.out.num_entries; i++) {
2732 add_string_to_array(mem_ctx,
2733 q1.out.sam->entries[i].name.string,
2734 &names, &num_names);
2738 if (!NT_STATUS_IS_OK(status)) {
2739 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
2747 q2.in.domain_handle = handle;
2749 q2.in.start_idx = 0;
2750 q2.in.max_entries = 5;
2751 q2.in.buf_size = (uint32_t)-1;
2753 status = STATUS_MORE_ENTRIES;
2754 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
2755 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &q2);
2757 if (!NT_STATUS_IS_OK(status) &&
2758 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
2761 for (i=0; i<q2.out.info.info5.count; i++) {
2763 const char *name = q2.out.info.info5.entries[i].account_name.string;
2765 for (j=0; j<num_names; j++) {
2766 if (names[j] == NULL)
2768 /* Hmm. No strequal in samba4 */
2769 if (strequal(names[j], name)) {
2777 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
2782 q2.in.start_idx += q2.out.info.info5.count;
2785 if (!NT_STATUS_IS_OK(status)) {
2786 printf("QueryDisplayInfo level 5 failed - %s\n",
2791 for (i=0; i<num_names; i++) {
2792 if (names[i] != NULL) {
2793 printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
2802 static BOOL test_DeleteDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2803 struct policy_handle *group_handle)
2805 struct samr_DeleteDomainGroup d;
2809 printf("Testing DeleteDomainGroup\n");
2811 d.in.group_handle = group_handle;
2812 d.out.group_handle = group_handle;
2814 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
2815 if (!NT_STATUS_IS_OK(status)) {
2816 printf("DeleteDomainGroup failed - %s\n", nt_errstr(status));
2823 static BOOL test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2824 struct policy_handle *domain_handle)
2826 struct samr_TestPrivateFunctionsDomain r;
2830 printf("Testing TestPrivateFunctionsDomain\n");
2832 r.in.domain_handle = domain_handle;
2834 status = dcerpc_samr_TestPrivateFunctionsDomain(p, mem_ctx, &r);
2835 if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
2836 printf("TestPrivateFunctionsDomain failed - %s\n", nt_errstr(status));
2843 static BOOL test_RidToSid(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2844 struct dom_sid *domain_sid,
2845 struct policy_handle *domain_handle)
2847 struct samr_RidToSid r;
2850 struct dom_sid *calc_sid;
2851 int rids[] = { 0, 42, 512, 10200 };
2854 for (i=0;i<ARRAY_SIZE(rids);i++) {
2856 printf("Testing RidToSid\n");
2858 calc_sid = dom_sid_dup(mem_ctx, domain_sid);
2859 r.in.domain_handle = domain_handle;
2862 status = dcerpc_samr_RidToSid(p, mem_ctx, &r);
2863 if (!NT_STATUS_IS_OK(status)) {
2864 printf("RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
2867 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
2869 if (!dom_sid_equal(calc_sid, r.out.sid)) {
2870 printf("RidToSid for %d failed - got %s, expected %s\n", rids[i],
2871 dom_sid_string(mem_ctx, r.out.sid),
2872 dom_sid_string(mem_ctx, calc_sid));
2881 static BOOL test_GetBootKeyInformation(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2882 struct policy_handle *domain_handle)
2884 struct samr_GetBootKeyInformation r;
2888 printf("Testing GetBootKeyInformation\n");
2890 r.in.domain_handle = domain_handle;
2892 status = dcerpc_samr_GetBootKeyInformation(p, mem_ctx, &r);
2893 if (!NT_STATUS_IS_OK(status)) {
2894 /* w2k3 seems to fail this sometimes and pass it sometimes */
2895 printf("GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
2901 static BOOL test_AddGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2902 struct policy_handle *domain_handle,
2903 struct policy_handle *group_handle)
2906 struct samr_AddGroupMember r;
2907 struct samr_DeleteGroupMember d;
2908 struct samr_QueryGroupMember q;
2909 struct samr_SetMemberAttributesOfGroup s;
2913 status = test_LookupName(p, mem_ctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
2914 if (!NT_STATUS_IS_OK(status)) {
2918 r.in.group_handle = group_handle;
2920 r.in.flags = 0; /* ??? */
2922 printf("Testing AddGroupMember and DeleteGroupMember\n");
2924 d.in.group_handle = group_handle;
2927 status = dcerpc_samr_DeleteGroupMember(p, mem_ctx, &d);
2928 if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_NOT_IN_GROUP, status)) {
2929 printf("DeleteGroupMember gave %s - should be NT_STATUS_MEMBER_NOT_IN_GROUP\n",
2934 status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
2935 if (!NT_STATUS_IS_OK(status)) {
2936 printf("AddGroupMember failed - %s\n", nt_errstr(status));
2940 status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
2941 if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_IN_GROUP, status)) {
2942 printf("AddGroupMember gave %s - should be NT_STATUS_MEMBER_IN_GROUP\n",
2947 /* this one is quite strange. I am using random inputs in the
2948 hope of triggering an error that might give us a clue */
2949 s.in.group_handle = group_handle;
2950 s.in.unknown1 = random();
2951 s.in.unknown2 = random();
2953 status = dcerpc_samr_SetMemberAttributesOfGroup(p, mem_ctx, &s);
2954 if (!NT_STATUS_IS_OK(status)) {
2955 printf("SetMemberAttributesOfGroup failed - %s\n", nt_errstr(status));
2959 q.in.group_handle = group_handle;
2961 status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &q);
2962 if (!NT_STATUS_IS_OK(status)) {
2963 printf("QueryGroupMember failed - %s\n", nt_errstr(status));
2967 status = dcerpc_samr_DeleteGroupMember(p, mem_ctx, &d);
2968 if (!NT_STATUS_IS_OK(status)) {
2969 printf("DeleteGroupMember failed - %s\n", nt_errstr(status));
2973 status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
2974 if (!NT_STATUS_IS_OK(status)) {
2975 printf("AddGroupMember failed - %s\n", nt_errstr(status));
2983 static BOOL test_CreateDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2984 struct policy_handle *domain_handle, struct policy_handle *group_handle)
2987 struct samr_CreateDomainGroup r;
2989 struct lsa_String name;
2992 init_lsa_String(&name, TEST_GROUPNAME);
2994 r.in.domain_handle = domain_handle;
2996 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2997 r.out.group_handle = group_handle;
3000 printf("Testing CreateDomainGroup(%s)\n", r.in.name->string);
3002 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
3004 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
3005 printf("Server refused create of '%s'\n", r.in.name->string);
3006 ZERO_STRUCTP(group_handle);
3010 if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS) ||
3011 NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
3012 if (!test_DeleteGroup_byname(p, mem_ctx, domain_handle, r.in.name->string)) {
3015 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
3017 if (!NT_STATUS_IS_OK(status)) {
3018 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
3022 if (!test_AddGroupMember(p, mem_ctx, domain_handle, group_handle)) {
3026 if (!test_SetGroupInfo(p, mem_ctx, group_handle)) {
3035 its not totally clear what this does. It seems to accept any sid you like.
3037 static BOOL test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p,
3038 TALLOC_CTX *mem_ctx,
3039 struct policy_handle *domain_handle)
3042 struct samr_RemoveMemberFromForeignDomain r;
3044 r.in.domain_handle = domain_handle;
3045 r.in.sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-12-34-56-78");
3047 status = dcerpc_samr_RemoveMemberFromForeignDomain(p, mem_ctx, &r);
3048 if (!NT_STATUS_IS_OK(status)) {
3049 printf("RemoveMemberFromForeignDomain failed - %s\n", nt_errstr(status));
3058 static BOOL test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3059 struct policy_handle *handle);
3061 static BOOL test_OpenDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3062 struct policy_handle *handle, struct dom_sid *sid)
3065 struct samr_OpenDomain r;
3066 struct policy_handle domain_handle;
3067 struct policy_handle user_handle;
3068 struct policy_handle alias_handle;
3069 struct policy_handle group_handle;
3072 ZERO_STRUCT(user_handle);
3073 ZERO_STRUCT(alias_handle);
3074 ZERO_STRUCT(group_handle);
3075 ZERO_STRUCT(domain_handle);
3077 printf("Testing OpenDomain\n");
3079 r.in.connect_handle = handle;
3080 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3082 r.out.domain_handle = &domain_handle;
3084 status = dcerpc_samr_OpenDomain(p, mem_ctx, &r);
3085 if (!NT_STATUS_IS_OK(status)) {
3086 printf("OpenDomain failed - %s\n", nt_errstr(status));
3090 /* run the domain tests with the main handle closed - this tests
3091 the servers reference counting */
3092 ret &= test_samr_handle_Close(p, mem_ctx, handle);
3094 ret &= test_QuerySecurity(p, mem_ctx, &domain_handle);
3095 ret &= test_RemoveMemberFromForeignDomain(p, mem_ctx, &domain_handle);
3096 ret &= test_CreateUser2(p, mem_ctx, &domain_handle);
3097 ret &= test_CreateUser(p, mem_ctx, &domain_handle, &user_handle);
3098 ret &= test_CreateAlias(p, mem_ctx, &domain_handle, &alias_handle, sid);
3099 ret &= test_CreateDomainGroup(p, mem_ctx, &domain_handle, &group_handle);
3100 ret &= test_QueryDomainInfo(p, mem_ctx, &domain_handle);
3101 ret &= test_QueryDomainInfo2(p, mem_ctx, &domain_handle);
3102 ret &= test_EnumDomainUsers(p, mem_ctx, &domain_handle);
3103 ret &= test_EnumDomainUsers_async(p, mem_ctx, &domain_handle);
3104 ret &= test_EnumDomainGroups(p, mem_ctx, &domain_handle);
3105 ret &= test_EnumDomainAliases(p, mem_ctx, &domain_handle);
3106 ret &= test_QueryDisplayInfo(p, mem_ctx, &domain_handle);
3107 ret &= test_QueryDisplayInfo2(p, mem_ctx, &domain_handle);
3108 ret &= test_QueryDisplayInfo3(p, mem_ctx, &domain_handle);
3109 ret &= test_QueryDisplayInfo_continue(p, mem_ctx, &domain_handle);
3110 ret &= test_GetDisplayEnumerationIndex(p, mem_ctx, &domain_handle);
3111 ret &= test_GetDisplayEnumerationIndex2(p, mem_ctx, &domain_handle);
3112 ret &= test_GroupList(p, mem_ctx, &domain_handle);
3113 ret &= test_TestPrivateFunctionsDomain(p, mem_ctx, &domain_handle);
3114 ret &= test_RidToSid(p, mem_ctx, sid, &domain_handle);
3115 ret &= test_GetBootKeyInformation(p, mem_ctx, &domain_handle);
3117 if (!policy_handle_empty(&user_handle) &&
3118 !test_DeleteUser(p, mem_ctx, &user_handle)) {
3122 if (!policy_handle_empty(&alias_handle) &&
3123 !test_DeleteAlias(p, mem_ctx, &alias_handle)) {
3127 if (!policy_handle_empty(&group_handle) &&
3128 !test_DeleteDomainGroup(p, mem_ctx, &group_handle)) {
3132 ret &= test_samr_handle_Close(p, mem_ctx, &domain_handle);
3134 /* reconnect the main handle */
3135 ret &= test_Connect(p, mem_ctx, handle);
3140 static BOOL test_LookupDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3141 struct policy_handle *handle, struct lsa_String *domain)
3144 struct samr_LookupDomain r;
3145 struct lsa_String n2;
3148 printf("Testing LookupDomain(%s)\n", domain->string);
3150 /* check for correct error codes */
3151 r.in.connect_handle = handle;
3152 r.in.domain_name = &n2;
3155 status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
3156 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_PARAMETER, status)) {
3157 printf("failed: LookupDomain expected NT_STATUS_INVALID_PARAMETER - %s\n", nt_errstr(status));
3161 n2.string = "xxNODOMAINxx";
3163 status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
3164 if (!NT_STATUS_EQUAL(NT_STATUS_NO_SUCH_DOMAIN, status)) {
3165 printf("failed: LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN - %s\n", nt_errstr(status));
3169 r.in.connect_handle = handle;
3170 r.in.domain_name = domain;
3172 status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
3173 if (!NT_STATUS_IS_OK(status)) {
3174 printf("LookupDomain failed - %s\n", nt_errstr(status));
3178 if (!test_GetDomPwInfo(p, mem_ctx, domain)) {
3182 if (!test_OpenDomain(p, mem_ctx, handle, r.out.sid)) {
3190 static BOOL test_EnumDomains(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3191 struct policy_handle *handle)
3194 struct samr_EnumDomains r;
3195 uint32_t resume_handle = 0;
3199 r.in.connect_handle = handle;
3200 r.in.resume_handle = &resume_handle;
3201 r.in.buf_size = (uint32_t)-1;
3202 r.out.resume_handle = &resume_handle;
3204 status = dcerpc_samr_EnumDomains(p, mem_ctx, &r);
3205 if (!NT_STATUS_IS_OK(status)) {
3206 printf("EnumDomains failed - %s\n", nt_errstr(status));
3214 for (i=0;i<r.out.sam->count;i++) {
3215 if (!test_LookupDomain(p, mem_ctx, handle,
3216 &r.out.sam->entries[i].name)) {
3221 status = dcerpc_samr_EnumDomains(p, mem_ctx, &r);
3222 if (!NT_STATUS_IS_OK(status)) {
3223 printf("EnumDomains failed - %s\n", nt_errstr(status));
3231 static BOOL test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3232 struct policy_handle *handle)
3235 struct samr_Connect r;
3236 struct samr_Connect2 r2;
3237 struct samr_Connect3 r3;
3238 struct samr_Connect4 r4;
3239 struct samr_Connect5 r5;
3240 union samr_ConnectInfo info;
3241 struct policy_handle h;
3242 BOOL ret = True, got_handle = False;
3244 printf("testing samr_Connect\n");
3246 r.in.system_name = 0;
3247 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3248 r.out.connect_handle = &h;
3250 status = dcerpc_samr_Connect(p, mem_ctx, &r);
3251 if (!NT_STATUS_IS_OK(status)) {
3252 printf("Connect failed - %s\n", nt_errstr(status));
3259 printf("testing samr_Connect2\n");
3261 r2.in.system_name = NULL;
3262 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3263 r2.out.connect_handle = &h;
3265 status = dcerpc_samr_Connect2(p, mem_ctx, &r2);
3266 if (!NT_STATUS_IS_OK(status)) {
3267 printf("Connect2 failed - %s\n", nt_errstr(status));
3271 test_samr_handle_Close(p, mem_ctx, handle);
3277 printf("testing samr_Connect3\n");
3279 r3.in.system_name = NULL;
3281 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3282 r3.out.connect_handle = &h;
3284 status = dcerpc_samr_Connect3(p, mem_ctx, &r3);
3285 if (!NT_STATUS_IS_OK(status)) {
3286 printf("Connect3 failed - %s\n", nt_errstr(status));
3290 test_samr_handle_Close(p, mem_ctx, handle);
3296 printf("testing samr_Connect4\n");
3298 r4.in.system_name = "";
3300 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3301 r4.out.connect_handle = &h;
3303 status = dcerpc_samr_Connect4(p, mem_ctx, &r4);
3304 if (!NT_STATUS_IS_OK(status)) {
3305 printf("Connect4 failed - %s\n", nt_errstr(status));
3309 test_samr_handle_Close(p, mem_ctx, handle);
3315 printf("testing samr_Connect5\n");
3317 info.info1.unknown1 = 0;
3318 info.info1.unknown2 = 0;
3320 r5.in.system_name = "";
3321 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3324 r5.out.info = &info;
3325 r5.out.connect_handle = &h;
3327 status = dcerpc_samr_Connect5(p, mem_ctx, &r5);
3328 if (!NT_STATUS_IS_OK(status)) {
3329 printf("Connect5 failed - %s\n", nt_errstr(status));
3333 test_samr_handle_Close(p, mem_ctx, handle);
3343 BOOL torture_rpc_samr(void)
3346 struct dcerpc_pipe *p;
3347 TALLOC_CTX *mem_ctx;
3349 struct policy_handle handle;
3351 mem_ctx = talloc_init("torture_rpc_samr");
3353 status = torture_rpc_connection(mem_ctx, &p, &dcerpc_table_samr);
3354 if (!NT_STATUS_IS_OK(status)) {
3355 talloc_free(mem_ctx);
3359 if (!test_Connect(p, mem_ctx, &handle)) {
3363 if (!test_QuerySecurity(p, mem_ctx, &handle)) {
3367 if (!test_EnumDomains(p, mem_ctx, &handle)) {
3371 if (!test_SetDsrmPassword(p, mem_ctx, &handle)) {
3375 if (!test_Shutdown(p, mem_ctx, &handle)) {
3379 if (!test_samr_handle_Close(p, mem_ctx, &handle)) {
3383 talloc_free(mem_ctx);