2 Unix SMB/CIFS implementation.
3 test suite for samr rpc operations
5 Copyright (C) Andrew Tridgell 2003
6 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #include "torture/torture.h"
25 #include "librpc/gen_ndr/lsa.h"
26 #include "librpc/gen_ndr/ndr_samr.h"
27 #include "librpc/gen_ndr/ndr_samr_c.h"
28 #include "librpc/gen_ndr/ndr_security.h"
30 #include "lib/crypto/crypto.h"
31 #include "libcli/auth/libcli_auth.h"
32 #include "libcli/security/proto.h"
33 #include "torture/rpc/rpc.h"
35 #define TEST_ACCOUNT_NAME "samrtorturetest"
36 #define TEST_ALIASNAME "samrtorturetestalias"
37 #define TEST_GROUPNAME "samrtorturetestgroup"
38 #define TEST_MACHINENAME "samrtestmach$"
39 #define TEST_DOMAINNAME "samrtestdom$"
42 static BOOL test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
43 struct policy_handle *handle);
45 static BOOL test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
46 struct policy_handle *handle);
48 static BOOL test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
49 struct policy_handle *handle);
51 static void init_lsa_String(struct lsa_String *string, const char *s)
56 BOOL test_samr_handle_Close(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
57 struct policy_handle *handle)
63 r.out.handle = handle;
65 status = dcerpc_samr_Close(p, mem_ctx, &r);
66 if (!NT_STATUS_IS_OK(status)) {
67 printf("Close handle failed - %s\n", nt_errstr(status));
74 static BOOL test_Shutdown(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
75 struct policy_handle *handle)
78 struct samr_Shutdown r;
80 if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
81 printf("samr_Shutdown disabled - enable dangerous tests to use\n");
85 r.in.connect_handle = handle;
87 printf("testing samr_Shutdown\n");
89 status = dcerpc_samr_Shutdown(p, mem_ctx, &r);
90 if (!NT_STATUS_IS_OK(status)) {
91 printf("samr_Shutdown failed - %s\n", nt_errstr(status));
98 static BOOL test_SetDsrmPassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
99 struct policy_handle *handle)
102 struct samr_SetDsrmPassword r;
103 struct lsa_String string;
104 struct samr_Password hash;
106 if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
107 printf("samr_SetDsrmPassword disabled - enable dangerous tests to use\n");
111 E_md4hash("TeSTDSRM123", hash.hash);
113 init_lsa_String(&string, "Administrator");
119 printf("testing samr_SetDsrmPassword\n");
121 status = dcerpc_samr_SetDsrmPassword(p, mem_ctx, &r);
122 if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
123 printf("samr_SetDsrmPassword failed - %s\n", nt_errstr(status));
131 static BOOL test_QuerySecurity(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
132 struct policy_handle *handle)
135 struct samr_QuerySecurity r;
136 struct samr_SetSecurity s;
138 r.in.handle = handle;
141 status = dcerpc_samr_QuerySecurity(p, mem_ctx, &r);
142 if (!NT_STATUS_IS_OK(status)) {
143 printf("QuerySecurity failed - %s\n", nt_errstr(status));
147 if (r.out.sdbuf == NULL) {
151 s.in.handle = handle;
153 s.in.sdbuf = r.out.sdbuf;
155 status = dcerpc_samr_SetSecurity(p, mem_ctx, &s);
156 if (!NT_STATUS_IS_OK(status)) {
157 printf("SetSecurity failed - %s\n", nt_errstr(status));
161 status = dcerpc_samr_QuerySecurity(p, mem_ctx, &r);
162 if (!NT_STATUS_IS_OK(status)) {
163 printf("QuerySecurity failed - %s\n", nt_errstr(status));
171 static BOOL test_SetUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
172 struct policy_handle *handle, uint32_t base_acct_flags,
173 const char *base_account_name)
176 struct samr_SetUserInfo s;
177 struct samr_SetUserInfo2 s2;
178 struct samr_QueryUserInfo q;
179 struct samr_QueryUserInfo q0;
180 union samr_UserInfo u;
182 const char *test_account_name;
184 uint32_t user_extra_flags = 0;
185 if (base_acct_flags == ACB_NORMAL) {
186 /* When created, accounts are expired by default */
187 user_extra_flags = ACB_PW_EXPIRED;
190 s.in.user_handle = handle;
193 s2.in.user_handle = handle;
196 q.in.user_handle = handle;
200 #define TESTCALL(call, r) \
201 status = dcerpc_samr_ ##call(p, mem_ctx, &r); \
202 if (!NT_STATUS_IS_OK(status)) { \
203 printf(#call " level %u failed - %s (%s)\n", \
204 r.in.level, nt_errstr(status), __location__); \
209 #define STRING_EQUAL(s1, s2, field) \
210 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
211 printf("Failed to set %s to '%s' (%s)\n", \
212 #field, s2, __location__); \
217 #define INT_EQUAL(i1, i2, field) \
219 printf("Failed to set %s to 0x%x - got 0x%x (%s)\n", \
220 #field, i2, i1, __location__); \
225 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
226 printf("field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
228 TESTCALL(QueryUserInfo, q) \
230 s2.in.level = lvl1; \
233 ZERO_STRUCT(u.info21); \
234 u.info21.fields_present = fpval; \
236 init_lsa_String(&u.info ## lvl1.field1, value); \
237 TESTCALL(SetUserInfo, s) \
238 TESTCALL(SetUserInfo2, s2) \
239 init_lsa_String(&u.info ## lvl1.field1, ""); \
240 TESTCALL(QueryUserInfo, q); \
242 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
244 TESTCALL(QueryUserInfo, q) \
246 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
249 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
250 printf("field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
252 TESTCALL(QueryUserInfo, q) \
254 s2.in.level = lvl1; \
257 uint8_t *bits = u.info21.logon_hours.bits; \
258 ZERO_STRUCT(u.info21); \
259 if (fpval == SAMR_FIELD_LOGON_HOURS) { \
260 u.info21.logon_hours.units_per_week = 168; \
261 u.info21.logon_hours.bits = bits; \
263 u.info21.fields_present = fpval; \
265 u.info ## lvl1.field1 = value; \
266 TESTCALL(SetUserInfo, s) \
267 TESTCALL(SetUserInfo2, s2) \
268 u.info ## lvl1.field1 = 0; \
269 TESTCALL(QueryUserInfo, q); \
271 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
273 TESTCALL(QueryUserInfo, q) \
275 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
278 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
279 TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
283 do { TESTCALL(QueryUserInfo, q0) } while (0);
285 TEST_USERINFO_STRING(2, comment, 1, comment, "xx2-1 comment", 0);
286 TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
287 TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment",
290 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-1", base_account_name);
291 TEST_USERINFO_STRING(7, account_name, 1, account_name, base_account_name, 0);
292 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-3", base_account_name);
293 TEST_USERINFO_STRING(7, account_name, 3, account_name, base_account_name, 0);
294 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-5", base_account_name);
295 TEST_USERINFO_STRING(7, account_name, 5, account_name, base_account_name, 0);
296 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-6", base_account_name);
297 TEST_USERINFO_STRING(7, account_name, 6, account_name, base_account_name, 0);
298 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-7", base_account_name);
299 TEST_USERINFO_STRING(7, account_name, 7, account_name, base_account_name, 0);
300 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-21", base_account_name);
301 TEST_USERINFO_STRING(7, account_name, 21, account_name, base_account_name, 0);
302 test_account_name = base_account_name;
303 TEST_USERINFO_STRING(21, account_name, 21, account_name, base_account_name,
304 SAMR_FIELD_ACCOUNT_NAME);
306 TEST_USERINFO_STRING(6, full_name, 1, full_name, "xx6-1 full_name", 0);
307 TEST_USERINFO_STRING(6, full_name, 3, full_name, "xx6-3 full_name", 0);
308 TEST_USERINFO_STRING(6, full_name, 5, full_name, "xx6-5 full_name", 0);
309 TEST_USERINFO_STRING(6, full_name, 6, full_name, "xx6-6 full_name", 0);
310 TEST_USERINFO_STRING(6, full_name, 8, full_name, "xx6-8 full_name", 0);
311 TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
312 TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
313 TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name",
314 SAMR_FIELD_FULL_NAME);
316 TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
317 TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
318 TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
319 TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script",
320 SAMR_FIELD_LOGON_SCRIPT);
322 TEST_USERINFO_STRING(12, profile_path, 3, profile_path, "xx12-3 profile_path", 0);
323 TEST_USERINFO_STRING(12, profile_path, 5, profile_path, "xx12-5 profile_path", 0);
324 TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
325 TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path",
326 SAMR_FIELD_PROFILE_PATH);
328 TEST_USERINFO_STRING(13, description, 1, description, "xx13-1 description", 0);
329 TEST_USERINFO_STRING(13, description, 5, description, "xx13-5 description", 0);
330 TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
331 TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description",
332 SAMR_FIELD_DESCRIPTION);
334 TEST_USERINFO_STRING(14, workstations, 3, workstations, "14workstation3", 0);
335 TEST_USERINFO_STRING(14, workstations, 5, workstations, "14workstation4", 0);
336 TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
337 TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21",
338 SAMR_FIELD_WORKSTATIONS);
340 TEST_USERINFO_STRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
341 TEST_USERINFO_STRING(21, parameters, 21, parameters, "xx21-21 parameters",
342 SAMR_FIELD_PARAMETERS);
344 TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
345 TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__,
346 SAMR_FIELD_COUNTRY_CODE);
348 TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
349 TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__,
350 SAMR_FIELD_CODE_PAGE);
352 TEST_USERINFO_INT(4, logon_hours.bits[3], 3, logon_hours.bits[3], 1, 0);
353 TEST_USERINFO_INT(4, logon_hours.bits[3], 5, logon_hours.bits[3], 2, 0);
354 TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
355 TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4,
356 SAMR_FIELD_LOGON_HOURS);
358 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
359 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
360 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
362 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
363 (base_acct_flags | ACB_DISABLED),
364 (base_acct_flags | ACB_DISABLED | user_extra_flags),
367 /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
368 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
369 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
370 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
372 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
373 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
374 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
377 /* The 'autolock' flag doesn't stick - check this */
378 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
379 (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK),
380 (base_acct_flags | ACB_DISABLED | user_extra_flags),
382 TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags,
383 (base_acct_flags | ACB_DISABLED),
384 (base_acct_flags | ACB_DISABLED | user_extra_flags),
385 SAMR_FIELD_ACCT_FLAGS);
388 /* these fail with win2003 - it appears you can't set the primary gid?
389 the set succeeds, but the gid isn't changed. Very weird! */
390 TEST_USERINFO_INT(9, primary_gid, 1, primary_gid, 513);
391 TEST_USERINFO_INT(9, primary_gid, 3, primary_gid, 513);
392 TEST_USERINFO_INT(9, primary_gid, 5, primary_gid, 513);
393 TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
400 generate a random password for password change tests
402 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
404 size_t len = MAX(8, min_len) + (random() % 6);
405 char *s = generate_random_str(mem_ctx, len);
406 printf("Generated password '%s'\n", s);
410 static BOOL test_SetUserPass(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
411 struct policy_handle *handle, char **password)
414 struct samr_SetUserInfo s;
415 union samr_UserInfo u;
417 DATA_BLOB session_key;
419 struct samr_GetUserPwInfo pwp;
420 int policy_min_pw_len = 0;
421 pwp.in.user_handle = handle;
423 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
424 if (NT_STATUS_IS_OK(status)) {
425 policy_min_pw_len = pwp.out.info.min_password_length;
427 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
429 s.in.user_handle = handle;
433 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
434 /* w2k3 ignores this length */
435 u.info24.pw_len = strlen_m(newpass) * 2;
437 status = dcerpc_fetch_session_key(p, &session_key);
438 if (!NT_STATUS_IS_OK(status)) {
439 printf("SetUserInfo level %u - no session key - %s\n",
440 s.in.level, nt_errstr(status));
444 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
446 printf("Testing SetUserInfo level 24 (set password)\n");
448 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
449 if (!NT_STATUS_IS_OK(status)) {
450 printf("SetUserInfo level %u failed - %s\n",
451 s.in.level, nt_errstr(status));
461 static BOOL test_SetUserPass_23(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
462 struct policy_handle *handle, uint32_t fields_present,
466 struct samr_SetUserInfo s;
467 union samr_UserInfo u;
469 DATA_BLOB session_key;
471 struct samr_GetUserPwInfo pwp;
472 int policy_min_pw_len = 0;
473 pwp.in.user_handle = handle;
475 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
476 if (NT_STATUS_IS_OK(status)) {
477 policy_min_pw_len = pwp.out.info.min_password_length;
479 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
481 s.in.user_handle = handle;
487 u.info23.info.fields_present = fields_present;
489 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
491 status = dcerpc_fetch_session_key(p, &session_key);
492 if (!NT_STATUS_IS_OK(status)) {
493 printf("SetUserInfo level %u - no session key - %s\n",
494 s.in.level, nt_errstr(status));
498 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
500 printf("Testing SetUserInfo level 23 (set password)\n");
502 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
503 if (!NT_STATUS_IS_OK(status)) {
504 printf("SetUserInfo level %u failed - %s\n",
505 s.in.level, nt_errstr(status));
515 static BOOL test_SetUserPassEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
516 struct policy_handle *handle, char **password)
519 struct samr_SetUserInfo s;
520 union samr_UserInfo u;
522 DATA_BLOB session_key;
523 DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
524 uint8_t confounder[16];
526 struct MD5Context ctx;
527 struct samr_GetUserPwInfo pwp;
528 int policy_min_pw_len = 0;
529 pwp.in.user_handle = handle;
531 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
532 if (NT_STATUS_IS_OK(status)) {
533 policy_min_pw_len = pwp.out.info.min_password_length;
535 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
537 s.in.user_handle = handle;
541 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
542 u.info26.pw_len = strlen(newpass);
544 status = dcerpc_fetch_session_key(p, &session_key);
545 if (!NT_STATUS_IS_OK(status)) {
546 printf("SetUserInfo level %u - no session key - %s\n",
547 s.in.level, nt_errstr(status));
551 generate_random_buffer((uint8_t *)confounder, 16);
554 MD5Update(&ctx, confounder, 16);
555 MD5Update(&ctx, session_key.data, session_key.length);
556 MD5Final(confounded_session_key.data, &ctx);
558 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
559 memcpy(&u.info26.password.data[516], confounder, 16);
561 printf("Testing SetUserInfo level 26 (set password ex)\n");
563 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
564 if (!NT_STATUS_IS_OK(status)) {
565 printf("SetUserInfo level %u failed - %s\n",
566 s.in.level, nt_errstr(status));
575 static BOOL test_SetUserPass_25(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
576 struct policy_handle *handle, uint32_t fields_present,
580 struct samr_SetUserInfo s;
581 union samr_UserInfo u;
583 DATA_BLOB session_key;
584 DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
585 struct MD5Context ctx;
586 uint8_t confounder[16];
588 struct samr_GetUserPwInfo pwp;
589 int policy_min_pw_len = 0;
590 pwp.in.user_handle = handle;
592 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
593 if (NT_STATUS_IS_OK(status)) {
594 policy_min_pw_len = pwp.out.info.min_password_length;
596 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
598 s.in.user_handle = handle;
604 u.info25.info.fields_present = fields_present;
606 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
608 status = dcerpc_fetch_session_key(p, &session_key);
609 if (!NT_STATUS_IS_OK(status)) {
610 printf("SetUserInfo level %u - no session key - %s\n",
611 s.in.level, nt_errstr(status));
615 generate_random_buffer((uint8_t *)confounder, 16);
618 MD5Update(&ctx, confounder, 16);
619 MD5Update(&ctx, session_key.data, session_key.length);
620 MD5Final(confounded_session_key.data, &ctx);
622 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
623 memcpy(&u.info25.password.data[516], confounder, 16);
625 printf("Testing SetUserInfo level 25 (set password ex)\n");
627 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
628 if (!NT_STATUS_IS_OK(status)) {
629 printf("SetUserInfo level %u failed - %s\n",
630 s.in.level, nt_errstr(status));
639 static BOOL test_SetAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
640 struct policy_handle *handle)
643 struct samr_SetAliasInfo r;
644 struct samr_QueryAliasInfo q;
645 uint16_t levels[] = {2, 3};
649 /* Ignoring switch level 1, as that includes the number of members for the alias
650 * and setting this to a wrong value might have negative consequences
653 for (i=0;i<ARRAY_SIZE(levels);i++) {
654 printf("Testing SetAliasInfo level %u\n", levels[i]);
656 r.in.alias_handle = handle;
657 r.in.level = levels[i];
658 r.in.info = talloc(mem_ctx, union samr_AliasInfo);
659 switch (r.in.level) {
660 case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
661 case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
662 "Test Description, should test I18N as well"); break;
665 status = dcerpc_samr_SetAliasInfo(p, mem_ctx, &r);
666 if (!NT_STATUS_IS_OK(status)) {
667 printf("SetAliasInfo level %u failed - %s\n",
668 levels[i], nt_errstr(status));
672 q.in.alias_handle = handle;
673 q.in.level = levels[i];
675 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &q);
676 if (!NT_STATUS_IS_OK(status)) {
677 printf("QueryAliasInfo level %u failed - %s\n",
678 levels[i], nt_errstr(status));
686 static BOOL test_GetGroupsForUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
687 struct policy_handle *user_handle)
689 struct samr_GetGroupsForUser r;
693 printf("testing GetGroupsForUser\n");
695 r.in.user_handle = user_handle;
697 status = dcerpc_samr_GetGroupsForUser(p, mem_ctx, &r);
698 if (!NT_STATUS_IS_OK(status)) {
699 printf("GetGroupsForUser failed - %s\n",nt_errstr(status));
707 static BOOL test_GetDomPwInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
708 struct lsa_String *domain_name)
711 struct samr_GetDomPwInfo r;
714 r.in.domain_name = domain_name;
715 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
717 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
718 if (!NT_STATUS_IS_OK(status)) {
719 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
723 r.in.domain_name->string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
724 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
726 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
727 if (!NT_STATUS_IS_OK(status)) {
728 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
732 r.in.domain_name->string = "\\\\__NONAME__";
733 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
735 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
736 if (!NT_STATUS_IS_OK(status)) {
737 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
741 r.in.domain_name->string = "\\\\Builtin";
742 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
744 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
745 if (!NT_STATUS_IS_OK(status)) {
746 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
754 static BOOL test_GetUserPwInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
755 struct policy_handle *handle)
758 struct samr_GetUserPwInfo r;
761 printf("Testing GetUserPwInfo\n");
763 r.in.user_handle = handle;
765 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &r);
766 if (!NT_STATUS_IS_OK(status)) {
767 printf("GetUserPwInfo failed - %s\n", nt_errstr(status));
774 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
775 struct policy_handle *domain_handle, const char *name,
779 struct samr_LookupNames n;
780 struct lsa_String sname[2];
782 init_lsa_String(&sname[0], name);
784 n.in.domain_handle = domain_handle;
787 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
788 if (NT_STATUS_IS_OK(status)) {
789 *rid = n.out.rids.ids[0];
794 init_lsa_String(&sname[1], "xxNONAMExx");
796 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
797 if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
798 printf("LookupNames[2] failed - %s\n", nt_errstr(status));
802 init_lsa_String(&sname[1], "xxNONAMExx");
804 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
805 if (!NT_STATUS_IS_OK(status)) {
806 printf("LookupNames[0] failed - %s\n", nt_errstr(status));
812 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
813 struct policy_handle *domain_handle,
814 const char *name, struct policy_handle *user_handle)
817 struct samr_OpenUser r;
820 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
821 if (!NT_STATUS_IS_OK(status)) {
825 r.in.domain_handle = domain_handle;
826 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
828 r.out.user_handle = user_handle;
829 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
830 if (!NT_STATUS_IS_OK(status)) {
831 printf("OpenUser_byname(%s) failed - %s\n", name, nt_errstr(status));
838 static BOOL test_ChangePasswordNT3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
839 struct policy_handle *handle)
842 struct samr_ChangePasswordUser r;
844 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
845 struct policy_handle user_handle;
846 char *oldpass = "test";
847 char *newpass = "test2";
848 uint8_t old_nt_hash[16], new_nt_hash[16];
849 uint8_t old_lm_hash[16], new_lm_hash[16];
851 status = test_OpenUser_byname(p, mem_ctx, handle, "testuser", &user_handle);
852 if (!NT_STATUS_IS_OK(status)) {
856 printf("Testing ChangePasswordUser for user 'testuser'\n");
858 printf("old password: %s\n", oldpass);
859 printf("new password: %s\n", newpass);
861 E_md4hash(oldpass, old_nt_hash);
862 E_md4hash(newpass, new_nt_hash);
863 E_deshash(oldpass, old_lm_hash);
864 E_deshash(newpass, new_lm_hash);
866 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
867 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
868 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
869 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
870 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
871 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
873 r.in.handle = &user_handle;
875 r.in.old_lm_crypted = &hash1;
876 r.in.new_lm_crypted = &hash2;
878 r.in.old_nt_crypted = &hash3;
879 r.in.new_nt_crypted = &hash4;
880 r.in.cross1_present = 1;
881 r.in.nt_cross = &hash5;
882 r.in.cross2_present = 1;
883 r.in.lm_cross = &hash6;
885 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
886 if (!NT_STATUS_IS_OK(status)) {
887 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
891 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
899 static BOOL test_ChangePasswordUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
900 struct policy_handle *handle, char **password)
903 struct samr_ChangePasswordUser r;
905 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
906 struct policy_handle user_handle;
907 char *oldpass = *password;
908 uint8_t old_nt_hash[16], new_nt_hash[16];
909 uint8_t old_lm_hash[16], new_lm_hash[16];
912 struct samr_GetUserPwInfo pwp;
913 int policy_min_pw_len = 0;
915 status = test_OpenUser_byname(p, mem_ctx, handle, TEST_ACCOUNT_NAME, &user_handle);
916 if (!NT_STATUS_IS_OK(status)) {
919 pwp.in.user_handle = &user_handle;
921 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
922 if (NT_STATUS_IS_OK(status)) {
923 policy_min_pw_len = pwp.out.info.min_password_length;
925 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
927 printf("Testing ChangePasswordUser\n");
929 E_md4hash(oldpass, old_nt_hash);
930 E_md4hash(newpass, new_nt_hash);
931 E_deshash(oldpass, old_lm_hash);
932 E_deshash(newpass, new_lm_hash);
934 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
935 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
936 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
937 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
938 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
939 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
941 r.in.user_handle = &user_handle;
943 r.in.old_lm_crypted = &hash1;
944 r.in.new_lm_crypted = &hash2;
946 r.in.old_nt_crypted = &hash3;
947 r.in.new_nt_crypted = &hash4;
948 r.in.cross1_present = 1;
949 r.in.nt_cross = &hash5;
950 r.in.cross2_present = 1;
951 r.in.lm_cross = &hash6;
953 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
954 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
955 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
956 } else if (!NT_STATUS_IS_OK(status)) {
957 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
963 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
971 static BOOL test_OemChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
972 struct policy_handle *handle, char **password)
975 struct samr_OemChangePasswordUser2 r;
977 struct samr_Password lm_verifier;
978 struct samr_CryptPassword lm_pass;
979 struct lsa_AsciiString server, account, account_bad;
980 char *oldpass = *password;
982 uint8_t old_lm_hash[16], new_lm_hash[16];
984 struct samr_GetDomPwInfo dom_pw_info;
985 int policy_min_pw_len = 0;
987 struct lsa_String domain_name;
988 domain_name.string = "";
989 dom_pw_info.in.domain_name = &domain_name;
991 printf("Testing OemChangePasswordUser2\n");
993 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &dom_pw_info);
994 if (NT_STATUS_IS_OK(status)) {
995 policy_min_pw_len = dom_pw_info.out.info.min_password_length;
998 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1000 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1001 account.string = TEST_ACCOUNT_NAME;
1003 E_deshash(oldpass, old_lm_hash);
1004 E_deshash(newpass, new_lm_hash);
1006 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1007 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1008 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1010 r.in.server = &server;
1011 r.in.account = &account;
1012 r.in.password = &lm_pass;
1013 r.in.hash = &lm_verifier;
1015 /* Break the verification */
1016 lm_verifier.hash[0]++;
1018 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1020 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1021 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1022 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1027 /* This shouldn't be a valid name */
1028 account_bad.string = TEST_ACCOUNT_NAME "XX";
1029 r.in.account = &account_bad;
1031 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1033 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1034 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1039 E_deshash(oldpass, old_lm_hash);
1040 E_deshash(newpass, new_lm_hash);
1042 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1043 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1044 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1046 r.in.server = &server;
1047 r.in.account = &account;
1048 r.in.password = &lm_pass;
1049 r.in.hash = &lm_verifier;
1051 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1052 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1053 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1054 } else if (!NT_STATUS_IS_OK(status)) {
1055 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
1058 *password = newpass;
1065 static BOOL test_ChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1066 struct policy_handle *handle, char **password)
1069 struct samr_ChangePasswordUser2 r;
1071 struct lsa_String server, account;
1072 struct samr_CryptPassword nt_pass, lm_pass;
1073 struct samr_Password nt_verifier, lm_verifier;
1074 char *oldpass = *password;
1076 uint8_t old_nt_hash[16], new_nt_hash[16];
1077 uint8_t old_lm_hash[16], new_lm_hash[16];
1079 struct samr_GetDomPwInfo dom_pw_info;
1080 int policy_min_pw_len = 0;
1082 struct lsa_String domain_name;
1083 domain_name.string = "";
1084 dom_pw_info.in.domain_name = &domain_name;
1086 printf("Testing ChangePasswordUser2\n");
1088 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &dom_pw_info);
1089 if (NT_STATUS_IS_OK(status)) {
1090 policy_min_pw_len = dom_pw_info.out.info.min_password_length;
1093 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1095 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1096 init_lsa_String(&account, TEST_ACCOUNT_NAME);
1098 E_md4hash(oldpass, old_nt_hash);
1099 E_md4hash(newpass, new_nt_hash);
1101 E_deshash(oldpass, old_lm_hash);
1102 E_deshash(newpass, new_lm_hash);
1104 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
1105 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1106 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1108 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1109 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1110 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1112 r.in.server = &server;
1113 r.in.account = &account;
1114 r.in.nt_password = &nt_pass;
1115 r.in.nt_verifier = &nt_verifier;
1117 r.in.lm_password = &lm_pass;
1118 r.in.lm_verifier = &lm_verifier;
1120 status = dcerpc_samr_ChangePasswordUser2(p, mem_ctx, &r);
1121 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1122 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1123 } else if (!NT_STATUS_IS_OK(status)) {
1124 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
1127 *password = newpass;
1134 BOOL test_ChangePasswordUser3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1135 const char *account_string,
1136 int policy_min_pw_len,
1140 struct samr_ChangePasswordUser3 r;
1142 struct lsa_String server, account, account_bad;
1143 struct samr_CryptPassword nt_pass, lm_pass;
1144 struct samr_Password nt_verifier, lm_verifier;
1145 char *oldpass = *password;
1146 char *newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1147 uint8_t old_nt_hash[16], new_nt_hash[16];
1148 uint8_t old_lm_hash[16], new_lm_hash[16];
1150 printf("Testing ChangePasswordUser3\n");
1152 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1153 init_lsa_String(&account, account_string);
1155 E_md4hash(oldpass, old_nt_hash);
1156 E_md4hash(newpass, new_nt_hash);
1158 E_deshash(oldpass, old_lm_hash);
1159 E_deshash(newpass, new_lm_hash);
1161 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1162 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1163 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1165 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1166 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1167 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1169 /* Break the verification */
1170 nt_verifier.hash[0]++;
1172 r.in.server = &server;
1173 r.in.account = &account;
1174 r.in.nt_password = &nt_pass;
1175 r.in.nt_verifier = &nt_verifier;
1177 r.in.lm_password = &lm_pass;
1178 r.in.lm_verifier = &lm_verifier;
1179 r.in.password3 = NULL;
1181 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1182 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1183 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1184 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1189 /* This shouldn't be a valid name */
1190 init_lsa_String(&account_bad, talloc_asprintf(mem_ctx, "%sXX", account_string));
1192 r.in.account = &account_bad;
1193 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1194 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1195 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
1200 E_md4hash(oldpass, old_nt_hash);
1201 E_md4hash(newpass, new_nt_hash);
1203 E_deshash(oldpass, old_lm_hash);
1204 E_deshash(newpass, new_lm_hash);
1206 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1207 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1208 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1210 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1211 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1212 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1214 r.in.server = &server;
1215 r.in.account = &account;
1216 r.in.nt_password = &nt_pass;
1217 r.in.nt_verifier = &nt_verifier;
1219 r.in.lm_password = &lm_pass;
1220 r.in.lm_verifier = &lm_verifier;
1221 r.in.password3 = NULL;
1223 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1224 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1225 && !policy_min_pw_len) {
1226 if (r.out.dominfo) {
1227 policy_min_pw_len = r.out.dominfo->min_password_length;
1229 if (policy_min_pw_len) /* try again with the right min password length */ {
1230 ret = test_ChangePasswordUser3(p, mem_ctx, account_string, policy_min_pw_len, password);
1232 printf("ChangePasswordUser3 failed (no min length known) - %s\n", nt_errstr(status));
1235 } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1236 printf("ChangePasswordUser3 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1237 } else if (!NT_STATUS_IS_OK(status)) {
1238 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
1241 *password = newpass;
1248 static BOOL test_GetMembersInAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1249 struct policy_handle *alias_handle)
1251 struct samr_GetMembersInAlias r;
1252 struct lsa_SidArray sids;
1256 printf("Testing GetMembersInAlias\n");
1258 r.in.alias_handle = alias_handle;
1261 status = dcerpc_samr_GetMembersInAlias(p, mem_ctx, &r);
1262 if (!NT_STATUS_IS_OK(status)) {
1263 printf("GetMembersInAlias failed - %s\n",
1271 static BOOL test_AddMemberToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1272 struct policy_handle *alias_handle,
1273 const struct dom_sid *domain_sid)
1275 struct samr_AddAliasMember r;
1276 struct samr_DeleteAliasMember d;
1279 struct dom_sid *sid;
1281 sid = dom_sid_add_rid(mem_ctx, domain_sid, 512);
1283 printf("testing AddAliasMember\n");
1284 r.in.alias_handle = alias_handle;
1287 status = dcerpc_samr_AddAliasMember(p, mem_ctx, &r);
1288 if (!NT_STATUS_IS_OK(status)) {
1289 printf("AddAliasMember failed - %s\n", nt_errstr(status));
1293 d.in.alias_handle = alias_handle;
1296 status = dcerpc_samr_DeleteAliasMember(p, mem_ctx, &d);
1297 if (!NT_STATUS_IS_OK(status)) {
1298 printf("DelAliasMember failed - %s\n", nt_errstr(status));
1305 static BOOL test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1306 struct policy_handle *alias_handle)
1308 struct samr_AddMultipleMembersToAlias a;
1309 struct samr_RemoveMultipleMembersFromAlias r;
1312 struct lsa_SidArray sids;
1314 printf("testing AddMultipleMembersToAlias\n");
1315 a.in.alias_handle = alias_handle;
1319 sids.sids = talloc_array(mem_ctx, struct lsa_SidPtr, 3);
1321 sids.sids[0].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-1");
1322 sids.sids[1].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-2");
1323 sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-3");
1325 status = dcerpc_samr_AddMultipleMembersToAlias(p, mem_ctx, &a);
1326 if (!NT_STATUS_IS_OK(status)) {
1327 printf("AddMultipleMembersToAlias failed - %s\n", nt_errstr(status));
1332 printf("testing RemoveMultipleMembersFromAlias\n");
1333 r.in.alias_handle = alias_handle;
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 /* strange! removing twice doesn't give any error */
1343 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1344 if (!NT_STATUS_IS_OK(status)) {
1345 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1349 /* but removing an alias that isn't there does */
1350 sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-4");
1352 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1353 if (!NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_NOT_FOUND, status)) {
1354 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1361 static BOOL test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1362 struct policy_handle *user_handle)
1364 struct samr_TestPrivateFunctionsUser r;
1368 printf("Testing TestPrivateFunctionsUser\n");
1370 r.in.user_handle = user_handle;
1372 status = dcerpc_samr_TestPrivateFunctionsUser(p, mem_ctx, &r);
1373 if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
1374 printf("TestPrivateFunctionsUser failed - %s\n", nt_errstr(status));
1382 static BOOL test_user_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1383 struct policy_handle *handle, uint32_t base_acct_flags,
1384 const char *base_acct_name)
1388 if (!test_QuerySecurity(p, mem_ctx, handle)) {
1392 if (!test_QueryUserInfo(p, mem_ctx, handle)) {
1396 if (!test_QueryUserInfo2(p, mem_ctx, handle)) {
1400 if (!test_SetUserInfo(p, mem_ctx, handle, base_acct_flags,
1405 if (!test_GetUserPwInfo(p, mem_ctx, handle)) {
1409 if (!test_TestPrivateFunctionsUser(p, mem_ctx, handle)) {
1416 static BOOL test_alias_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1417 struct policy_handle *alias_handle,
1418 const struct dom_sid *domain_sid)
1422 if (!test_QuerySecurity(p, mem_ctx, alias_handle)) {
1426 if (!test_QueryAliasInfo(p, mem_ctx, alias_handle)) {
1430 if (!test_SetAliasInfo(p, mem_ctx, alias_handle)) {
1434 if (!test_AddMemberToAlias(p, mem_ctx, alias_handle, domain_sid)) {
1438 if (!test_AddMultipleMembersToAlias(p, mem_ctx, alias_handle)) {
1446 BOOL test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1447 struct policy_handle *handle, const char *name)
1450 struct samr_DeleteUser d;
1451 struct policy_handle user_handle;
1454 status = test_LookupName(p, mem_ctx, handle, name, &rid);
1455 if (!NT_STATUS_IS_OK(status)) {
1459 status = test_OpenUser_byname(p, mem_ctx, handle, name, &user_handle);
1460 if (!NT_STATUS_IS_OK(status)) {
1464 d.in.user_handle = &user_handle;
1465 d.out.user_handle = &user_handle;
1466 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
1467 if (!NT_STATUS_IS_OK(status)) {
1474 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
1479 static BOOL test_DeleteGroup_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1480 struct policy_handle *handle, const char *name)
1483 struct samr_OpenGroup r;
1484 struct samr_DeleteDomainGroup d;
1485 struct policy_handle group_handle;
1488 status = test_LookupName(p, mem_ctx, handle, name, &rid);
1489 if (!NT_STATUS_IS_OK(status)) {
1493 r.in.domain_handle = handle;
1494 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1496 r.out.group_handle = &group_handle;
1497 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
1498 if (!NT_STATUS_IS_OK(status)) {
1502 d.in.group_handle = &group_handle;
1503 d.out.group_handle = &group_handle;
1504 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
1505 if (!NT_STATUS_IS_OK(status)) {
1512 printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
1517 static BOOL test_DeleteAlias_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1518 struct policy_handle *domain_handle, const char *name)
1521 struct samr_OpenAlias r;
1522 struct samr_DeleteDomAlias d;
1523 struct policy_handle alias_handle;
1526 printf("testing DeleteAlias_byname\n");
1528 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
1529 if (!NT_STATUS_IS_OK(status)) {
1533 r.in.domain_handle = domain_handle;
1534 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1536 r.out.alias_handle = &alias_handle;
1537 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
1538 if (!NT_STATUS_IS_OK(status)) {
1542 d.in.alias_handle = &alias_handle;
1543 d.out.alias_handle = &alias_handle;
1544 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
1545 if (!NT_STATUS_IS_OK(status)) {
1552 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
1556 static BOOL test_DeleteAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1557 struct policy_handle *alias_handle)
1559 struct samr_DeleteDomAlias d;
1562 printf("Testing DeleteAlias\n");
1564 d.in.alias_handle = alias_handle;
1565 d.out.alias_handle = alias_handle;
1567 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
1568 if (!NT_STATUS_IS_OK(status)) {
1569 printf("DeleteAlias failed - %s\n", nt_errstr(status));
1576 static BOOL test_CreateAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1577 struct policy_handle *domain_handle,
1578 struct policy_handle *alias_handle,
1579 const struct dom_sid *domain_sid)
1582 struct samr_CreateDomAlias r;
1583 struct lsa_String name;
1587 init_lsa_String(&name, TEST_ALIASNAME);
1588 r.in.domain_handle = domain_handle;
1589 r.in.alias_name = &name;
1590 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1591 r.out.alias_handle = alias_handle;
1594 printf("Testing CreateAlias (%s)\n", r.in.alias_name->string);
1596 status = dcerpc_samr_CreateDomAlias(p, mem_ctx, &r);
1598 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1599 printf("Server refused create of '%s'\n", r.in.alias_name->string);
1603 if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
1604 if (!test_DeleteAlias_byname(p, mem_ctx, domain_handle, r.in.alias_name->string)) {
1607 status = dcerpc_samr_CreateDomAlias(p, mem_ctx, &r);
1610 if (!NT_STATUS_IS_OK(status)) {
1611 printf("CreateAlias failed - %s\n", nt_errstr(status));
1615 if (!test_alias_ops(p, mem_ctx, alias_handle, domain_sid)) {
1622 static BOOL test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1623 struct policy_handle *domain_handle, char **password)
1631 if (!test_ChangePasswordUser(p, mem_ctx, domain_handle, password)) {
1635 if (!test_ChangePasswordUser2(p, mem_ctx, domain_handle, password)) {
1639 if (!test_OemChangePasswordUser2(p, mem_ctx, domain_handle, password)) {
1643 /* we change passwords twice - this has the effect of verifying
1644 they were changed correctly for the final call */
1645 if (!test_ChangePasswordUser3(p, mem_ctx, TEST_ACCOUNT_NAME, 0, password)) {
1649 if (!test_ChangePasswordUser3(p, mem_ctx, TEST_ACCOUNT_NAME, 0, password)) {
1656 static BOOL test_CreateUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1657 struct policy_handle *domain_handle, struct policy_handle *user_handle)
1660 struct samr_CreateUser r;
1661 struct samr_QueryUserInfo q;
1663 char *password = NULL;
1666 const uint32_t password_fields[] = {
1667 SAMR_FIELD_PASSWORD,
1668 SAMR_FIELD_PASSWORD2,
1669 SAMR_FIELD_PASSWORD | SAMR_FIELD_PASSWORD2,
1673 TALLOC_CTX *user_ctx;
1675 /* This call creates a 'normal' account - check that it really does */
1676 const uint32_t acct_flags = ACB_NORMAL;
1677 struct lsa_String name;
1680 user_ctx = talloc_named(mem_ctx, 0, "test_CreateUser2 per-user context");
1681 init_lsa_String(&name, TEST_ACCOUNT_NAME);
1683 r.in.domain_handle = domain_handle;
1684 r.in.account_name = &name;
1685 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1686 r.out.user_handle = user_handle;
1689 printf("Testing CreateUser(%s)\n", r.in.account_name->string);
1691 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
1693 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1694 printf("Server refused create of '%s'\n", r.in.account_name->string);
1695 ZERO_STRUCTP(user_handle);
1696 talloc_free(user_ctx);
1700 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
1701 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
1702 talloc_free(user_ctx);
1705 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
1707 if (!NT_STATUS_IS_OK(status)) {
1708 talloc_free(user_ctx);
1709 printf("CreateUser failed - %s\n", nt_errstr(status));
1713 q.in.user_handle = user_handle;
1716 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
1717 if (!NT_STATUS_IS_OK(status)) {
1718 printf("QueryUserInfo level %u failed - %s\n",
1719 q.in.level, nt_errstr(status));
1722 if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
1723 printf("QuerUserInfo level 16 failed, it returned 0x%08x (%u) when we expected flags of 0x%08x (%u)\n",
1724 q.out.info->info16.acct_flags, q.out.info->info16.acct_flags,
1725 acct_flags, acct_flags);
1730 if (!test_user_ops(p, user_ctx, user_handle, acct_flags, name.string)) {
1734 if (!test_SetUserPass(p, user_ctx, user_handle, &password)) {
1738 for (i = 0; password_fields[i]; i++) {
1739 if (!test_SetUserPass_23(p, user_ctx, user_handle, password_fields[i], &password)) {
1743 /* check it was set right */
1744 if (!test_ChangePasswordUser3(p, user_ctx, TEST_ACCOUNT_NAME, 0, &password)) {
1749 for (i = 0; password_fields[i]; i++) {
1750 if (!test_SetUserPass_25(p, user_ctx, user_handle, password_fields[i], &password)) {
1754 /* check it was set right */
1755 if (!test_ChangePasswordUser3(p, user_ctx, TEST_ACCOUNT_NAME, 0, &password)) {
1760 if (!test_SetUserPassEx(p, user_ctx, user_handle, &password)) {
1764 if (!test_ChangePassword(p, user_ctx, domain_handle, &password)) {
1768 talloc_free(user_ctx);
1774 static BOOL test_DeleteUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1775 struct policy_handle *user_handle)
1777 struct samr_DeleteUser d;
1781 printf("Testing DeleteUser\n");
1783 d.in.user_handle = user_handle;
1784 d.out.user_handle = user_handle;
1786 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
1787 if (!NT_STATUS_IS_OK(status)) {
1788 printf("DeleteUser failed - %s\n", nt_errstr(status));
1795 static BOOL test_CreateUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1796 struct policy_handle *handle)
1799 struct samr_CreateUser2 r;
1800 struct samr_QueryUserInfo q;
1801 struct samr_DeleteUser d;
1802 struct policy_handle user_handle;
1804 struct lsa_String name;
1809 uint32_t acct_flags;
1810 const char *account_name;
1812 } account_types[] = {
1813 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
1814 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1815 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1816 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
1817 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1818 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1819 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
1820 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1821 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1822 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
1823 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
1824 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
1825 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1826 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1827 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
1830 for (i = 0; account_types[i].account_name; i++) {
1831 TALLOC_CTX *user_ctx;
1832 uint32_t acct_flags = account_types[i].acct_flags;
1833 uint32_t access_granted;
1834 user_ctx = talloc_named(mem_ctx, 0, "test_CreateUser2 per-user context");
1835 init_lsa_String(&name, account_types[i].account_name);
1837 r.in.domain_handle = handle;
1838 r.in.account_name = &name;
1839 r.in.acct_flags = acct_flags;
1840 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1841 r.out.user_handle = &user_handle;
1842 r.out.access_granted = &access_granted;
1845 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
1847 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
1849 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1850 talloc_free(user_ctx);
1851 printf("Server refused create of '%s'\n", r.in.account_name->string);
1854 } else if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
1855 if (!test_DeleteUser_byname(p, user_ctx, handle, r.in.account_name->string)) {
1856 talloc_free(user_ctx);
1860 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
1863 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
1864 printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
1865 nt_errstr(status), nt_errstr(account_types[i].nt_status));
1869 if (NT_STATUS_IS_OK(status)) {
1870 q.in.user_handle = &user_handle;
1873 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
1874 if (!NT_STATUS_IS_OK(status)) {
1875 printf("QueryUserInfo level %u failed - %s\n",
1876 q.in.level, nt_errstr(status));
1879 if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
1880 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
1881 q.out.info->info16.acct_flags,
1887 if (!test_user_ops(p, user_ctx, &user_handle, acct_flags, name.string)) {
1891 printf("Testing DeleteUser (createuser2 test)\n");
1893 d.in.user_handle = &user_handle;
1894 d.out.user_handle = &user_handle;
1896 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
1897 if (!NT_STATUS_IS_OK(status)) {
1898 printf("DeleteUser failed - %s\n", nt_errstr(status));
1902 talloc_free(user_ctx);
1908 static BOOL test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1909 struct policy_handle *handle)
1912 struct samr_QueryAliasInfo r;
1913 uint16_t levels[] = {1, 2, 3};
1917 for (i=0;i<ARRAY_SIZE(levels);i++) {
1918 printf("Testing QueryAliasInfo level %u\n", levels[i]);
1920 r.in.alias_handle = handle;
1921 r.in.level = levels[i];
1923 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
1924 if (!NT_STATUS_IS_OK(status)) {
1925 printf("QueryAliasInfo level %u failed - %s\n",
1926 levels[i], nt_errstr(status));
1934 static BOOL test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1935 struct policy_handle *handle)
1938 struct samr_QueryGroupInfo r;
1939 uint16_t levels[] = {1, 2, 3, 4, 5};
1943 for (i=0;i<ARRAY_SIZE(levels);i++) {
1944 printf("Testing QueryGroupInfo level %u\n", levels[i]);
1946 r.in.group_handle = handle;
1947 r.in.level = levels[i];
1949 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
1950 if (!NT_STATUS_IS_OK(status)) {
1951 printf("QueryGroupInfo level %u failed - %s\n",
1952 levels[i], nt_errstr(status));
1960 static BOOL test_QueryGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1961 struct policy_handle *handle)
1964 struct samr_QueryGroupMember r;
1967 printf("Testing QueryGroupMember\n");
1969 r.in.group_handle = handle;
1971 status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &r);
1972 if (!NT_STATUS_IS_OK(status)) {
1973 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
1981 static BOOL test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1982 struct policy_handle *handle)
1985 struct samr_QueryGroupInfo r;
1986 struct samr_SetGroupInfo s;
1987 uint16_t levels[] = {1, 2, 3, 4};
1988 uint16_t set_ok[] = {0, 1, 1, 1};
1992 for (i=0;i<ARRAY_SIZE(levels);i++) {
1993 printf("Testing QueryGroupInfo level %u\n", levels[i]);
1995 r.in.group_handle = handle;
1996 r.in.level = levels[i];
1998 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
1999 if (!NT_STATUS_IS_OK(status)) {
2000 printf("QueryGroupInfo level %u failed - %s\n",
2001 levels[i], nt_errstr(status));
2005 printf("Testing SetGroupInfo level %u\n", levels[i]);
2007 s.in.group_handle = handle;
2008 s.in.level = levels[i];
2009 s.in.info = r.out.info;
2012 /* disabled this, as it changes the name only from the point of view of samr,
2013 but leaves the name from the point of view of w2k3 internals (and ldap). This means
2014 the name is still reserved, so creating the old name fails, but deleting by the old name
2016 if (s.in.level == 2) {
2017 init_lsa_String(&s.in.info->string, "NewName");
2021 if (s.in.level == 4) {
2022 init_lsa_String(&s.in.info->description, "test description");
2025 status = dcerpc_samr_SetGroupInfo(p, mem_ctx, &s);
2027 if (!NT_STATUS_IS_OK(status)) {
2028 printf("SetGroupInfo level %u failed - %s\n",
2029 r.in.level, nt_errstr(status));
2034 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
2035 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
2036 r.in.level, nt_errstr(status));
2046 static BOOL test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2047 struct policy_handle *handle)
2050 struct samr_QueryUserInfo r;
2051 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
2052 11, 12, 13, 14, 16, 17, 20, 21};
2056 for (i=0;i<ARRAY_SIZE(levels);i++) {
2057 printf("Testing QueryUserInfo level %u\n", levels[i]);
2059 r.in.user_handle = handle;
2060 r.in.level = levels[i];
2062 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
2063 if (!NT_STATUS_IS_OK(status)) {
2064 printf("QueryUserInfo level %u failed - %s\n",
2065 levels[i], nt_errstr(status));
2073 static BOOL test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2074 struct policy_handle *handle)
2077 struct samr_QueryUserInfo2 r;
2078 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
2079 11, 12, 13, 14, 16, 17, 20, 21};
2083 for (i=0;i<ARRAY_SIZE(levels);i++) {
2084 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
2086 r.in.user_handle = handle;
2087 r.in.level = levels[i];
2089 status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r);
2090 if (!NT_STATUS_IS_OK(status)) {
2091 printf("QueryUserInfo2 level %u failed - %s\n",
2092 levels[i], nt_errstr(status));
2100 static BOOL test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2101 struct policy_handle *handle, uint32_t rid)
2104 struct samr_OpenUser r;
2105 struct policy_handle user_handle;
2108 printf("Testing OpenUser(%u)\n", rid);
2110 r.in.domain_handle = handle;
2111 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2113 r.out.user_handle = &user_handle;
2115 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
2116 if (!NT_STATUS_IS_OK(status)) {
2117 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
2121 if (!test_QuerySecurity(p, mem_ctx, &user_handle)) {
2125 if (!test_QueryUserInfo(p, mem_ctx, &user_handle)) {
2129 if (!test_QueryUserInfo2(p, mem_ctx, &user_handle)) {
2133 if (!test_GetUserPwInfo(p, mem_ctx, &user_handle)) {
2137 if (!test_GetGroupsForUser(p,mem_ctx, &user_handle)) {
2141 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
2148 static BOOL test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2149 struct policy_handle *handle, uint32_t rid)
2152 struct samr_OpenGroup r;
2153 struct policy_handle group_handle;
2156 printf("Testing OpenGroup(%u)\n", rid);
2158 r.in.domain_handle = handle;
2159 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2161 r.out.group_handle = &group_handle;
2163 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
2164 if (!NT_STATUS_IS_OK(status)) {
2165 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
2169 if (!test_QuerySecurity(p, mem_ctx, &group_handle)) {
2173 if (!test_QueryGroupInfo(p, mem_ctx, &group_handle)) {
2177 if (!test_QueryGroupMember(p, mem_ctx, &group_handle)) {
2181 if (!test_samr_handle_Close(p, mem_ctx, &group_handle)) {
2188 static BOOL test_OpenAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2189 struct policy_handle *handle, uint32_t rid)
2192 struct samr_OpenAlias r;
2193 struct policy_handle alias_handle;
2196 printf("Testing OpenAlias(%u)\n", rid);
2198 r.in.domain_handle = handle;
2199 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2201 r.out.alias_handle = &alias_handle;
2203 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
2204 if (!NT_STATUS_IS_OK(status)) {
2205 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
2209 if (!test_QuerySecurity(p, mem_ctx, &alias_handle)) {
2213 if (!test_QueryAliasInfo(p, mem_ctx, &alias_handle)) {
2217 if (!test_GetMembersInAlias(p, mem_ctx, &alias_handle)) {
2221 if (!test_samr_handle_Close(p, mem_ctx, &alias_handle)) {
2228 static BOOL test_EnumDomainUsers(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2229 struct policy_handle *handle)
2232 struct samr_EnumDomainUsers r;
2233 uint32_t resume_handle=0;
2236 struct samr_LookupNames n;
2237 struct samr_LookupRids lr ;
2239 printf("Testing EnumDomainUsers\n");
2241 r.in.domain_handle = handle;
2242 r.in.resume_handle = &resume_handle;
2243 r.in.acct_flags = 0;
2244 r.in.max_size = (uint32_t)-1;
2245 r.out.resume_handle = &resume_handle;
2247 status = dcerpc_samr_EnumDomainUsers(p, mem_ctx, &r);
2248 if (!NT_STATUS_IS_OK(status)) {
2249 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
2257 if (r.out.sam->count == 0) {
2261 for (i=0;i<r.out.sam->count;i++) {
2262 if (!test_OpenUser(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
2267 printf("Testing LookupNames\n");
2268 n.in.domain_handle = handle;
2269 n.in.num_names = r.out.sam->count;
2270 n.in.names = talloc_array(mem_ctx, struct lsa_String, r.out.sam->count);
2271 for (i=0;i<r.out.sam->count;i++) {
2272 n.in.names[i].string = r.out.sam->entries[i].name.string;
2274 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
2275 if (!NT_STATUS_IS_OK(status)) {
2276 printf("LookupNames failed - %s\n", nt_errstr(status));
2281 printf("Testing LookupRids\n");
2282 lr.in.domain_handle = handle;
2283 lr.in.num_rids = r.out.sam->count;
2284 lr.in.rids = talloc_array(mem_ctx, uint32_t, r.out.sam->count);
2285 for (i=0;i<r.out.sam->count;i++) {
2286 lr.in.rids[i] = r.out.sam->entries[i].idx;
2288 status = dcerpc_samr_LookupRids(p, mem_ctx, &lr);
2289 if (!NT_STATUS_IS_OK(status)) {
2290 printf("LookupRids failed - %s\n", nt_errstr(status));
2298 try blasting the server with a bunch of sync requests
2300 static BOOL test_EnumDomainUsers_async(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2301 struct policy_handle *handle)
2304 struct samr_EnumDomainUsers r;
2305 uint32_t resume_handle=0;
2307 #define ASYNC_COUNT 100
2308 struct rpc_request *req[ASYNC_COUNT];
2310 if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
2311 printf("samr async test disabled - enable dangerous tests to use\n");
2315 printf("Testing EnumDomainUsers_async\n");
2317 r.in.domain_handle = handle;
2318 r.in.resume_handle = &resume_handle;
2319 r.in.acct_flags = 0;
2320 r.in.max_size = (uint32_t)-1;
2321 r.out.resume_handle = &resume_handle;
2323 for (i=0;i<ASYNC_COUNT;i++) {
2324 req[i] = dcerpc_samr_EnumDomainUsers_send(p, mem_ctx, &r);
2327 for (i=0;i<ASYNC_COUNT;i++) {
2328 status = dcerpc_ndr_request_recv(req[i]);
2329 if (!NT_STATUS_IS_OK(status)) {
2330 printf("EnumDomainUsers[%d] failed - %s\n",
2331 i, nt_errstr(status));
2336 printf("%d async requests OK\n", i);
2341 static BOOL test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2342 struct policy_handle *handle)
2345 struct samr_EnumDomainGroups r;
2346 uint32_t resume_handle=0;
2350 printf("Testing EnumDomainGroups\n");
2352 r.in.domain_handle = handle;
2353 r.in.resume_handle = &resume_handle;
2354 r.in.max_size = (uint32_t)-1;
2355 r.out.resume_handle = &resume_handle;
2357 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
2358 if (!NT_STATUS_IS_OK(status)) {
2359 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
2367 for (i=0;i<r.out.sam->count;i++) {
2368 if (!test_OpenGroup(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
2376 static BOOL test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2377 struct policy_handle *handle)
2380 struct samr_EnumDomainAliases r;
2381 uint32_t resume_handle=0;
2385 printf("Testing EnumDomainAliases\n");
2387 r.in.domain_handle = handle;
2388 r.in.resume_handle = &resume_handle;
2389 r.in.acct_flags = (uint32_t)-1;
2390 r.out.resume_handle = &resume_handle;
2392 status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
2393 if (!NT_STATUS_IS_OK(status)) {
2394 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
2402 for (i=0;i<r.out.sam->count;i++) {
2403 if (!test_OpenAlias(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
2411 static BOOL test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2412 struct policy_handle *handle)
2415 struct samr_GetDisplayEnumerationIndex r;
2417 uint16_t levels[] = {1, 2, 3, 4, 5};
2418 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
2421 for (i=0;i<ARRAY_SIZE(levels);i++) {
2422 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
2424 r.in.domain_handle = handle;
2425 r.in.level = levels[i];
2426 init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
2428 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
2431 !NT_STATUS_IS_OK(status) &&
2432 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2433 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
2434 levels[i], nt_errstr(status));
2438 init_lsa_String(&r.in.name, "zzzzzzzz");
2440 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
2442 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2443 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
2444 levels[i], nt_errstr(status));
2452 static BOOL test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2453 struct policy_handle *handle)
2456 struct samr_GetDisplayEnumerationIndex2 r;
2458 uint16_t levels[] = {1, 2, 3, 4, 5};
2459 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
2462 for (i=0;i<ARRAY_SIZE(levels);i++) {
2463 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
2465 r.in.domain_handle = handle;
2466 r.in.level = levels[i];
2467 init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
2469 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
2471 !NT_STATUS_IS_OK(status) &&
2472 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2473 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
2474 levels[i], nt_errstr(status));
2478 init_lsa_String(&r.in.name, "zzzzzzzz");
2480 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
2481 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2482 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
2483 levels[i], nt_errstr(status));
2491 static BOOL test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2492 struct policy_handle *handle)
2495 struct samr_QueryDisplayInfo r;
2497 uint16_t levels[] = {1, 2, 3, 4, 5};
2500 for (i=0;i<ARRAY_SIZE(levels);i++) {
2501 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
2503 r.in.domain_handle = handle;
2504 r.in.level = levels[i];
2506 r.in.max_entries = 1000;
2507 r.in.buf_size = (uint32_t)-1;
2509 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
2510 if (!NT_STATUS_IS_OK(status)) {
2511 printf("QueryDisplayInfo level %u failed - %s\n",
2512 levels[i], nt_errstr(status));
2520 static BOOL test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2521 struct policy_handle *handle)
2524 struct samr_QueryDisplayInfo2 r;
2526 uint16_t levels[] = {1, 2, 3, 4, 5};
2529 for (i=0;i<ARRAY_SIZE(levels);i++) {
2530 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
2532 r.in.domain_handle = handle;
2533 r.in.level = levels[i];
2535 r.in.max_entries = 1000;
2536 r.in.buf_size = (uint32_t)-1;
2538 status = dcerpc_samr_QueryDisplayInfo2(p, mem_ctx, &r);
2539 if (!NT_STATUS_IS_OK(status)) {
2540 printf("QueryDisplayInfo2 level %u failed - %s\n",
2541 levels[i], nt_errstr(status));
2549 static BOOL test_QueryDisplayInfo3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2550 struct policy_handle *handle)
2553 struct samr_QueryDisplayInfo3 r;
2555 uint16_t levels[] = {1, 2, 3, 4, 5};
2558 for (i=0;i<ARRAY_SIZE(levels);i++) {
2559 printf("Testing QueryDisplayInfo3 level %u\n", levels[i]);
2561 r.in.domain_handle = handle;
2562 r.in.level = levels[i];
2564 r.in.max_entries = 1000;
2565 r.in.buf_size = (uint32_t)-1;
2567 status = dcerpc_samr_QueryDisplayInfo3(p, mem_ctx, &r);
2568 if (!NT_STATUS_IS_OK(status)) {
2569 printf("QueryDisplayInfo3 level %u failed - %s\n",
2570 levels[i], nt_errstr(status));
2579 static BOOL test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2580 struct policy_handle *handle)
2583 struct samr_QueryDisplayInfo r;
2586 printf("Testing QueryDisplayInfo continuation\n");
2588 r.in.domain_handle = handle;
2591 r.in.max_entries = 1;
2592 r.in.buf_size = (uint32_t)-1;
2595 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
2596 if (NT_STATUS_IS_OK(status) && r.out.returned_size != 0) {
2597 if (r.out.info.info1.entries[0].idx != r.in.start_idx + 1) {
2598 printf("failed: expected idx %d but got %d\n",
2600 r.out.info.info1.entries[0].idx);
2605 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
2606 !NT_STATUS_IS_OK(status)) {
2607 printf("QueryDisplayInfo level %u failed - %s\n",
2608 r.in.level, nt_errstr(status));
2613 } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
2614 NT_STATUS_IS_OK(status)) &&
2615 r.out.returned_size != 0);
2620 static BOOL test_QueryDomainInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2621 struct policy_handle *handle)
2624 struct samr_QueryDomainInfo r;
2625 struct samr_SetDomainInfo s;
2626 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
2627 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
2631 for (i=0;i<ARRAY_SIZE(levels);i++) {
2632 printf("Testing QueryDomainInfo level %u\n", levels[i]);
2634 r.in.domain_handle = handle;
2635 r.in.level = levels[i];
2637 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2638 if (!NT_STATUS_IS_OK(status)) {
2639 printf("QueryDomainInfo level %u failed - %s\n",
2640 r.in.level, nt_errstr(status));
2645 printf("Testing SetDomainInfo level %u\n", levels[i]);
2647 s.in.domain_handle = handle;
2648 s.in.level = levels[i];
2649 s.in.info = r.out.info;
2651 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2653 if (!NT_STATUS_IS_OK(status)) {
2654 printf("SetDomainInfo level %u failed - %s\n",
2655 r.in.level, nt_errstr(status));
2660 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
2661 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
2662 r.in.level, nt_errstr(status));
2668 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2669 if (!NT_STATUS_IS_OK(status)) {
2670 printf("QueryDomainInfo level %u failed - %s\n",
2671 r.in.level, nt_errstr(status));
2681 static BOOL test_QueryDomainInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2682 struct policy_handle *handle)
2685 struct samr_QueryDomainInfo2 r;
2686 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
2690 for (i=0;i<ARRAY_SIZE(levels);i++) {
2691 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
2693 r.in.domain_handle = handle;
2694 r.in.level = levels[i];
2696 status = dcerpc_samr_QueryDomainInfo2(p, mem_ctx, &r);
2697 if (!NT_STATUS_IS_OK(status)) {
2698 printf("QueryDomainInfo2 level %u failed - %s\n",
2699 r.in.level, nt_errstr(status));
2708 /* Test whether querydispinfo level 5 and enumdomgroups return the same
2709 set of group names. */
2710 static BOOL test_GroupList(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2711 struct policy_handle *handle)
2713 struct samr_EnumDomainGroups q1;
2714 struct samr_QueryDisplayInfo q2;
2716 uint32_t resume_handle=0;
2721 const char **names = NULL;
2723 printf("Testing coherency of querydispinfo vs enumdomgroups\n");
2725 q1.in.domain_handle = handle;
2726 q1.in.resume_handle = &resume_handle;
2728 q1.out.resume_handle = &resume_handle;
2730 status = STATUS_MORE_ENTRIES;
2731 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
2732 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &q1);
2734 if (!NT_STATUS_IS_OK(status) &&
2735 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
2738 for (i=0; i<q1.out.num_entries; i++) {
2739 add_string_to_array(mem_ctx,
2740 q1.out.sam->entries[i].name.string,
2741 &names, &num_names);
2745 if (!NT_STATUS_IS_OK(status)) {
2746 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
2754 q2.in.domain_handle = handle;
2756 q2.in.start_idx = 0;
2757 q2.in.max_entries = 5;
2758 q2.in.buf_size = (uint32_t)-1;
2760 status = STATUS_MORE_ENTRIES;
2761 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
2762 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &q2);
2764 if (!NT_STATUS_IS_OK(status) &&
2765 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
2768 for (i=0; i<q2.out.info.info5.count; i++) {
2770 const char *name = q2.out.info.info5.entries[i].account_name.string;
2772 for (j=0; j<num_names; j++) {
2773 if (names[j] == NULL)
2775 /* Hmm. No strequal in samba4 */
2776 if (strequal(names[j], name)) {
2784 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
2789 q2.in.start_idx += q2.out.info.info5.count;
2792 if (!NT_STATUS_IS_OK(status)) {
2793 printf("QueryDisplayInfo level 5 failed - %s\n",
2798 for (i=0; i<num_names; i++) {
2799 if (names[i] != NULL) {
2800 printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
2809 static BOOL test_DeleteDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2810 struct policy_handle *group_handle)
2812 struct samr_DeleteDomainGroup d;
2816 printf("Testing DeleteDomainGroup\n");
2818 d.in.group_handle = group_handle;
2819 d.out.group_handle = group_handle;
2821 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
2822 if (!NT_STATUS_IS_OK(status)) {
2823 printf("DeleteDomainGroup failed - %s\n", nt_errstr(status));
2830 static BOOL test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2831 struct policy_handle *domain_handle)
2833 struct samr_TestPrivateFunctionsDomain r;
2837 printf("Testing TestPrivateFunctionsDomain\n");
2839 r.in.domain_handle = domain_handle;
2841 status = dcerpc_samr_TestPrivateFunctionsDomain(p, mem_ctx, &r);
2842 if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
2843 printf("TestPrivateFunctionsDomain failed - %s\n", nt_errstr(status));
2850 static BOOL test_RidToSid(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2851 struct dom_sid *domain_sid,
2852 struct policy_handle *domain_handle)
2854 struct samr_RidToSid r;
2857 struct dom_sid *calc_sid;
2858 int rids[] = { 0, 42, 512, 10200 };
2861 for (i=0;i<ARRAY_SIZE(rids);i++) {
2863 printf("Testing RidToSid\n");
2865 calc_sid = dom_sid_dup(mem_ctx, domain_sid);
2866 r.in.domain_handle = domain_handle;
2869 status = dcerpc_samr_RidToSid(p, mem_ctx, &r);
2870 if (!NT_STATUS_IS_OK(status)) {
2871 printf("RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
2874 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
2876 if (!dom_sid_equal(calc_sid, r.out.sid)) {
2877 printf("RidToSid for %d failed - got %s, expected %s\n", rids[i],
2878 dom_sid_string(mem_ctx, r.out.sid),
2879 dom_sid_string(mem_ctx, calc_sid));
2888 static BOOL test_GetBootKeyInformation(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2889 struct policy_handle *domain_handle)
2891 struct samr_GetBootKeyInformation r;
2895 printf("Testing GetBootKeyInformation\n");
2897 r.in.domain_handle = domain_handle;
2899 status = dcerpc_samr_GetBootKeyInformation(p, mem_ctx, &r);
2900 if (!NT_STATUS_IS_OK(status)) {
2901 /* w2k3 seems to fail this sometimes and pass it sometimes */
2902 printf("GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
2908 static BOOL test_AddGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2909 struct policy_handle *domain_handle,
2910 struct policy_handle *group_handle)
2913 struct samr_AddGroupMember r;
2914 struct samr_DeleteGroupMember d;
2915 struct samr_QueryGroupMember q;
2916 struct samr_SetMemberAttributesOfGroup s;
2920 status = test_LookupName(p, mem_ctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
2921 if (!NT_STATUS_IS_OK(status)) {
2925 r.in.group_handle = group_handle;
2927 r.in.flags = 0; /* ??? */
2929 printf("Testing AddGroupMember and DeleteGroupMember\n");
2931 d.in.group_handle = group_handle;
2934 status = dcerpc_samr_DeleteGroupMember(p, mem_ctx, &d);
2935 if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_NOT_IN_GROUP, status)) {
2936 printf("DeleteGroupMember gave %s - should be NT_STATUS_MEMBER_NOT_IN_GROUP\n",
2941 status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
2942 if (!NT_STATUS_IS_OK(status)) {
2943 printf("AddGroupMember failed - %s\n", nt_errstr(status));
2947 status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
2948 if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_IN_GROUP, status)) {
2949 printf("AddGroupMember gave %s - should be NT_STATUS_MEMBER_IN_GROUP\n",
2954 /* this one is quite strange. I am using random inputs in the
2955 hope of triggering an error that might give us a clue */
2956 s.in.group_handle = group_handle;
2957 s.in.unknown1 = random();
2958 s.in.unknown2 = random();
2960 status = dcerpc_samr_SetMemberAttributesOfGroup(p, mem_ctx, &s);
2961 if (!NT_STATUS_IS_OK(status)) {
2962 printf("SetMemberAttributesOfGroup failed - %s\n", nt_errstr(status));
2966 q.in.group_handle = group_handle;
2968 status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &q);
2969 if (!NT_STATUS_IS_OK(status)) {
2970 printf("QueryGroupMember failed - %s\n", nt_errstr(status));
2974 status = dcerpc_samr_DeleteGroupMember(p, mem_ctx, &d);
2975 if (!NT_STATUS_IS_OK(status)) {
2976 printf("DeleteGroupMember failed - %s\n", nt_errstr(status));
2980 status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
2981 if (!NT_STATUS_IS_OK(status)) {
2982 printf("AddGroupMember failed - %s\n", nt_errstr(status));
2990 static BOOL test_CreateDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2991 struct policy_handle *domain_handle, struct policy_handle *group_handle)
2994 struct samr_CreateDomainGroup r;
2996 struct lsa_String name;
2999 init_lsa_String(&name, TEST_GROUPNAME);
3001 r.in.domain_handle = domain_handle;
3003 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3004 r.out.group_handle = group_handle;
3007 printf("Testing CreateDomainGroup(%s)\n", r.in.name->string);
3009 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
3011 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
3012 printf("Server refused create of '%s'\n", r.in.name->string);
3013 ZERO_STRUCTP(group_handle);
3017 if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS) ||
3018 NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
3019 if (!test_DeleteGroup_byname(p, mem_ctx, domain_handle, r.in.name->string)) {
3022 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
3024 if (!NT_STATUS_IS_OK(status)) {
3025 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
3029 if (!test_AddGroupMember(p, mem_ctx, domain_handle, group_handle)) {
3033 if (!test_SetGroupInfo(p, mem_ctx, group_handle)) {
3042 its not totally clear what this does. It seems to accept any sid you like.
3044 static BOOL test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p,
3045 TALLOC_CTX *mem_ctx,
3046 struct policy_handle *domain_handle)
3049 struct samr_RemoveMemberFromForeignDomain r;
3051 r.in.domain_handle = domain_handle;
3052 r.in.sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-12-34-56-78");
3054 status = dcerpc_samr_RemoveMemberFromForeignDomain(p, mem_ctx, &r);
3055 if (!NT_STATUS_IS_OK(status)) {
3056 printf("RemoveMemberFromForeignDomain failed - %s\n", nt_errstr(status));
3065 static BOOL test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3066 struct policy_handle *handle);
3068 static BOOL test_OpenDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3069 struct policy_handle *handle, struct dom_sid *sid)
3072 struct samr_OpenDomain r;
3073 struct policy_handle domain_handle;
3074 struct policy_handle user_handle;
3075 struct policy_handle alias_handle;
3076 struct policy_handle group_handle;
3079 ZERO_STRUCT(user_handle);
3080 ZERO_STRUCT(alias_handle);
3081 ZERO_STRUCT(group_handle);
3082 ZERO_STRUCT(domain_handle);
3084 printf("Testing OpenDomain\n");
3086 r.in.connect_handle = handle;
3087 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3089 r.out.domain_handle = &domain_handle;
3091 status = dcerpc_samr_OpenDomain(p, mem_ctx, &r);
3092 if (!NT_STATUS_IS_OK(status)) {
3093 printf("OpenDomain failed - %s\n", nt_errstr(status));
3097 /* run the domain tests with the main handle closed - this tests
3098 the servers reference counting */
3099 ret &= test_samr_handle_Close(p, mem_ctx, handle);
3101 ret &= test_QuerySecurity(p, mem_ctx, &domain_handle);
3102 ret &= test_RemoveMemberFromForeignDomain(p, mem_ctx, &domain_handle);
3103 ret &= test_CreateUser2(p, mem_ctx, &domain_handle);
3104 ret &= test_CreateUser(p, mem_ctx, &domain_handle, &user_handle);
3105 ret &= test_CreateAlias(p, mem_ctx, &domain_handle, &alias_handle, sid);
3106 ret &= test_CreateDomainGroup(p, mem_ctx, &domain_handle, &group_handle);
3107 ret &= test_QueryDomainInfo(p, mem_ctx, &domain_handle);
3108 ret &= test_QueryDomainInfo2(p, mem_ctx, &domain_handle);
3109 ret &= test_EnumDomainUsers(p, mem_ctx, &domain_handle);
3110 ret &= test_EnumDomainUsers_async(p, mem_ctx, &domain_handle);
3111 ret &= test_EnumDomainGroups(p, mem_ctx, &domain_handle);
3112 ret &= test_EnumDomainAliases(p, mem_ctx, &domain_handle);
3113 ret &= test_QueryDisplayInfo(p, mem_ctx, &domain_handle);
3114 ret &= test_QueryDisplayInfo2(p, mem_ctx, &domain_handle);
3115 ret &= test_QueryDisplayInfo3(p, mem_ctx, &domain_handle);
3116 ret &= test_QueryDisplayInfo_continue(p, mem_ctx, &domain_handle);
3117 ret &= test_GetDisplayEnumerationIndex(p, mem_ctx, &domain_handle);
3118 ret &= test_GetDisplayEnumerationIndex2(p, mem_ctx, &domain_handle);
3119 ret &= test_GroupList(p, mem_ctx, &domain_handle);
3120 ret &= test_TestPrivateFunctionsDomain(p, mem_ctx, &domain_handle);
3121 ret &= test_RidToSid(p, mem_ctx, sid, &domain_handle);
3122 ret &= test_GetBootKeyInformation(p, mem_ctx, &domain_handle);
3124 if (!policy_handle_empty(&user_handle) &&
3125 !test_DeleteUser(p, mem_ctx, &user_handle)) {
3129 if (!policy_handle_empty(&alias_handle) &&
3130 !test_DeleteAlias(p, mem_ctx, &alias_handle)) {
3134 if (!policy_handle_empty(&group_handle) &&
3135 !test_DeleteDomainGroup(p, mem_ctx, &group_handle)) {
3139 ret &= test_samr_handle_Close(p, mem_ctx, &domain_handle);
3141 /* reconnect the main handle */
3142 ret &= test_Connect(p, mem_ctx, handle);
3147 static BOOL test_LookupDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3148 struct policy_handle *handle, struct lsa_String *domain)
3151 struct samr_LookupDomain r;
3152 struct lsa_String n2;
3155 printf("Testing LookupDomain(%s)\n", domain->string);
3157 /* check for correct error codes */
3158 r.in.connect_handle = handle;
3159 r.in.domain_name = &n2;
3162 status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
3163 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_PARAMETER, status)) {
3164 printf("failed: LookupDomain expected NT_STATUS_INVALID_PARAMETER - %s\n", nt_errstr(status));
3168 n2.string = "xxNODOMAINxx";
3170 status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
3171 if (!NT_STATUS_EQUAL(NT_STATUS_NO_SUCH_DOMAIN, status)) {
3172 printf("failed: LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN - %s\n", nt_errstr(status));
3176 r.in.connect_handle = handle;
3177 r.in.domain_name = domain;
3179 status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
3180 if (!NT_STATUS_IS_OK(status)) {
3181 printf("LookupDomain failed - %s\n", nt_errstr(status));
3185 if (!test_GetDomPwInfo(p, mem_ctx, domain)) {
3189 if (!test_OpenDomain(p, mem_ctx, handle, r.out.sid)) {
3197 static BOOL test_EnumDomains(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3198 struct policy_handle *handle)
3201 struct samr_EnumDomains r;
3202 uint32_t resume_handle = 0;
3206 r.in.connect_handle = handle;
3207 r.in.resume_handle = &resume_handle;
3208 r.in.buf_size = (uint32_t)-1;
3209 r.out.resume_handle = &resume_handle;
3211 status = dcerpc_samr_EnumDomains(p, mem_ctx, &r);
3212 if (!NT_STATUS_IS_OK(status)) {
3213 printf("EnumDomains failed - %s\n", nt_errstr(status));
3221 for (i=0;i<r.out.sam->count;i++) {
3222 if (!test_LookupDomain(p, mem_ctx, handle,
3223 &r.out.sam->entries[i].name)) {
3228 status = dcerpc_samr_EnumDomains(p, mem_ctx, &r);
3229 if (!NT_STATUS_IS_OK(status)) {
3230 printf("EnumDomains failed - %s\n", nt_errstr(status));
3238 static BOOL test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3239 struct policy_handle *handle)
3242 struct samr_Connect r;
3243 struct samr_Connect2 r2;
3244 struct samr_Connect3 r3;
3245 struct samr_Connect4 r4;
3246 struct samr_Connect5 r5;
3247 union samr_ConnectInfo info;
3248 struct policy_handle h;
3249 BOOL ret = True, got_handle = False;
3251 printf("testing samr_Connect\n");
3253 r.in.system_name = 0;
3254 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3255 r.out.connect_handle = &h;
3257 status = dcerpc_samr_Connect(p, mem_ctx, &r);
3258 if (!NT_STATUS_IS_OK(status)) {
3259 printf("Connect failed - %s\n", nt_errstr(status));
3266 printf("testing samr_Connect2\n");
3268 r2.in.system_name = NULL;
3269 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3270 r2.out.connect_handle = &h;
3272 status = dcerpc_samr_Connect2(p, mem_ctx, &r2);
3273 if (!NT_STATUS_IS_OK(status)) {
3274 printf("Connect2 failed - %s\n", nt_errstr(status));
3278 test_samr_handle_Close(p, mem_ctx, handle);
3284 printf("testing samr_Connect3\n");
3286 r3.in.system_name = NULL;
3288 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3289 r3.out.connect_handle = &h;
3291 status = dcerpc_samr_Connect3(p, mem_ctx, &r3);
3292 if (!NT_STATUS_IS_OK(status)) {
3293 printf("Connect3 failed - %s\n", nt_errstr(status));
3297 test_samr_handle_Close(p, mem_ctx, handle);
3303 printf("testing samr_Connect4\n");
3305 r4.in.system_name = "";
3307 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3308 r4.out.connect_handle = &h;
3310 status = dcerpc_samr_Connect4(p, mem_ctx, &r4);
3311 if (!NT_STATUS_IS_OK(status)) {
3312 printf("Connect4 failed - %s\n", nt_errstr(status));
3316 test_samr_handle_Close(p, mem_ctx, handle);
3322 printf("testing samr_Connect5\n");
3324 info.info1.unknown1 = 0;
3325 info.info1.unknown2 = 0;
3327 r5.in.system_name = "";
3328 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3331 r5.out.info = &info;
3332 r5.out.connect_handle = &h;
3334 status = dcerpc_samr_Connect5(p, mem_ctx, &r5);
3335 if (!NT_STATUS_IS_OK(status)) {
3336 printf("Connect5 failed - %s\n", nt_errstr(status));
3340 test_samr_handle_Close(p, mem_ctx, handle);
3350 BOOL torture_rpc_samr(void)
3353 struct dcerpc_pipe *p;
3354 TALLOC_CTX *mem_ctx;
3356 struct policy_handle handle;
3358 mem_ctx = talloc_init("torture_rpc_samr");
3360 status = torture_rpc_connection(mem_ctx, &p, &dcerpc_table_samr);
3361 if (!NT_STATUS_IS_OK(status)) {
3362 talloc_free(mem_ctx);
3366 if (!test_Connect(p, mem_ctx, &handle)) {
3370 if (!test_QuerySecurity(p, mem_ctx, &handle)) {
3374 if (!test_EnumDomains(p, mem_ctx, &handle)) {
3378 if (!test_SetDsrmPassword(p, mem_ctx, &handle)) {
3382 if (!test_Shutdown(p, mem_ctx, &handle)) {
3386 if (!test_samr_handle_Close(p, mem_ctx, &handle)) {
3390 talloc_free(mem_ctx);